30
02 02 Struts Struts 核核核核 核核核核 核核核核核 核核核核核 核核核核核核

02 - Struts 核心组件 及运行机制

  • Upload
    brendy

  • View
    153

  • Download
    0

Embed Size (px)

DESCRIPTION

02 - Struts 核心组件 及运行机制. 中科软培训部. 回顾. 什么是 MVC? Struts 是怎么去实现 MVC 的 ? Struts 基本组件有那些 ? 基本组件之间有什么关系 ? Struts 标签的运行机制是什么 ? Struts 标签库的分类 ; 什么时候用什么标签 ;. 重点. 了解 Struts 的核心组件及运行机制 掌握如果扩展 ActionServlet 和 RequestProcessor 了解 DTO 对象 掌握 ActionForm 的配置和使用 ; 掌握 ActionForm 与 Action 的邦定 ; - PowerPoint PPT Presentation

Citation preview

Page 1: 02 - Struts 核心组件 及运行机制

0202 -- StrutsStruts 核心组件核心组件及运行机制及运行机制中科软培训部

Page 2: 02 - Struts 核心组件 及运行机制

回顾回顾什么是 MVC?Struts 是怎么去实现 MVC 的 ?Struts 基本组件有那些 ?基本组件之间有什么关系 ?Struts 标签的运行机制是什么 ?Struts 标签库的分类 ;什么时候用什么标签 ;

Page 3: 02 - Struts 核心组件 及运行机制

重点重点 了解 Struts 的核心组件及运行机制 掌握如果扩展 ActionServlet 和 RequestProcessor 了解 DTO 对象 掌握 ActionForm 的配置和使用 ; 掌握 ActionForm 与 Action 的邦定 ; 掌握 ActionForm 的数据验证 ; 掌握 ActionForm 的动态现实 ;

Page 4: 02 - Struts 核心组件 及运行机制

StrutsStruts 运行机制运行机制 Struts 架构从本质上是 MVC 设计模式的具体实现 表示层一般使用视图组件实现、控制层使用控制器组件实现,而应用逻辑层则使用模型组件实现。作为表示层和应用逻辑层之间的中介,控制器处于视图及模型之间,起到了桥梁的沟通作用 在 Struts 框架中对应着每一层一般都提供了相应的实现组件

表示层 控制层 逻辑层 数据库

Page 5: 02 - Struts 核心组件 及运行机制

对应的实现组件对应的实现组件 与控制器组件相关的类主要包括:

– ActionServlet : Struts架构的中央控制器,用于接受浏览器客户端用户请求以及状态改变,并依据处理结果选择表示层不同视图的重定向。– RequestProcessor :包含了 Struts 控制器在处理 servlet 请求时所遵循的控制逻辑。– Action :控制器的一部分,用于模型交互,执行状态改变或状态查询,以及告诉 ActionServlet 下一个选择的视图。– ActionForm :用于保存于表单数据相关的状态数据的改变。– ActionMapping :用于控制在状态数据改变后的事件处理的方式。 – ActionForward :用户指向或者视图选择。

与视图组件相关的工具主要包括 Struts架构中提供的强大标记库,常用的标记库功能如下所示:– struts-html.tld 标记库:扩展 HTML Form 的 JSP 标记– struts- bean.tld 标记库:扩展扩展处理 JavaBean 的 JSP 标记– struts-logic.tld 标记库:扩展测试属性值的 JSP 标记

与模型组件相关的工具主要包括:– 开发者提供的其他数据服务和 API ,例如: JavaBean 等

Page 6: 02 - Struts 核心组件 及运行机制

控制器组件控制器组件 Struts 架构中控制器组件所承担的主要功能包括:

– 接受浏览器客户端的处理请求– 根据用户的不同请求,调用对应的模型组件来执行相应的业务逻辑– 获取模型组件业务逻辑的处理结果– 根据当前的状态数据及业务逻辑的处理结果,选择合适的视图组件呈现在浏览器客户端。

在 Struts 框架中 , 整个控制工作是在一系列的相关组件的配合下共同完成的

Page 7: 02 - Struts 核心组件 及运行机制

ActionServletActionServlet 在 Struts 架构中 Controller 组件的核心控制器组件是 ActionServlet 是 org.apache.struts.action.ActionServlet 类型的 servlet 所有客户端提交的用户请求都由它进行处理

