《清华ITJAVAEE教学PPT演示文稿》由会员分享,可在线阅读,更多相关《清华ITJAVAEE教学PPT演示文稿(25页珍藏版)》请在金锄头文库上搜索。
1、第四章第四章 Struts Struts模型组件与视图组件模型组件与视图组件 1课程目标课程目标q模型的概念与理解模型的概念与理解 q业务对象及其应用业务对象及其应用 q编写编写ActionForm类类 q熟悉熟悉Struts标签建立表单标签建立表单 q各种用户注册程序各种用户注册程序 q各种表单信息提交程序各种表单信息提交程序 2体验项目体验项目 程序实现的功能:程序实现保存用户收货单信息的功能。当用户提交数程序实现的功能:程序实现保存用户收货单信息的功能。当用户提交数据时,程序会检验用户提交的数据是否符合要求,如符合要求最后可提交至据时,程序会检验用户提交的数据是否符合要求,如符合要求最后
2、可提交至数据库保存,如果不符合要求将返回提交信息页面并提示错误信息。数据库保存,如果不符合要求将返回提交信息页面并提示错误信息。 程序运行过程如下:程序运行过程如下: 图4-1 填写表单信息 (1)访问表单页面,输入用户的收货信息。如图)访问表单页面,输入用户的收货信息。如图4-1填写表单信息界面填写表单信息界面所示:所示: 3(2)表单信息填写完成后,点击)表单信息填写完成后,点击“提交提交”按钮。如果用户填写的数据符合要按钮。如果用户填写的数据符合要求(譬如姓名长度大于求(譬如姓名长度大于2,地址长度大于,地址长度大于5等),将弹出如图等),将弹出如图4-2所示的验证所示的验证表单信息成功
3、页面表单信息成功页面 图4-2 验证表单信息成功 (3)如果用户确定所提交的数据无误后,即可点击)如果用户确定所提交的数据无误后,即可点击“确定提交确定提交”按钮将数据按钮将数据保存至数据库。数据保存成功,则出现生成收货单页面。保存至数据库。数据保存成功,则出现生成收货单页面。 4Struts模型组件模型组件 模型组件代表应用的业务数据和逻辑。模型组件代表应用的业务数据和逻辑。Struts框架并没有为设计和创建框架并没有为设计和创建模型组件提供现成的框架。不过模型组件提供现成的框架。不过Strtus允许使用其他的模型组件来处理应用允许使用其他的模型组件来处理应用的业务领域。的业务领域。 模型是
4、应用中重要的一部分,它包含了业务实体和业务规则,负责访问模型是应用中重要的一部分,它包含了业务实体和业务规则,负责访问和更新持久化数据。应该把所有的模型组件放在系统中的同一个位置,这样和更新持久化数据。应该把所有的模型组件放在系统中的同一个位置,这样有利于维护数据的完整性,提高代码的可重用性。有利于维护数据的完整性,提高代码的可重用性。 设计模型需要在概念模型的基础上设计。可以用设计模型需要在概念模型的基础上设计。可以用UML类框图,活动图以类框图,活动图以及状态图来描述设计模型。而根据及状态图来描述设计模型。而根据UML语言,类之间又存在以下四种关系。语言,类之间又存在以下四种关系。 模型的
5、概念与理解模型的概念与理解 关联(Association):指类之间的引用关系。 依赖(Dependency):指类之间的访问关系。 累积(Aggregation):指整体与个体之间的关系,可以把累积看作一种强关联关系。 一般化(Generalization):指类之间的继承关系。5 业务对象业务对象(Business Object,BO)是对数据进行检索和处理的组件。是是对数据进行检索和处理的组件。是对简单的真实世界的软件抽象,业务对象通常位于中间层。对简单的真实世界的软件抽象,业务对象通常位于中间层。 业务对象(业务对象(BO)是由第三方开发的,用其可以在一个应用中自动的)是由第三方开发的
6、,用其可以在一个应用中自动的加入一个特定的功能来获得增值效应。使代码重用变为可能。比如,如果要加入一个特定的功能来获得增值效应。使代码重用变为可能。比如,如果要开发一个包含多货币处理的应用,可以选择使用一个已经开发完成的,包含开发一个包含多货币处理的应用,可以选择使用一个已经开发完成的,包含所有多货币处理功能的业务对象来开始您的开发。使你的开发工作极大的减所有多货币处理功能的业务对象来开始您的开发。使你的开发工作极大的减少。少。 业务对象业务对象 如果一个类可以作为业务对象,那它必须具有以下条件:如果一个类可以作为业务对象,那它必须具有以下条件:1. 业务对象的必要条件业务对象的必要条件 由状
7、态和行为组成。由状态和行为组成。 表达了来自业务域的一个人、地点、事物或概念。表达了来自业务域的一个人、地点、事物或概念。 可以重用。可以重用。 6业务对象可以分为以下三类:业务对象可以分为以下三类: 2业务对象的分类业务对象的分类 (1)实体业务对象:表达了一个人、地点、事物或者概念。根据业)实体业务对象:表达了一个人、地点、事物或者概念。根据业务中的名词从业务域中提取。如客户、订单、物品。在务中的名词从业务域中提取。如客户、订单、物品。在EJB应用程序应用程序中,一般为实体中,一般为实体Bean。在传统的。在传统的web应用程序中,可能是包含业务应应用程序中,可能是包含业务应用的状态和行为
8、的普通用的状态和行为的普通javabean。(2)过程业务对象:表达应用程序中业务处理过程或者工作流程任)过程业务对象:表达应用程序中业务处理过程或者工作流程任务。通常依赖于实体业务对象,是业务的动词。在务。通常依赖于实体业务对象,是业务的动词。在EJB应用程序中,应用程序中,通常是模型的会话通常是模型的会话Bean,或者消息驱动,或者消息驱动Bean。在非。在非EJB应用中,可能应用中,可能是是javabean包含特定的行为,作为应用程序的管理者或者控制者。包含特定的行为,作为应用程序的管理者或者控制者。(3)事件业务对象:表达应用程序中由于系统的一些操作造成或产)事件业务对象:表达应用程序
9、中由于系统的一些操作造成或产生的一些事件。生的一些事件。 7在应用中使用业务对象有许多好处,最重要的一点就是业务对象提供了通用的术语和概念,不管是技术人员还是非技术人员都可以共享并理解它们。它们可以直观地代表现实世界中的概念,开发小组的所有成员都能理解他们。如果正对同一个业务领域需要开发出多个应用,那么这些应用可以共享这些业务对象。业务对象的可重用特性可以提高应用开发速度,减少冗余。 3. 业务对象的重要性业务对象的重要性 当应用中的业务对象在内存中创建后,它们不可能永远存在。最后,他们要么从内存中清除,要么被持久化到数据库中。内存无法永久保存数据,因此必需对业务对象进行持久化。否则,如果对象
10、没有被持久化,用户在应用运行时发出的订单信息将在应用结束运行后随之消失。关系型数据库被广泛用来存储数据。关系型数据库中存放的是关系型数据,它是非面向对象的。把业务对象映射到非面向对象的数据库中,存在着阻抗不匹配(impedance mismatch),因此对象由状态和行为组成,而关系型数据库则由表组成,对象之间的各种关系和关系型数据库中表之间的关系并不一一对应。 4. 业务对象的持久化业务对象的持久化 85数据访问对象(数据访问对象(DAO)设计模式)设计模式 DAO模式提供了访问关系型数据库系统所需的所有操作的接口,其中包模式提供了访问关系型数据库系统所需的所有操作的接口,其中包括创建数据库
11、、定义表、字段和索引,建立表间的关系,更新和查询数据库括创建数据库、定义表、字段和索引,建立表间的关系,更新和查询数据库等。等。DAO模式将底层数据访问操作与高层业务逻辑分离开,对上层提供面向模式将底层数据访问操作与高层业务逻辑分离开,对上层提供面向对象的数据访问接口。在对象的数据访问接口。在DAO的实现中,可以采用的实现中,可以采用XML语言来配置对象和关语言来配置对象和关系型数据之间的映射。系型数据之间的映射。 对于对于Java应用,可以直接通过应用,可以直接通过JDBC编程来访问数据库。编程来访问数据库。JDBC可以说是可以说是访问持久数据层最原始、最直接的方法。在企业级应用开发中,可以
12、通过访问持久数据层最原始、最直接的方法。在企业级应用开发中,可以通过JDBC编程,来开发自己的编程,来开发自己的DAO API,把数据库访问操作封装起来,供业务,把数据库访问操作封装起来,供业务层统一调用。层统一调用。 注意:ORM框架是一种持久化框架,DAO是用于实现持久化框架的一种设计模式。 9 ActionForm类类 在在Struts框架中,模型层包括框架中,模型层包括ActionForm、JavaBean或或EJB。通常,。通常,Struts框架会为你的应用程序中每一个用户的输入请求创建一个框架会为你的应用程序中每一个用户的输入请求创建一个ActionForm bean,它为,它为A
13、ction提供用户请求的数据,所以提供用户请求的数据,所以ActionForm代表了由浏览器所代表了由浏览器所传递过来的数据。传递过来的数据。(1)控制器接收到请求。)控制器接收到请求。(2)从)从request或或session范围中取出范围中取出ActionForm实例,如果该实例不存实例,如果该实例不存在,就自动创建一个新的实例。在,就自动创建一个新的实例。(3)调用)调用ActionForm的的reset()方法。方法。(4)把)把ActionForm实例保存在实例保存在request或或session范围中。范围中。(5)把用户输入的表单数据组装到)把用户输入的表单数据组装到Acti
14、onForm中。中。(6) 如果如果Struts配置文件中配置文件中元素的元素的validate属性为属性为true,则调用,则调用ActionForm的的validate()方法。方法。(7)把请求转发给其他)把请求转发给其他Web组件,组件,ActionForm实例依然保存在实例依然保存在request或或session范围内。范围内。 ActionForm的生命周期的生命周期 10 ActionForm是一个抽象类,每一个自定义的是一个抽象类,每一个自定义的ActionForm类都要求继承类都要求继承org.apache.struts. action.ActionForm类,本例的类,本
15、例的ActionForm我们取名为我们取名为HelloActionForm,它的定义方法如下所示:,它的定义方法如下所示:定义定义ActionForm类类 package com.centrain.struts.model; import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionErrors;import org.apache.struts.action.ActionMessage;import org.apache.struts.action.ActionMapping;import
16、javax.servlet.http.HttpServletRequest;public class HelloActionForm extends ActionForm 11在在ActionForm中,需要为每一个用户提交的数据定义一个属性,用来保存中,需要为每一个用户提交的数据定义一个属性,用来保存数据的值。另外,为了实现对这些属性的存取操作,还需要在数据的值。另外,为了实现对这些属性的存取操作,还需要在ActionForm对对象中提供对这些属性操作的象中提供对这些属性操作的setter()和和getter()方法。这些方法。这些setter()和和getter()方法方法的命名要符合的命
17、名要符合JavaBean的规定,也就是将的规定,也就是将set或或get与属性名首字母大写后组与属性名首字母大写后组成方法名,如成方法名,如getUserName()。 定义定义ActionForm的属性的属性 定义完属性与相关的定义完属性与相关的setter()和和getter()方法后,就需要重写方法后,就需要重写ActionForm父父类的类的reset()方法。方法。reset()方法会在每一次收到用户请求时被调用,定义这个方方法会在每一次收到用户请求时被调用,定义这个方法的目的是通过这个方法为法的目的是通过这个方法为ActionForm对象中的每一个属性设置初始的默认对象中的每一个属
18、性设置初始的默认值,即进行初始化。值,即进行初始化。reset( )方法包括了两个参数,分别是方法包括了两个参数,分别是ActionMapping和和HttpServletRequest。 重写重写reset()方法方法 public void reset(ActionMapping actionMapping,HttpServletRequest servletRequest)/12 validate()方法的作用主要是对用户提交的表单数据进行初步验证,譬如方法的作用主要是对用户提交的表单数据进行初步验证,譬如用户提交的数据是否为空,是否数据长度不够等等。当然,这些验证,我们用户提交的数据是
19、否为空,是否数据长度不够等等。当然,这些验证,我们完全可以在表单页面使用完全可以在表单页面使用javascript脚本语言来实现。脚本语言来实现。 实现实现validate()方法方法 配置配置ActionForm Struts配置文件的配置文件的元素用来配置所有的元素用来配置所有的ActionForm Bean。元素可以包含多个元素可以包含多个子元素,它代表单个的子元素,它代表单个的ActionForm Bean。 同一个同一个ActionForm可以和多个可以和多个Action映射。在映射。在元素中,元素中,name和和scope属性分别指定属性分别指定ActionForm的名字和范围,的
20、名字和范围,validate属性指定是否执行表属性指定是否执行表单验证。单验证。 13开发开发JavaBean组件组件 JavaBean可以存活在可以存活在page、request、session及及application范围内。在范围内。在Web应用中,可以将常用的属性或方法写在应用中,可以将常用的属性或方法写在JavaBean中,由于一个中,由于一个JavaBean可以被多个可以被多个JSP页面或页面或Servlet调用,所以这样将很大程度上提高代码调用,所以这样将很大程度上提高代码的可重用性。的可重用性。 如如HelloActionForm的代码可以这样写如下的代码可以这样写如下 (部分
21、代码):(部分代码):/验证表单数据public ActionErrors validate(ActionMapping actionMapping,HttpServletRequest httpServletRequest) ActionErrors error = new ActionErrors();if (users.getUserName() = = null | users.getUserName().trim().length() 2) error.add(userName.error,new ActionMessage(login.form.userName.error);re
22、turn error;14 如果程序涉及到数据库操作,也可以将数据库操作代码写成方法封装在如果程序涉及到数据库操作,也可以将数据库操作代码写成方法封装在Bean中,然后可以在其他程序中调用。例如我们要把订单信息保存至数据库,中,然后可以在其他程序中调用。例如我们要把订单信息保存至数据库,DBConnection.java的代码可以这样写,参考代码如下:的代码可以这样写,参考代码如下: public boolean addInfo(Users users) try PreparedStatement ps = cn.prepareStatement(insert into usersorder
23、values(?,?,?,?,?); ps.setString(1,users.getUserName(); / ps.execute(); catch(Exception e) eturn false; return true; 在在addInfo()方法中,我们传递的是方法中,我们传递的是users对象,所以在调用该方法时,也对象,所以在调用该方法时,也必须传递必须传递users对象给它,当然这是在对象给它,当然这是在users对象不为空的情况下才这么使用。对象不为空的情况下才这么使用。 15 DynaActionForm类类 DynaActionForm的目的就是减少ActionForm
24、的数目,利用它你不必创建一个个具体的ActionForm类,而是在配置文件中配置出所需的虚拟ActionForm。例如,在下表中通过指定的type为org.apache.struts.action.DynaActionForm来创建一个动态的ActionFormLoginActionForm。 16 动态的动态的ActionForm的使用方法跟普通的的使用方法跟普通的ActionForm相同,但是要注意相同,但是要注意一点。普通的一点。普通的ActionForm对象需要为每个属性提供对象需要为每个属性提供getter和和setter方法,以上方法,以上面的例子而言,我们需要提供面的例子而言,我
25、们需要提供getUserName()和和setUserName()方法取得和设方法取得和设置置userName属性,同样地有一对方法用于取得和设置属性,同样地有一对方法用于取得和设置password属性和属性和actionClass属性。属性。如果使用如果使用DynaActionForm,它将属性保存在一个,它将属性保存在一个HashMap类对象中,类对象中,同时提供相应的同时提供相应的get(name)和和set(name)方法,其中参数方法,其中参数name是要访问的属性是要访问的属性名。例如要访问名。例如要访问DynaActionForm中中userName的值,可以采用类似的代码:的值
26、,可以采用类似的代码: String userName = (String)form.get(“userName”);由于值存放于一个由于值存放于一个HashMap对象,所以要记得对对象,所以要记得对get()方法返回的方法返回的Object对象做强制性类型转换。正是由于这点区别,如果你在对象做强制性类型转换。正是由于这点区别,如果你在Action中非常频繁地中非常频繁地使用使用ActionForm对象,建议还是使用普通的对象,建议还是使用普通的ActionForm对象。对象。 17Struts视图组件视图组件 Struts框架的视图负责向客户显示动态的网页内容。框架的视图负责向客户显示动态的
27、网页内容。Struts框架的视图主要框架的视图主要由由JSP网页构成。此外,网页构成。此外,Struts框架还提供了一系列的客户化标签和框架还提供了一系列的客户化标签和ActionForm Bean,这些组件提供对国际化、接收用户输入的表单数据、表,这些组件提供对国际化、接收用户输入的表单数据、表单验证和错误处理等的支持。单验证和错误处理等的支持。 譬如,一个用户的用户名字段的输入元素在譬如,一个用户的用户名字段的输入元素在JSP中可以这样来写:中可以这样来写: input type=text“ name=userName value=/ 但是这样的代码会让页面美工设计人员看起来很头疼,如果采
28、用但是这样的代码会让页面美工设计人员看起来很头疼,如果采用Struts标签建立表单的话,就显得方便多了,如下:标签建立表单的话,就显得方便多了,如下: 18 Struts框架明确了控制器的角色,所有请求需要先转发给控制器,再框架明确了控制器的角色,所有请求需要先转发给控制器,再由控制器来负责请求转发。由控制器来负责请求转发。 由控制器来负责请求转发有以下一些优点:由控制器来负责请求转发有以下一些优点: org.apache.struts.actions.ForwardAction 控制器具有预处理请求功能,它能够选择正确的子应用模块来处控制器具有预处理请求功能,它能够选择正确的子应用模块来处理
29、请求,并且把子应用模块的理请求,并且把子应用模块的ModuleConfig和和MessageResources对对象存放在象存放在request范围内。范围内。 控制器具有预处理请求功能,它能够选择正确的子应用模块来处控制器具有预处理请求功能,它能够选择正确的子应用模块来处理请求,并且把子应用模块的理请求,并且把子应用模块的ModuleConfig和和MessageResources对对象存放在象存放在request范围内。范围内。 JSP网页之间直接相互转发违背了网页之间直接相互转发违背了MVC的分层原则,按照的分层原则,按照MVC设设计思想,控制器负责处理所有请求,然后选择适当的视图组件返
30、回计思想,控制器负责处理所有请求,然后选择适当的视图组件返回给用户,如果直接让给用户,如果直接让JSP相互调用,控制器就失去了流程控制作用。相互调用,控制器就失去了流程控制作用。 19 org.apache.struts.actions.IncludeAction Struts框架提倡先把请求转发给控制器,再由控制器来负责包含其他框架提倡先把请求转发给控制器,再由控制器来负责包含其他Web组件。组件。IncludeAction类提供了包含其他类提供了包含其他Web组件的功能。与组件的功能。与ForwardAction一样,一样,Web组件通过组件通过IncludeAction类来包含另一个类来
31、包含另一个Web组件,可以充分利用组件,可以充分利用Struts控制器的预处理功能。控制器的预处理功能。 Struts配置文件中,元素的paramter属性指定需要包含的Web组件。 20org.apache.struts.actions.LookupDispatchAction LookupDispatchAction类是类是DispatchAction的子类,在该类中也可以定义的子类,在该类中也可以定义多个业务方法。通常多个业务方法。通常LookupDispatchAction主要应用于一个表单中有多个提主要应用于一个表单中有多个提交按钮的情况,而这些按钮又有一个共同的名字的场合,这些按钮
32、的名字和交按钮的情况,而这些按钮又有一个共同的名字的场合,这些按钮的名字和具体的具体的ActionMapping的的parameter属性值相对应。属性值相对应。 一个一个DEMO 21org.apache.struts.actions.SwitchAction SwitchAction类用于子应用模块之间的切换。对于请求访问类用于子应用模块之间的切换。对于请求访问SwitchAction的的URL,需要提供两个参数:,需要提供两个参数: prefix:指定子应用模块的前缀,以“/”开头,默认子应用模块的前缀为空字符串“”。 page:指定被请求Web组件的URI,只需指定相对于被切换后的子应
33、用模块的相对路径。 配置配置SwitchAction类如下所示:类如下所示: 22实践项目实践项目 一、程序的实现要求如下:一、程序的实现要求如下:(1)对用户提交的表单信息进行验证,例如用户提交的姓)对用户提交的表单信息进行验证,例如用户提交的姓名是否为空,或是否太短(一般来说,用户姓名的长度不名是否为空,或是否太短(一般来说,用户姓名的长度不可能为可能为1,所以我们可以判断是否小于,所以我们可以判断是否小于2)。)。 (2)对用户提交的信息进行中文乱码处理。)对用户提交的信息进行中文乱码处理。 (3)用户进行第一次提交的时候,并不把数据添加到数据)用户进行第一次提交的时候,并不把数据添加到
34、数据库中,而是将所有信息返回给用户,然后又用户判断所提库中,而是将所有信息返回给用户,然后又用户判断所提交的信息是否理想,如果不理想可以返回重新提交,如果交的信息是否理想,如果不理想可以返回重新提交,如果理想则可进行最后的确定,从而将数据保存至数据库中。理想则可进行最后的确定,从而将数据保存至数据库中。 23二、实现步骤二、实现步骤 (1)当用户在)当用户在index.jsp页面中点击页面中点击“提交提交”按钮时,是将请求提交给了按钮时,是将请求提交给了HelloAction,HelloAction得到请求后,将填充得到请求后,将填充HelloActionForm的数的数据,并将其保存至据,并
35、将其保存至request对象中,最后将请求转发给对象中,最后将请求转发给ok.jsp页面。页面。 (2)在)在ok.jsp页面中,通过以下代码,取出页面中,通过以下代码,取出HelloActionForm对象,获对象,获得用户提交的数据,最后再将得用户提交的数据,最后再将Users对象保存在对象保存在session对象里。对象里。 (3)如果用户确定提交的数据无误之后,可再点击)如果用户确定提交的数据无误之后,可再点击“确定提交确定提交”按钮将按钮将数据保存至数据库。此次提交是将请求提交给了数据保存至数据库。此次提交是将请求提交给了DBAction,在,在DBAction中取出中取出Users
36、对象并调用对象并调用DBConnection Bean将数据保存至数将数据保存至数据库。在据库。在DBAction中存在两种请求转发的可能,如果数据成功添加到中存在两种请求转发的可能,如果数据成功添加到数据库,将会把请求转发到成功页面,如果添加失败则将请求转发至数据库,将会把请求转发到成功页面,如果添加失败则将请求转发至错误页面。错误页面。 24本章总结本章总结q模型的概念与理解模型的概念与理解 q业务对象及其应用业务对象及其应用 q编写编写ActionForm类类 q熟悉熟悉Struts标签建立表单标签建立表单 q各种用户注册程序各种用户注册程序 q各种表单信息提交程序各种表单信息提交程序 25