1 / 31

Struts 核心组件及 运行机制

Struts 核心组件及 运行机制. Struts 运行机制. Struts 架构从本质上是 MVC 设计模式的具体实现 表示层一般使用视图组件实现 、 控制层使用控制器组件实现 , 而应用逻辑层则使用模型组件实现 。作为表示层和应用逻辑层之间的中介,控制器处于视图及模型之间,起到了桥梁的沟通作用. 对应的实现组件. 与控制器组件相关的类主要包括: ActionServlet : Struts 架构的中央控制器 ,用于接受浏览器客户端用户请求以及状态改变,并依据处理结果选择表示层不同视图的重定向。

Télécharger la présentation

Struts 核心组件及 运行机制

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Struts核心组件及运行机制

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

  3. 对应的实现组件 • 与控制器组件相关的类主要包括: • 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等。

  4. 控制器组件 • Struts 架构中控制器组件所承担的主要功能包括: • 接受浏览器客户端的处理请求 • 根据用户的不同请求,调用对应的模型组件来执行相应的业务逻辑 • 获取模型组件业务逻辑的处理结果 • 根据当前的状态数据及业务逻辑的处理结果,选择合适的视图组件呈现在浏览器客户端。 • 在Struts框架中,整个控制工作是在一系列的相关组件的配合下共同完成的

  5. ActionServlet • 在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处理业务的过程是借助RequestProcessor这个类的功能来实现的

  6. RequestProcessor类 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对象进行调整

  7. RequestProcessor类的process方法调用的方法列表 • 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.就调用表单的 validate方法进行数据验证; • processForward()—调用requestDispatcher的forward()方法进行页面跳转; • processInclude()--调用requestDispatcher的include()方法进行页面输出; • processActionCreate()—创建一个action的实例存放到缓存中; • processActionPerform()—调用action的execute()方法; • precessActionForward()—根据action的execute()的返回值进行页面跳转;

  8. 扩展RequestProcessor处理文字编码问题 • 我们可以去重写requestProcessor类的processPreprocess方法去处理编码; • 并在struts-config.xml文件里面配置 <controller processorClass="struts.requestprocessor.MyRequestProcessor"> </controller>

  9. 例:MyRequestProcesser类 publicclass MyRequestProcessor extends RequestProcessor { protectedboolean processPreprocess(HttpServletRequest request, HttpServletResponse response) { try { request.setCharacterEncoding("GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } returnsuper.processPreprocess(request, response); } }

  10. ActionForm • org.apache.struts.action.ActionForm的子类的实例 • 用于保存用户请求表单中的数据,并可保持其状态的连续性,即在不同的页面间传递这些数据 • 由开发者定义的子类(ActionForm Bean类)中主要包含和用户表单数据同名的属性以及相应的存取方法(属性的get方法和set方法),而没有商业逻辑 • 此外,还可根据需要重写从父类继承来的reset()和validate()方法,实现属性重置和表单数据验证功能

  11. 处理ActionForm Bean的基本步骤 1)检查并确认在Action中已经配置了对表单Bean的映射。 2)根据表单Bean的name属性,查找表单Bean的配置信息。 3)检查该表单Bean的使用范围,查找在该范围内,是否已存在该Bean的实例。如果已经存在,那么就重用该实例。否则,就重新创建一个。 4)调用该Bean实例的reset()方法重置其状态。 5)调用该Bean实例相应的setter方法,使用请求表单中的数据填充Bean的属性。 6)如果起用了validate机制,则调用表单Bean的validate()方法。如果validate()方法返回任何错误,则跳过步骤7)转到预定的出错处理页面。 7)将该表单Bean实例作为参数,传给处理器对象的execute()方法并执行。

  12. ActionForm的生命周期 接收控制器的请求 如果校验失败,将请求转发给<action> 的input属性所指定的web组件,并将 FormBean保存在指定的范围中 从request或session范围中取出 ActionForm对象,如果不存在就new一个 调用ActonForm对象的reset方法 如果校验成功调用Action的execute方法 并将FormBean传递给该方法 将FormBean对象保存在scope 指定的范围内 将请求转发给<action指定的web组件, 并将FormBean保存在指定的范围中 将用户的表单数据封装在FormBean中 如果<action>中的validate属性为true,调 用FormBean的validatte()方法

  13. Action Bean • Action类是Struts架构中控制器组件的重要组成部分.它是用户请求和业务逻辑之间的媒介. • org.apache.struts.action.Action子类类型, RequestProcessor调用它以处理不同的页面请求 • 它通过如下的方式发挥作用:开发者事先创建一个或多个Action的子类,在子类中加入所需要的处理逻辑,用于处理不同的业务逻辑.我们称这些子类为处理器类或ActionBean类 • 当Struts架构的核心控制器ActionServlet委托RequestProcessor对象处理一个用户的请求时, RequestProcessor对象除了使用FormBean来接受表单的数据外,还会查找配置文件中的<action-mapping>元素,根据请求页面的URI确定匹配的<action>子元素(参见下面的蓝色代码) • RequestProcessor对象会针对当前用户请求寻找一个可用的Action类型的对象.如果找不到就创建一个新的对象,然后将客户端的请求发送给该处理器类的对象,并调用Action子类的execute方法进行处理. <action-mappings> <action path="/regist" type="test.RegistAction" name="formBean1" scope="session" /> <action path="/overview" forward="/links.jsp"/> </action-mappings>

  14. ActionBean public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception • mapping :是对struts-config.xml文件中配置信息的一个映射,它封装了当前处理器类对象(既ActionBean)的相关信息

  15. ActionBean 设计ActionBean时注意事项 • RequestProcessor对象对于每种ActionBean类型只创建一个实例.该实例将被用于所有匹配的请求,这就需要我们在定义ActionBean类时考虑如果在多线程的条件下使用.一个重要的原则就是在ActionBean类中尽量使用局部变量而不是实例变量 • 尽量在ActionBean类中加入异常处理逻辑,在方法内部捕获和处理可能出现的异常,而不是简单的抛出 • 在控制器将请求重新定向到其他页面前,释放ActionBean组件作占用的资源(如数据库连接) • 要避免将所有的业务逻辑都直接写在ActionBean类中,这样会导致ActionBean类的可读性和可维护性变差.由于这些商业的业务逻辑代表被嵌入到只能运行在Web应用程序环境的组件中,很难做到代码重用 • 综上所述,ActionBean通常负责将客户端请求映射到处理这些请求的业务逻辑Bean,在转向生成响应回送到客户端解码,实际上起到Controll和Model之间的适配器作用,属于低层面的控制器

  16. ActionMapping • org.apache.struts.action.ActionMapping类型 • 系统针对每个<action>元素都创建一个与之对应的 ActionMapping • 当ActionServlet转发请求时,ActionMapping实例被作为参数之一传递给相应Action对象的execute()方法 • ActionMapping对象映射的配置信息主要来自配置文件中的<action-mapping>和<global-forward>元素

  17. ActionForward • 一种配置对象,映射配置文件struts-config.xml中的<forward>元素,封装目标响应页面URI。 • <forward> 元素不但可以定义在<global-forwards>元素中,作为全局的配置信息,也可以定义在<action>元素中,此时只能用于特定的Action处理. • ActionForward的主要属性: • name - 本ActionForward对象的标识,在Action Bean类 • 的execute()方法中,ActionMapping对象的 • findForward()方法就是根据此标识来查找相应 • 的ActionForward对象的。 • path - 目标响应页面URI • redirect - 标明页面转向的方式 <global-forwards> <forward name="failed" path="/error.jsp"/> <forward name="successed" path="/right.jsp"/> </global-forwards>

  18. 模型组件 • 一般使用JavaBean来实现Model组件,对应着其作用可以分为两方面: • 系统状态Bean(Application State) • 业务逻辑Bean(Business Logic Bean) • JavaBean的作用范围: • page request session application

  19. 视图组件 • 视图组件中提交的请求被控制器组件接收.在实际的开发 中,在视图组件内可以提交请求的途径主要有两种 • HTML表单:通过表单的action属性来指定 • HTML超连接 <a href=“regist.do”>注册新用户 如果需要在发送请求的时候携带参数,可以按照如下 的方式 <a href=“regist.do”?name=aaa&password=aaa>注册 • 在视图组件中还可以使用Struts标记库

  20. 标记库初步 • Struts在国际化的过程中会用到一个特殊的JSP标记<bean:message/>,用来获取属性文件中存放的字符串信息,在使用前,首先要部署包含此标记定义的Struts标记库,具体做法是: • 将Struts发布包中的标记库文件struts-bean.tld复制到当前应用程序的WEB-INF下 • 在web.xml文件中添加相应的<taglib>子元素 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> </web-app> • 在使用<bean:message/>标记的JSP文件中开头引入标记库文件 <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> 这样我们就可以在JSP中使用<bean:message>标记了

  21. 应用程序国际化 • 本地化:针对不同的语言版本环境的客户开发出不同语言环境的软件版本.如果需要对Web应用进行中文本地化操作,要注意处理中文乱码的问题:<%@ page pageEncoding="GBK" contentType="text/html; charset=GBK"%> • 国际化:应用程序在运行时能够根据客户端请求所来自的国家/地区、语言的不同而显示不同的用户界面 internationalization,简称I18N。 • 资源包和属性文件:国际化能够提供多种语言界面,就应该在某个地方存放着所用到的各种语言的标签信息。这些字符串类型的信息事先已保存在多个文本文件中,每个文本文件对于一种不同语言的版本。这些文件我们称为属性文件,所有属性文件合作一起,我们称为资源包。 在struts-config.xml文件中添加<message-resources/>元素,用来指明所要用到的资源包 <struts-config> <message-resources parameter=“MyResource”> <struts-config> • 属性文件中包含的是“键-值”对形式的字符串信息。该文件在程序启动时被载入内存,并根据客户端请求所携带的语言/地区信息进行匹配和使用,

  22. 应用程序国际化 • 属性文件的命名格式: • 文件名前缀.properties • 文件名前缀_语言种类.properties • 前缀由开发者自行确定,后缀名必须固定为.properties,语言 • 种类是有效的ISO语言代码,ISO639标准定义的这些代码的 • 格式为:英文小写、双字符,见下表 • 缺省的属性文件

  23. 案例: 实现程序国际化 • 英文属性文件 MyResource.properties # Simple properties file for test. title.welcome = Welcome you! title.imageEnter=/enter.gif title.imgEnterHint=classmate title.imageRegist=/register.gif title.imgRegistHint=regist label.deny = Sorry,Login Failed! item.submit = submit item.reset = reset item.username = UserName item.password = Password item.password2 = Confirm Password item.regist = click here to regist item.loginAgain = login again item.registsubmit = regist item.back = go back to login

  24. 中文属性文件 MyResource_zh.properties # 中文属性文件 title.welcome = 欢迎欢迎 title.imageEnter=/enter.gif title.imgEnterHint=同学录 title.imageRegist=/register.gif title.imgRegistHint=注册 label.deny = 抱歉,登陆失败 item.submit = 提交 item.reset = 重制 item.username = 用户名 item.password = 密码 item.password2 = 确认 item.regist = 注册新用户 item.loginAgain = 重新登陆 item.registsubmit = 注册 item.back = 返回登陆

  25. 为了更好的解决中文问题,使用java提供的native2ascii命令来对中文属性文件进行编码.在cmd下执行该命令 格式如下: native2ascii -encoding gb2312 MyResource_zh.properties MyResource_zh_new.properties

  26. 重新编码后的中文属性文件格式如下 # \u4e2d\u6587\u5c5e\u6027\u6587\u4ef6 title.welcome = \u6b22\u8fce\u6b22\u8fce title.imageEnter=/enter.gif title.imgEnterHint=\u540c\u5b66\u5f55 title.imageRegist=/register.gif title.imgRegistHint=\u6ce8\u518c label.deny = \u62b1\u6b49,\u767b\u9646\u5931\u8d25 item.submit = \u63d0\u4ea4 item.reset = \u91cd\u5236 item.username = \u7528\u6237\u540d item.password = \u5bc6\u7801 item.password2 = \u786e\u8ba4 item.regist = \u6ce8\u518c\u65b0\u7528\u6237 item.loginAgain = \u91cd\u65b0\u767b\u9646 item.registsubmit = \u6ce8\u518c item.back = \u8fd4\u56de\u767b\u9646

  27. Validate()方法 当Struts的配置文件满足以下两个条件,Struts控制器就会调用ActionForm的validate()方法; • 为ActionForm配置了Action映射,即<form-bean>元素里面name和<action>元素里面的name相匹配; • <action>元素的validate属性为true; 方法返回ActionErrors对象,如果该对象为空或不包含任何ActionMessage对象,那么就表示验证通过;反之把ActionErrors存到request中并返回input页面;

  28. 表单验证和错误处理 • 重写ActionForm的validate方法; • 在validate方法里根据ActionForm中填充的属性值判断是否适合程序的要求; • 返回一个ActionErrors对象; • ActionErrors对象是一个MAP集合,存放的全都是ActionMessage对象; • ActionMessage对象的错误提示配合Resource bundle文件使用; • 如果ActionErrors集合里没有ActionMessage对象,则通过数据验证,执行Action的execute方法,否则返回ActionMapping对象用的input页面,并通过<html:errors>标签显示ActionMessage中的错误提示;

  29. public ActionErrors validate(ActionMapping mapping, javax.servlet.http.HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if(this.name.equals("") || this.name ==null){ errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.name.required")); } if(this.psw.equals("") || this.psw ==null){ errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.psw.required")); } return errors; }

  30. 修改语言包 • 英文属性文件 error.name.required = <li><font color="red">UserName is not null</font></li> error.psw.required = <li><font color="red">Psw is not null</font></li><br> • 中文属性文件 error.name.required = <li><font color="red"> \u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a</font></li> error.psw.required = <li><font color="red"> \u5bc6\u7801\u4e0d\u80fd\u4e3a\u7a7a</font></li><br>

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

More Related