– 负责接收客户端请求后将之分发到相应的 Action Bean 处理,再根据处理的结果将不同的显示请求重定向到响应页面。– 实际上, ActionServlet 完全是在幕后工作,它将其他组件绑定在一起。– 该类继承自 javax.servlet.http.HttpServlet, 有标准的生命周期中所用到的方法 .另外在 ActionServlet 类添加了一个特殊的 process 方法 .process() 方法的作用是处理接收的请求并作出相应– 代码参见ActionServlet.java 第1184行

ActionServlet 接收到 Servlet 容器的新的客户端请求后 , 它采取的具体的处理过程如下 :– 根据请求的种类执行相应的 doGet 或 doPost 方法 , 然后在 doGet 和 doPost 中调用 process 方法– Process 方法首先会获得 RequestProcessor 类的对象 , 然后调用该类的 process方法进行处理 . 实际上控制器所执行的控制逻辑就包含在 RequestProcessor 这个类中 , 而不是在 ActionServlet 中 .ActionServlet 处理业务的过程是借助 Requ

estProcessor 这个类的功能来实现的

Page 8: 02 - Struts 核心组件 及运行机制

RequestProcessorRequestProcessor 类类RequestProcessor 类 一个应该模块对应一个 RequestProcessor 类 ; ActionSerlvet 接收请求后调用 RquestProcessor 类的 process 方法 , 并把 request和 response传给它 ; 根据配置文件创建 ActionMapping 对象 RquestProcessor 类的 process 方法从 struts-config.xml文件中根据请求 URI 查询匹配的 <action>子元素 , 然后根据 <action>子元素中的“ name” 属性在配置文件中查找匹配的 <form-bean>子元素 ,确定下一步要用到的 ActionForm Bean类 RquestProcessor 类的 process 方法调用 ActionForm Bean 类的 setXXX 方法 , 将表单中的数据填充到 FormBean 类的相应的属性中 , 然后根据 <action>子元素中的 validate 属性的值 , 判断是否调用 FormBean 类的 validate 方法校验表单的数据 查找匹配的 <action>子元素中的“ type” 属性寻找相应的可用的 ActionBean 类的对象 , 如果找不到就新创建一个 将 FormBean 类的对象 ,ActionMapping 对象 ,request 对象 ,reponse 对象一起传给 Action 类的 execute() 方法 Action 类的 execute() 方法执行完毕 ,返回一个表明相应页面的 ActionForward对象 . RequestProcessor 类根据 ActionForward 对象进行调整

Page 9: 02 - Struts 核心组件 及运行机制

RequestProcessorRequestProcessor 类的类的 processprocess 方法调用的方法列方法调用的方法列表表 processMultipart()—预处理 request 的请求方式以及分析请求的 contentType 属性 processPath()— 得到请求的 url, 分析后选择合适的 Action 组件 ; processLocale()— 得到请求的 locale, 适当时候存放到 session 中 ; processContent()— 通过 ControllerConfig 对象的 contentType 属性设置字符编码 ; processNoCache()-- 通过 ControllerConfig 对象的 nocache 属性设置页面缓存机制 ; processPreprocess()— 这是一个空方法 ,直接返回 true, 一般用来扩展用的 ; processMapping()—匹配用户请求的 URL只否有相应的 ActionMapping 对象 ; processRoles()—判断用户是否配置了安全角色 ; processActionForm()— 查找 ActionMapping 对象邦定的 ActionForm, 并实例化 ; processPopulate()— 如果找到 ActionForm 就把 request 中的表单值填到 actionForm; ProcessValidate()— 如果 ActionMapping 中 validate 属性为 true. 就调用表单的 vali

date 方法进行数据验证 ; processForward()— 调用 requestDispatcher 的 forward() 方法进行页面跳转 ; processInclude()-- 调用 requestDispatcher 的 include() 方法进行页面输出 ; processActionCreate()—创建一个 action 的实例存放到缓存中 ; processActionPerform()— 调用 action 的 execute() 方法 ; precessActionForward()— 根据 action 的 execute() 的返回值进行页面跳转 ;

Page 10: 02 - Struts 核心组件 及运行机制

扩展扩展 RequestProcessorRequestProcessor处理文字编码问题处理文字编码问题我们可以去重写 requestProcessor 类的 proces

sPreprocess 方法去处理编码 ;

并在 struts-config.xml文件里面配置<controller processorClass="struts.requestprocessor.MyRequestProcessor"></controller>

Page 11: 02 - Struts 核心组件 及运行机制

