zoukankan      html  css  js  c++  java
  • Struts 笔记

    Struts 概述

    随着MVC 模式的广泛使用,催生了MVC 框架的产生。在所有的MVC 框架中,出现最早,应用最广的就是Struts 框架。

    Struts 的起源

    Struts 是Apache 软件基金组织Jakarta 项目的一个子项目, Struts 的前身是CraigR. McClanahan 编写的JSP Model2 架构。

    Struts 在英文中是"支架、支撑"的意思,这表明了Struts 在Web 应用开发中的巨大作用,采用Struts 可以更好地遵循MVC 模式。此外, Struts 提供了一套完备的规范,以基础类库,可以充分利用JSP/Servlet 的优点,减轻程序员的工作量,具有很强的可扩展性。

    Struts优点

    提高开发效率,减轻了程序员的工作量,降低了重复代码(降低代码冗余),文件不再臃肿。

    可以规范软件开发的行为。ActionForm为我们封装请求数据

    增加代码的扩展性、移植性

    提高代码的可重用性、可读性,无需多个Servlet多个方法

    Action转发页面只须配置跳转资源即可,无效全路径、硬编码。降低代码的耦合性

    Struts 架构的工作原理

    1. Model 部分

    Struts 的Model 部分由ActionForm和JavaBean 组成。其中ActionForm用于封装用户请求参数,所有的用户请求参数由系统自动封装成ActionForm 对象:该对象被ActionServlet转发给Action; 然后Action 根据ActionForm里的请求参数处理用户请求。JavaBean 则封装了底层的业务逻辑,包括数据库访问等。在更复杂的应用中,JavaBean所代表的绝非一个简单的JavaBean,可能是EJB 组件或者其他的业务逻辑组件。该Model 对应图3 .4的Model 部分。

    2. View 部分

    Struts 的View 部分采用JSP 实现。Struts 提供了丰富的标签库,通过这些标签库可以最大限度地减少脚本的使用。这些自定义的标签库可以实现与Model 的有效交互,并增加了显示功能。对应图的JSP 部分。

    整个应用由客户端请求驱动,当客户端请求被ActionServlet 拦截时, ActionServlet根据请求决定是否需要调用Model 处理用户请求,当用户请求处理完成后,其处理结果通过JSP 呈现给用户。

    3. Controller部分

    Struts 的Controller 由两个部分组成。

    ·系统核心控制器—拦截用户请求ActionServlet 派发请求

    ·业务逻辑控制器—处理用户请求的Action,处理业务逻辑

    其中,系统核心控制器是一个ActionServlet。该控制器由Struts 框架提供,继承HttpServlet类,因此可以配置成一个标准的Servlet。该控制器负责拦截所有Http请求,然后根据用户请求决定是否需要调用业务逻辑控制器,如果需要调用业务逻辑控制器,则将请求转发给Action 处理,否则直接转向请求的JSP 页面。业务逻辑控制器负责处理用户请求,但业务逻辑控制器本身并不具有处理能力,而是调用Model 来完成处理。业务逻辑控制器对应图3 .4中的Action 部分。

    clip_image002

    下面结合图3.7 对Struts 的工作流程作详细的讲解。

    Web 应用都是请求一响应的程序结构。程序是由客户端Client 发出Http 请求开始的,客户端请求被ActionServlet 拦截。在ActionServlet 处,有两种情况:

    ·要求逻辑控制器处理的请求:

    ·简单转发的请求。

    对于第一种的请求,ActionServlet 需要调用对应的Action。因此ActionServlet 将请求转发到Action ,如果请求还配置了对应的FormBean,则ActionServlet 还负责用请求参数填充ActionForm,此时如果ActionForm还没有创建。ActionServlet会帮我们创建一个可以用的ActionForm,如果ActionForm已经创建就直接给我们用, ActionForm 的实质就是JavaBean,专门用于封装请求参数。并且在次期间,如果ActionForm如果有验证方法,会去执行验证方法,如果验证通过会进入Action中。验证失败,会跳转到Action配置的input资源页面。

    此时的Action 将无须从HTTP Request 中获取请求参数,而是从ActionForm 中获得请求参数。Action 获得请求参数后,调用Model 对象由JavaBean 处理用户请求。Action处理完用户请求之后,将处理结果包装成ActionForward,回送给ActionServlet。

    由于ActionForward 对象封装了JSP 资源的映射。因此, ActionServlet 知道调用合适的JSP 资源表现给客户端。

    对于第二种请求, HTTP 请求无须Action 处理,只是对普通资源的请求,作为超级链接的替代。因为ActionServlet 直接将该请求转发给JSP 资源,既不会填充ActionForm,也无须调用Action 处理。

    JSP 页面在表现之前,还需要调用对应的JavaBean,此处的JavaBean 不再是包含业务逻辑的JavaBean,而是封装了处理结果的普通vo (值对象)。JSP 页面根据vo 的值,可能利用JSTL 或者Struts 的标签库来生成HTTP 响应给客户端。总之JSP 应尽量避免使用Java 脚本。

    Action配置

    path是我们请求访问的路径,如果用struts标签,会默认加上.do的后缀。ActionServlet拦截到*.do的请求后,就进行相应的业务处理,然后派发到path对应的Action;

    name是Action对象的ActionForm,ActionForm是封装请求的信息,如表单

    attribute和name一样,可以省略,在省略的情况下用name。都是对应ActionForm

    type是Action对象对应的文件路径,含包名

    scope是ActionForm的作用域,默认request

    parameter后带方法名称,即请求所执行的方法

    forward是转发后的资源页面

    ActionForward配置

    name逻辑名称和Action中的mapping.forward参数对应

    path对应映射的JSP页面

    redirect是否重定向请求

    forward有全局和局部的2种,如果当前Action配置的forward资源在当前配置的Action中没有找到,然后回到全局的forward资源中查找。局部优先全局

    ActonForm配置

    name是form的名称

    type是form的包名+文件名

    ActionForm还有动态ActionForm、验证ActionForm

    国际化I18N(Internationalization

    目的:是适应更多的、更好的用户界面

    Java 程序的国际化主要通过如下三个类完成。

       java.util. ResourceBundle: 对应用于加载一个资源包。

       java.util.Locale: 对应一个特定的国家/区域及语言环境。

       java.text.MessageFormat: 用于将消息格式化。

    为了实现程序的国际化,必须先提供程序所需要的资源文件。资源文件的内容是和很多key-value 对。其中key 是程序使用的部分,而value 则是程序界面的显示。

    资源文件的命名可以有如下三种形式。

       baseName _language_country.properties。

       baseName _language.properties。

       baseNarne.properties 。

    其中baseName 是资源文件的基本名,用户可以自由定义。而language 和count可都不可随意变化,必须是Java 所支持的语言和国家。

    1.国际化支持的语言和国家

    事实上, Java 也不可能支持所有国家和语言,如需要获取Java 所支持的语言和国家,可调用Locale 类的getAvailableLocale 方法来获取。该方法返回一个Locale 数组,该数组里包含了Java 所支持的语言和国家。

    2. 编写国际化所需的资源

    国际化所需的资源文件内容是key-value 对,下面提供了两个资源文件,这两个资源文件很简单,只包含一个key-value 对。

    下面是MyResource.properties 的文件的内容:

    资源文件的内容: key-value 对。

    msg=Hello , {O} Today is {1}.

    下面是MyResource_zh_CN.properties 文件的内容:

    资源文件的内容: key-value 对

    msg=你好. {O} 今天是{l}。

    所有资源文件的key 都是相同的,只是value 会随国家和语言的不同而变化。

    3.程序从哪里获取资源呢?

    在ResourceBundle 加载资源时按如下顺序搜索。

    搜索所有国家和语言都匹配的资源文件,例如,对于简体中文的环境,先搜索如下文件:

    MyResource_zh_CN.properties

    如果没有找到国家和语言都匹配的资源文件,则再搜索语言匹配的文件,即搜索如下文件:

    MyResource_zh.properties

    如果上面的文件依然无法搜索到,则搜索baseNarne 匹配的文件,即搜索如下文件:

    MyResource.properties

    4. 使用类文件代替资源文件

    Java 也允许使用类文件代替资源文件,即将所有的key-value对存入class 文件,而不是属性文件。

    用来代替资源文件的Java 文件必须满足如下条件。

    ·类的名字必须为baseNarne_language_country,这与属性文件的命名相似。

    ·该类必须继承ListResourceBundle,并重写getContents 方法,该方法返回Object数组,该数组的每一个项都是key=value 对。

    eg:下面的类文件可以代替上面的属性文件:

    public class MyResource_zh_CN extends ListResourceBundle {

        // 定义资源

        private final Object myData[][] = { "msg" , " {0}您好!今天是{l} "};

        //重写方法getContents()

        public Object[] [] getContents() {

            //该方法返回资源的key-value对

            return myData;

        }

    }

    如果系统同时存在资源文件及类文件,则系统将以类文件为主,而不会调用资源文件。对于简体中文的Locale, ResourceBundle 搜索资源的顺序是:

    (1) baseName zh CN.class 。

    (2) baseNarne_zh_CN.properties。

    (3) baseNarne zh.class 。

    (4) baseNarne_zh.properties。

    (5) baseNarne.class。

    (6) baseNarne.properties。

    当系统按上面的顺序搜索资源文件时,如果前面的文件不存在,则会使用下一个:如果一直找不到对应的文件,系统将抛出异常。

    struts加载资源文件

    资源文件的加载通过struts-config.xml文件来配置,加载资源文件应从Web 应用的WEB-INF/classes路径开始加载。因此,资源文件必须放在WEB-INF/classes路径或该路径的子路径下。如果直接放在WEB-INF/classes 路径下,在配置资源文件时,直接指定资源文件的baseName 即可。但如果放在子路径下,则必须以包的形式配置。

    动态ActionForm

    Why当一个form表单的属性、字段非常多的情况下,需要我们不断的修改、添加ActionForm中的属性,并提供getter、setter方法。虽然这个类比较简单,但是大量重复的getter、setter方法也是比较繁琐的。这个时候struts的动态ActionForm就派上用场了。使用动态ActionForm 的目的是为了减少代码的书写量,但是相对在配置方面要复杂些。

    配置动态ActionForm

    所有的动态ActionForm 的实现类都必须是org.apache.struts.action.DynaActionForm类,或者是它的子类。使用动态ActionForm 与前面不同的是:因为系统不清楚动态ActionForm 的属性,所以必须在配置文件中配置对应的属性。可以使用form-property 元素来配置动态ActionForm 的属性。

    <!一配置动态ActionForm,动态Aciton 必须使用乌rnaActionForm 一〉

    <form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm">

         <!一配置ActionForm的属性: username-->

         <form-property name="username" type="java.lang.String"/>

         <! 配置ActionForm的属性: pass-->

         <form-property name="pass"type="java.lang.String"/>

    </form-bean>

     

    <!-- 配置Action中的path , type , name 属性>

    <action path="/login" type="com.hoo.LoginAction" name="loginForm">

         <!一配置两个局部Forward-->

         <forward name="welcome" path="/WEB-INF/jsp/welcome.jsp"/>

         <forward name="input" path="/login.jsp"/>

    </action>

    从上面的配置文件可看出,动态ActionForm 的配置必须增加form-property 元素,每个属性必须对应一个form-property元素。

    form-property元素包含两个属性。

    name: 属性的名字,必须与JSP 页面的表单域的名字相同。

    type: 属性的类型。

     

    使用动态ActionForm

    //必须重写该核心方法,该方法actionForm 将表单的请求参数封装成值对象

    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

         //将ActionForm强制类型转换为DynaActionForm

         DynaActionForm loginForm = (DynaActionForm)form;

         //从ActionForm中解析出请求参数: username

         String username = (String)loginForm.get("username");

         //从ActionForm中解析出请求参数: password

         String pass = (String)loginForm.get("pass");

         //后面的处理与前一个示例的Action 相同。

         …………

    }

    使用动态ActionForm 时,请求参数必须使用DynaActionForm的getter 方法获取。

    DynaActionForm 的getter 方法主要有如下三个。

    Object get(java.lang.String name): 根据属性名返回对应的值。

    Object get(java.lang.String name, int index): 对于有多个重名表单域的情况, Struts将其当成数组处理,此处根据表面域名和索引获取对应值。

    Object get(java.lang.String name, java.lang.String key): 对于使用Map 属性的情况,根据属性名及对应key. 获取对应的值。

    Struts 的标签库

    Struts 提供了大量的标签库,用于完成表现层的输出。借助于Struts 的标签库,可避免在JSP 中嵌入大量的Java 脚本,从而提高代码的可读性。

    Struts 主要提供了如下三个标签库。

    A、 html: 用于生成HTML 的基本标签。

    B、 bean: 用于完成程序国际化,输出Struts 的ActionForm 的属性值等。

    C、 logic: 用于完成循环、选择等流程控制。

     

    使用html 标签库

    Struts 为htrnl 的大部分标签提供了对应的htrnl 标签, htrnl 所支持的标签大致有如下。

    * base: 表现成一个HTML 的<base>标签。

    * button: 表现成一个按钮,该按钮默认没有任何动作。

    * cancel: 表现成一个取消按钮。

    * checkbox: 表现成一个Checkbox 的输入框。

    * error: 用于输出数据校验的出错提示。

    * file: 表现成一个文件浏览输入框。

    * form: 表现成一个form 域。

    * frame: 表现成一个HTML<frame>标签。

    * hidde: 表现成一个隐藏域。

    * htrnl: 表现成HTML 的<htrnl>标签。

    * image: 表现成表单域的image 域。

    * img: 表现成一个HTML 的img 标签。

    * javascrit: 表现成JavaScript 的校验代码,这些校验代码根据ValidatorPlugIn 生成。

    * link: 表现成HTML 的超级链接。

    * messages: 用于输出Struts 的各种提示信息,包括校验提示。

    * multibox: 表现成一个Checkbox 输入框。

    * option: 表现成选择框的一个选项。

    * password: 表现成一个密码输入框。

    * radio: 表现成一个单选输入框。

    * reset: 表现成一个重设按钮。

    * rewrite: 表现成一个URL 。

    * select: 表现成一个列表选择框。

    * submit: 表现成一个提交按钮。

    * text: 表现成一个单行文本输入框。

    * textarea: 表现成一个多行文本框。

     

    使用bean 标签库

    bean 标签库主要用于输出属性值、提示消息及定义请求参数等。下面是bean 标签库的常用标签。

    * cookie: 将请求的cookie 的值定义成脚本可以访问的JavaBean 实例。

    * define: 将某个bean 的属性值定义成脚本可以访问的变量。

    * header: 将请求头的值定义成脚本可以访问的变量。

    * include: 将某个JSP 资源完整定义成一个bean 实例。

    * message: 用于输出国际化信息。

    * page: 将page Context 中的特定项定义成一个bean 。

    * parameter: 将请求参数定义成脚本可以访问的变量。

    * resource: 加载Web 应用的资源,并将其变成JavaB eano

    * struts: 用于将某个Struts 的内部配置成一个bean 。

    * write: 用于输出某个bean 的属性值。

     

    使用logic 标签库

    logic 标签库是使用最频繁,相对复杂的标签库。logic 标签库主要用于完成基本的流程控制,比如循环及选择等。

    logic 标签库主要有如下标签。

    * empty: 如果给定的变量为空或者为空字符串,则就计算并输出标签体的内容。

    * equal: 如果给定变量与特定的值相等,则会计算并输出该标签体的内容。

    * forward: 将某个页面的控制权forward 确定的ActionForward 项。

    * greaterEqual: 如果给定变量大于或等于特定的值,则会计算并输出标签体的内容。

    * greaterThan: 如果给定变量大于特定的值,则会计算井输出标签体的内容。

    * iterate: 通过遍历给定集合的元素,对标签体的内容进行循环。

    * lessEqual: 如果给定变量小于或等于特定的值,则会计算并输出标签体的内容。

    * lessThan: 如果给定变量小于特定的值,则会计算并输出标签体的内容。

    * match: 如果特定字符串是给定消息合适的子字符串,则会计算并输出标签体的内容。

    * messagesNotPresent: 如果请求中不包含特定的消息内容,将计算并输出标签体的内容。

    * messagesPresent: 如果请求中包含特定的消息内容,则计算并输出标签体的内容。

    * notEmpty: 如果给定的变量既不为空,也不是空字符串,则计算并输出标签体的内容。

    * notEqual: 如果给定变量不等于特定的值,则会计算并输出标签体的内容。

    * notMatch: 如果特定宇符串不是给定消息合适的子字符串,则会计算并输出标签体的内容。

    * notPresent: 如果特定的值没有出现在请求中,则计算并输出标签体的内容。

    * present: 如果特定的值出现在请求中,则计算并输出标签体的内容。

    * redirect: 重定向页面。

    Struts 的数据校验

    数据校验也称为输入校验,指导对用户的输入进行基本过滤,包括必填宇段,宇段必须为数字及两次输入的密码必须相匹配等。这些是每个MVC 框架都应该完成的任务,Struts 提供了基本的数据校验,如果结合commons-validator, Struts 则拥有强大的校验框架,包括进行客户端的JavaScript 校验等。

    Struts 的数据校验大致有如下几种方式:

    ActionForm 的代码校验。

    Action 里的代码校验。

    结合commons-validator.jar 的校验。

     

    ActionForm 的代码校验

    ActionForm 的代码校验是最基本的校验方式。这种校验方式是重写ActionForm 的validate 方法,在该方法内对所有的宇段进行基本校验。如果出现不符合要求的输出,则将出错提示封装在ActionError 对象里,最后将多个ActionError 组合成ActionErrors 对象,该对象里封装了全部的出错提示。并将错误信息用<html:error/>展现在配置的input的失败页面上。

     

    Action 的代码校验

    在Action 里通过代码完成输入校验,是最基本,也最容易使用的方法。与最初的MVC 设计相似,在调用业务逻辑组件之前,先对数据进行基本校验。这是最传统也是最原始的方法。

    这种校验方式非常容易理解,所有的代码都需要程序员自己控制,相当灵活。

    但有如下几个不方便之处。

    ·用户需要书写大量的校验代码,使程序变得烦琐。

    · 数据校验应该在填充ActionForm里完成,最好能在客户端完成校验,而不是推迟到Action 里才完成数据校验。

    注意:在实际的使用中,这种校验方式不仅程序开发复杂,且性能也不高。

     

    结合commons-validator.jar 的校验

    借助于commons-validator.jar 的支持, Struts的校验功能非常强大,几乎不需书写任何代码。不仅可以完成服务器端校验,同时还可完成客户端校验,即弹出Javascript 提示。

    使用commons-validator.jar 校验框架时,有如下几个通用配置。

    ·增加校验资源。

    ·利用ValidatorPlugIn 加载校验资源。

    ·ActionForm 使用ValidatorForm 的于类。

    下面分别通过三个示例讲解这三种校验:基本的校验、对动态ActionForm 执行校验及弹出JavaScript 校验提示。

     

    1. 继承ValidatorForm 的校验

    如果需要使用commons-validator 框架,请按如下步骤进行。

    (1) Struts 的ActionForm必须是ValidatorForm的子类,提供验证属性字段的getter、setter方法

    (2) 编写表单域时必须满足校验规则。校验规则都由规则文件控制,规则文件有以下两个。

    * validator-rules.xml 文件

    * validation.xml 文件

    第一个文件可在Struts 的解压缩后的文件夹的lib 下找到,将该文件复制到WEB-INF

    2. common-validator支持的校验规则

    common-validator支持的校验规则非常丰富,特别是mask 和validwhen 两个规则,

    极大地丰富了该校验框架的功能。

    常用的校验规则有如下几种。

    * required: 必填。

    * va1idwhen: 必须满足某个有效条件。

    * minlength: 输入必须大于最小长度。

    * maxlength: 输入必须小于最大长度。

    * mask: 输入匹配正确的表达式。

    * byte: 输入只能是一个byte 类型变量。

    * short: 输入只能是一个short 类型变量。

    * integer: 输入只能是一个integer 变量。

    * long: 输入只能是一个long 变量。

    * float: 输入只能是一个float 变量。

    * double: 输入只能是一个double 变量。

    * date: 输入必须是一个日期。

    * intRange: 输入的数字必须在整数范围内。

    * floatRange: 输入的数字必须在单精度浮点数范围内。

    * doubleRange: 输入的数字必须在双精度浮点数范围内。

    * email: 输入必须是有效的E-mail 地址。

    * uri: 输入必须是有效的uri 地址。

    3.使用DynaValidatorForm 的校验

    即使不书写ActionForm,也可以利用cornmon-validator 校验框架。此时使用的ActionForm 的实现类,必须既是动态Form ,也是验证Form,DynaValidatorForm 就是满足这两个条件的Form。

    4. 弹出客户端JavaScript提示

    如需要弹出客户端JavaScript 校验非常简单,无须修改其他配置文件,只需修改登录使用的JSP 页面的两个地方。

    (1) 为form 元素增加onsubmit="return validateXxxForm(this);"属性,其中的XxxForm就是需要校验的form 名,与struts-config.xrnl中配置的form-bean 的name 属性一致,也与validation.xrnl文件中需要校验的form 的name 属性一致。

    (2) 增加<html:javascript formName="xxxForm"/> ,其中xxxForm 是需要校验的form 名。

    注意:即使使用了客户端技验规则,也不要删除页面的htm1 :rnessages 标签。因为该标签会在客户端技验通过,而在服务器端技验并未通过时弹出提示。

    Struts 的异常框架

    Struts 1.1 版本中加入了对异常的处理,称之为Exception Handling,标志着作为一个整体的框架, Struts 越来越趋于成熟。

    在以前的Struts 开发过程中,对于异常的处理,主要是采用手动处理的方式:如通过try/catch 等捕获异常:然后将定制个性化的,比较详细的错误信息放进ActionMessage中:最后在返回页面中把这些错误信息反馈给用户。

    对于异常的原始信息,不管是最终用户还是开发员都不希望看到。

    借助于Struts 的异常框架,异常处理只需通过struts-config.xm1文件定义即可。根据异常定义的位置不同,异常可分为局部异常和全局异常两种。

    ·局部异常作为action 的子元素中定义。

    ·全局异常在globa1-excetpions 元素中定义。

    异常定义的格式如下:

    <exception key="keyNarne" type="ExceptionNarne" scope="scope" path="uri"/>: 当Struts 出现ExceptionNarne 的异常时,页面自动转向uri 指向的资源,并在该页面输出keyName 对应的国际化中的出错提示。

    几种常用的Action

    除了基本的Action 之外, Struts 还提供了几个其他类型的Action ,这些Action 大大丰富了Struts 的功能。下面介绍如下儿个常用的Action 。

    * DispatchAction: 能同时完成多个Action 功能的Action 。

    * ForwardActon: 该类用来整合Struts 和其他业务逻辑组件,通常只对请求作有效性检查。

    * IncludeAction: 用于引入其他的资源和页面。

    * LookupDispatchAction: DispatchAction 的子类,根据按钮的key ,控制转发给action的方法。

    * MappingDispatchAction: DispatchAction 的子类,一个action 可映射出多个Action地址。

    * SwitchAction: 用于从一个模块转换至另一个模块,如果应用分成多个模块时,就可以使用SwitchAction 完成模块之间的切换。

     

    DispatchAction

    在该action 的配置中,增加了parameter属性,该属性用于指定参数名,即Struts 将根据该参数的值调用对应的方法。为了让请求增加method 的参数,method参数对应的是要请求执行的方法。

    <action path="/login" type="com.hoo.LoginAction" name="loginForm" scope="request" validate="true" input="login.jsp" parameter="method">

         <forward name="success" path="/welcome.jsp"/>

    </action>

    Login.do?method=login

     

    MappingDispatchAction

    可将同一个Action 的不同方法映射成多个Action URI ,这种Action 的写法与DispatchAction 非常相似,同样不需要重写execute 方法,而是将书写多个自定义的方法。这些方法除了方法名与execute 方法不同外,其他的参数列表及异常处理完全一样。

    <!-- 配置第一个Action. 实现类是com.hoo.LoginAction , parameter 为add-->

    <action path="/add" type="com.hoo.LoginAction" name="loginForm" scope="request" validate="true" input="login.jsp" parameter="add">

         <forward name="success" path="/welcome.jsp"/>

    </action>

    <! 配置第二个Action. 实现类是com.hoo.LoginAction , parameter 为modify-->

    <action path="/modify" type="com.hoo.LoginAction" name="loginForm" scope="request" validate="true" input="login.jsp" parameter="modify">

         <forward name="success" path="/welcome.jsp"/>

    </action>

    其中,path对应的是请求的地址uri,而parameter是对于当前请求所执行的方法;

    注意:使用MappingDispatchAction 并没有带来太大的优势,系统完全可以书写两个Action,分别定义两个不同的action 映射,而其他部分没有区别。

     

    LookupDispatchAction

    LookupDispatchAction也是DispatchAction 的一种,但它的处理更加简单。该Action也可包含多个处理方法,它可让处理方法与按钮直接关联,无须使用任何的JavaScript脚本。因此可通过重写getKeyMethodMap方法完成按钮与Action 中方法的关联。

    //用于关联按钮和方法

    protected Map getKeyMethodMap() {

         Map map = new HashMap();

         //如果按钮标题的key 为button.add. 则提交该按钮时对应add 方法

         map .put ("button. add" , "add");

         //如果按钮标题的key 为button.modify. 则提交该按钮时对应modify 方法

         map.put ("button.modify" , "modify") ;

         return map;

    }

     

    ForwardAction

    如果需要从一个页面或资源转换到另一个资源时,直接使用页面或资源路径的超级链接定位并不是好的做法,这使得控制器没有机会处理相关的请求事直。

    使用ForwardAction可以完成请求的转发,当控制器调用ForwardAction的perform()方法时,它会使用属性parameter 所设定的路径进行forward 的动作。下面是一个设定ForwardAction的例子:

    <actlon-mapplngs>

         <action path="/welcome" type="org.apache.struts.actions.ForwardAction" parameter="/welcome.jsp"/>

    </action-mappings>

    该action 仅仅完成转发,并没有执行其他的额外动作。页面控制转发的代码如下:

    <a href="welcome.do">转入</a>

    当单击转入超级链接时,将可以转向ForwardAction中parameter指向的资源。

     

    IncludeAction

    IncludeAction的用法与ForwardAction的用法比较相似,区别在于ForwardAction将跳转到action 定义的资源,而IncludeAction用于引入该action 对应的资源。

    下面是IncludeAction定义的源代码:

    <action-mapplngs>

         <action path="/welcome" type="org.apache. struts.actions.IncludeAction" parameter="/welcome.jsp"/>

    </action-mappings>

    该action 用于经welcome.jsp 作为资源导入。

    页面中负责加载该action 所导入资源的代码如下:

    <jsp:include page="welcome.do"/><br>

    上面的代码将会把welcome action 定义的资源导入该页面。

     

    SwitchAction

    SwitchAction 主要用于模块之间的切换。当一个应用之中存在多个模块时,使用SwitchAction在不同模块之间的action 之间切换还是相当方便的。

    Struts 的常见扩展方法

    Struts 的强大吸引力还来自于它的可扩展性,其扩展性通常有如下三种方式。

    ·实现PlugIn: 如果需要在应用启动或关闭时完成某些操作,可以创建自己的PlugIn类。

    ·继承RequestProcessor: 如果想在请求被处理中的某个时刻做一些业务逻辑时,可以考虑实现自己的RequestProcessor 类。

    ·继承ActionServlet: 如果需要在每次开始处理请求之前,或者处理请求结束之后完成某些操作,可以实现自己的ActionServlet 来完成扩展。

     

    下面分别从三个方面来介绍Struts 的扩展。

    实现PlugIn 接口

    Struts 已经演示了PlugIn 的扩展方法:与common- validation 的整合。后面还将介绍Spring 与Struts 的整合,也利用了PlugIn 的扩展。

    在下面的应用中,系统使用Hibernate 作为持久层,在启动时创建SessionFactory 实例,并将该SessionFactory 存入application ,在应用关闭时销毁SessionFactory 。只需如下两步即可完成此功能。

    (1) 实现自己的PlugIn 类。

         实现PlugIn 接口必须实现如下两个方法。

         1 void destroy()。

         2 void init(ActionServlet serlet, ModuleConfig config) 。

         应用启动时调用init 方法,而应用关闭时则调用destroy 方法。

         下面是SessionFactoryLoaderPlugIn 的实现类:

         public class SessionFactoryLoaderPlugin implements PlugIn {

              //Hibernate 的配置文件

              private String configFile;

              //应用关闭时,销毁资源

              public void destroy()

                   System.out.println("系统销毁SessionFactory");

              }

              //应用启动时,完成SessionFactory 的初始化

              public void init(ActionServlet actionServlet , ModuleConfig config) throws ServletException

                   System.out.println("系统以" + getConfigFile() + "为配置文件初始化SessionFactory") ;

                  //获取Plugln 配置文件的方法

                   public String getConfigFile() {

                        return configFile;

                   }

              // 负责加载Plugln 配置属性的方法

              public void setConfigFile(String configFile) {

                    this.configFile = configFile;

              }

         }

    在上面的PlugIn 中,并没有真正初始化SessionFactory ,仅在控制台打印出字符串来标识创建动作。另外,还提供了configFile 属性的setter 和getter 方法,这两个方法负责访问plugin 元素的configFile 属性。

     

    ( 2 ) 将SessionFactoryLoaderPlugIn 配置在struts-config.xml 文件中。方法与ValidatorPlugIn 的配置并没有区别,下面是配置SessionFactoryLoaderPlugIn 的代码:

    <plug-in className="hoo.SessionFactoryLoaderPluging">

         <set-property property="conf工gFile" value=" WEB-INF/hibernate.cfg.xml"I>

    </plug-in>

    在配置SessionFactoryLoaderPlugIn 时,配置了configFile 属性,该属性用于确定Hibernate 配置文件的文件名。

     

    继承RequestProcessor

    RequestProcessor 是Struts 的核心类,而Struts 的核心控制器是ActionServlet 。但ActionServlet 并未完成真正的处理,只是调用RequestProcessor , RequestProcessor 才是Struts 的核心类。

    扩展RequestProcessor 的实例在Spring 中有个示范, Spring 提供的Delegating RequestProcessor 是一个很好的示例。下面示例对RequestProcessor 进行简单的扩展。

    RequestProcessor 包含了如下常见的方法。

    * ActionForm processActionForm: RequestProcessor填充ActionForm 时执行该方法。

    * Action processActionCreate: RequestProcessor 调用Action 时调用该方法。

    * boolean processPreprocess: 预处理用户请求时执行该方法。

    * boolean processValidate: 处理输入校验时调用该方法。

    扩展RequestProcessor 只需两步即可。

    (2)在struts-config.xml 文件中配置MyRequestProcessor。用户重写了RequestProcessor,但Struts 并不知道,必须在struts-config且nl 中配置才可以。

    下面是配置MyRequestProcessor 的代码:

    <controller processorClass="lee.MyRequestProcessor" />

    该属性的配置应该放在action-mappings元素之后。

    注意:重写RequestProccessor的方法时,别忘了使用super 来调用父类的动作。如果没有调用该方法,意味着开发者必须完成Struts 框架所完成的动作。这是不应该的,因为程序员只是在框架中加入额外的处理,并不是要替代Struts。

     

    继承ActionServlet

    如果需要在开始处理请求,或者处理结束之后加入自己的处理时,可对ActionServlet进行扩展。例如解决中文的编码问题。

    ActionServlet 接收处理请求参数时,并不是按GBK 的解码方式处理请求,因此容易形成乱码。为了解决该问题,可以强制指定ActionServlet 使用GBK 的解码方式。

    继承ActionServlet重写process方法,设置request、response编码为gbk,然后配置在web.xml中。

  • 作者:hoojo
    出处:
    blog:http://blog.csdn.net/IBM_hoojo
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权所有,转载请注明出处 本文出自:
分享道版权所有,欢迎转载,转载请注明出处,谢谢
收藏
关注
评论
查看全文
  • 相关阅读:
    安装MySQLdb
    树莓派及其他硬件平台国内外Linux镜像站全汇总
    rpc使用举例
    SAE上安装第三方模块
    【Java】Map
    【Java】判断字符串是否含字母
    【Android Studio】提示代码忽略大小写
    【iOS】Xcode 离线文档
    【iOS】iOS main() 简介
    【eclipse】No enclosing instance of type A is accessible. Must qualify the allocation with an enclosing instance of type A
  • 原文地址:https://www.cnblogs.com/hoojo/p/2331266.html
  • Copyright © 2011-2022 走看看