例例 :MyRequestProcesser:MyRequestProcesser 类类public class MyRequestProcessor extends RequestProcessor { protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) { try { request.setCharacterEncoding("GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return super.processPreprocess(request, response); }}

Page 12: 02 - Struts 核心组件 及运行机制

DTODTO 数据传输对象数据传输对象DTO:Data Transfer Object作用 : 用于 model 层和 view 层之间传递数据减少数据的冗余 , 提高传输效率 .有助于实现各个层之间的独力性 .

Page 13: 02 - Struts 核心组件 及运行机制

StrutsStruts 框架中的框架中的 DTODTO

ActionForm Bean 是 Struts 提供的 DTO, 用于视图层和控制层之间传递 HTML 表单数据 ;在 action 中直接得到 ActionForm Bean 实体得到数据 ;

Page 14: 02 - Struts 核心组件 及运行机制

ActionFormActionForm 的生命周期的生命周期接收控制器的请求

从 request 或 session范围中取出ActionForm 对象 , 如果不存在就 new 一个

调用 ActonForm 对象的 reset 方法

将 FormBean 对象保存在 scope指定的范围内

将用户的表单数据封装在 FormBean 中

如果 <action> 中的 validate 属性为 true, 调用 FormBean 的 validatte() 方法

如果校验失败 , 将请求转发给 <action>的 input 属性所指定的 web 组件 , 并将FormBean 保存在指定的范围中

如果校验成功调用 Action 的 execute 方法并将 FormBean传递给该方法

将请求转发给 <action 指定的 web 组件 ,并将 FormBean 保存在指定的范围中

Page 15: 02 - Struts 核心组件 及运行机制

创建创建 ActionFormActionForm

创建一个与 HTML 中表单一一对应的 JavaBean;

JavaBean 继承 org.apache.struts.action.Actionform 类 ;

重写 reset() 方法 ;重写 validate() 方法 ;

Page 16: 02 - Struts 核心组件 及运行机制

Validate()Validate() 方法方法当 Struts 的配置文件满足以下两个条件 ,Struts 控制器就会调用 ActionForm 的 validate() 方法 ;1. 为 ActionForm 配置了 Action映射 ,即 <form-bean>元素里面 name 和 <action>元素里面的 name 相匹配 ;2. <action>元素的 validate 属性为 true;

方法返回 ActionErrors 对象 , 如果该对象为空或不包含任何 ActionMessage 对象 , 那么就表示验证通过 ;反之把 ActionErrors 存到 request 中并返回 input 页面 ;

Page 17: 02 - Struts 核心组件 及运行机制

表单数据验证表单数据验证 重写 ActionForm 的 validate 方法 ; 在 validate 方法里根据 ActionForm 中填充的属性值判断是否适合程序的要求 ; 返回一个 ActionErrors 对象 ; ActionErrors 对象是一个 MAP集合 , 存放的全都是 Act

ionMessage 对象 ; ActionMessage 对象的错误提示配合 Resource bundle文件使用 ; 如果 ActionErrors集合里没有 ActionMessage 对象 , 则通过数据验证 , 执行 Action 的 execute 方法 ,否则返回

ActionMapping 对象用的 input 页面 , 并通过 <html:errors> 标签显示 ActionMessage 中的错误提示 ;

Page 18: 02 - Struts 核心组件 及运行机制

例例 :ActionFormBean:ActionFormBean 的的 validatvalidateepublic ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {

ActionErrors errors = new ActionErrors();if(userName==null||userName.equals("")){errors.add("userName",new ActionMessage("errors.tip.username.null"));}if(userPwd==null||userPwd.equals("")){errors.add("userPwd",new ActionMessage("errors.tip.userpwd.null"));}if(address==null||address.equals("")){errors.add("address",new ActionMessage("errors.tip.address.null"));}else if (address.length()<4){errors.add("address",new ActionMessage("errors.tip.address.length",4));}if(phone==null||phone.equals("")){errors.add("phone",new ActionMessage("errors.tip.phone.null"));}else if(phone.length()!=11){errors.add("phone",new ActionMessage("errors.tip.phone.length"));

}else{try {Double.parseDouble(phone);} catch (NumberFormatException e) {errors.add("phone",new ActionMessage("errors.tip.phone.int"));}if(age<16||age>90){errors.add("age",new ActionMessage("errors.tip.age.format",16,90));}}return errors;}

Page 19: 02 - Struts 核心组件 及运行机制

Reset()Reset() 方法方法不管 ActionForm 存在于那个 scope, 实例化之后 ActionForm 就会调用 reset 方法 ;Reset() 方法用于恢复 ActionForm 的默认值 ,例如把 boolean 设置成 true 或 false,把 Str

ing 设置为空 ;

Page 20: 02 - Struts 核心组件 及运行机制

例例 :ActionFormBean:ActionFormBean 的的 reset()reset()

public void reset(ActionMapping mapping, HttpServletRequest request) {

userName=null;userPwd=null;address=null;phone=null;age=0;}

Page 21: 02 - Struts 核心组件 及运行机制

配置配置 ActionFormActionForm

在 struts 配置文件的 <form-beans>元素中配置 ActionForm, 如 :<form-bean name=“loginForm” type=“com.a

ctionform.LoginForm”/>Name: 为实例化后的 ActionForm 取名 ;Type:ActionForm 的类路径 ;

Page 22: 02 - Struts 核心组件 及运行机制

访问访问 ActionFormActionForm

通过 Struts HTML 标签库访问 ;从 request 或 session范围内取出 ActionFo

rm 实例 ;在 Action 的 execute() 方法中直接访问 ;

Page 23: 02 - Struts 核心组件 及运行机制

处理表单跨页处理表单跨页通过 struts-config.xml 配置多个 action 邦定一个 ActionForm;ActionForm 配置一个属性用于区分页面索引 --page;ActionForm 对象必须保存在 session范围内 ;根据条件重写 reset 和 validate 方法 ;

Page 24: 02 - Struts 核心组件 及运行机制

动态动态 ActionFormActionForm

ActionFrom 和 DynaActionForm 的区别 ActionForm 对于大型的 Struts 应该必须以编程方式创建大量的 ActionForm, 如果 HTML 表单字段发生变化 , 就必须改源代码 ; Struts1.1 对此做出了改进 ,引入了动态 ActionF

orm 的概念 ,DynaActionForm 类以及其子类实现了动态 ActionForm, 而必须主意的是 DynaActionForm 本身是 ActionForm 的子类 ;

Page 25: 02 - Struts 核心组件 及运行机制

配置动态配置动态 ActionFormActionForm

动态 ActionFormp 完全支持在 Struts-config.xml文件中完成 ActionForm 的全部配置 ;动态 ActionForm 标签 :<form-bean>:name 指定 ActionForm 的实例名称 ;t

ype 指定 org.apache.struts.action.DynaActionForm;

<form-property>:name 指定动态 ActionForm Bean的成员属性名 ;type 指定该属性的数据类型 ;initial 指定初始化值 , 相当于 reset操作 ;

Page 26: 02 - Struts 核心组件 及运行机制

TypeType 属性指定的属性指定的 JAVAJAVA 类型类型 Java.lang.BigDecimal Java.lang.BigInteger Java.lang.Boolean Java.lang.Byte Java.lang.Character Java.lang.Class Java.lang.Double Java.lang.Float Java.lang.Integer Java.lang.Long如果表单的字段值是 java 基本类型 , 在配置时应该用上面相应的封装类来代替

Page 27: 02 - Struts 核心组件 及运行机制

例例 :: 动态动态 ActionFormActionForm 的配置的配置<form-bean name="loginForm"type="org.apache.struts.action.DynaActionForm"><form-property name="userName" type="java.lang.String"initial=" 请输入用户名 "></form-property><form-property name="userPwd" type="java.lang.String"initial=""></form-property></form-bean>

Page 28: 02 - Struts 核心组件 及运行机制

动态动态 ActionFormActionForm 的访问的访问Action 和 Struts HTML 标签都可以访问动态 ActionForm, 如果是标准的 ActionForm, 在 Action 的 execute 方法中可以使用

getter 和 setter 方法操作 ,但是 DynaActionForm把所有的数据都封装到一个 MAP集合中 , 所有动态 ActionForm 提供的是一个用于访问所有属性的通用方法 :public Object get(String name)public void set(String name,Object value)

其实有人在想 , 动态的 ActionForm 怎么去实现数据验证 ?我们将结合下一个知识点 ,struts 的验证框架一起来实现 ;

Page 29: 02 - Struts 核心组件 及运行机制

例例 :: 在在 ActiomActiom 中访问动态中访问动态 ActionFActionFormorm 对象对象

DynaActionForm daf = (DynaActionForm) form;String userName = (String) daf.get("userName");String userPwd = (String) daf.get("userPwd");

Page 30: 02 - Struts 核心组件 及运行机制

总结:总结:ActionForm 在 MVC 中的位置 ;ActionForm 的运行机制 ;ActionForm 配置及使用 ;ActionForm 的 reset 和 validate 方法 ;动态 ActionForm 的配置和使用 ;