`

Struts action mapping (controller的inputforward属性)

阅读更多

1.   Full action
这可以说是Struts action最流行的用法了。它包含一个action类和一个form bean,action mapping如下:
  

Java代码 复制代码
  1. <action path  = "/fullAction"  
  2.            type  = "com.acme.struts.MyAction"  
  3.            name  = "myForm"  
  4.            input = "/WEB-INF/jsp/dataError.jsp">   
  5.            <forward   path="/WEB-INF/jsp/viewResult.jsp"/>   
  6.            <forward   path="/WEB-INF/jsp/busError.jsp"/>   
  7.    </action>  
 <action path  = "/fullAction"
            type  = "com.acme.struts.MyAction"
            name  = "myForm"
            input = "/WEB-INF/jsp/dataError.jsp">
            <forward   path="/WEB-INF/jsp/viewResult.jsp"/>
            <forward   path="/WEB-INF/jsp/busError.jsp"/>
    </action>




1.1. Full action的调用顺序
1. Struts controller组件接受一个请求(request)

2. Struts 找出负责处理该请求的action mapping

3. 如果在指定范围内找不到该form bean的实例或者指定的范围是“request”类型,则创建一个form bean的实例,否则重用该form bean的实例。

4. 如果form bean定义了reset()方法,则调用(1)。

5. Struts利用request参数来填充form bean实例,利用form bean的mutators。(译者注:即set***方法。)(2)

6. 如果“validate”属性没有显式的设为“false”,则struts调用form bean的validate()方法。(3)

7. 如果validate()方法返回非空的ActionErrors对象,则控制流程会被转到action mapping中“input”属性标志的URI。(4a)(译者注:validate()方法返回类型为void,ActionErrors对象是放在request中的)

8. 如果validate()方法返回空的ActionErrors对象或者null,Struts就开始调用action类的excute()方法。(4b)

9. excute()方法返回的是一个ActionForward对象,Struts利用这个ActionForward对象来选择流程的下一个URI。(5)

1.2. 结论和使用提示
1.2.1. 如果ActionForm.validate()返回一个非空的ActionErrors对象,则action类的excute()方法是不会执行的,并且控制流程会被转到action mapping中“input”属性标志的URI。
1.2.2.  到action mapping中的“input”属性只允许转发(forward)URI。如果你需要重定向(redirect),使用Controller.inputForward属性,这个属性在struts1.1时引入,当“inputForward”属性设为true的时候表明“input”属性不是URI,而是Action.forward元素的名称。

译者注:Forward和Redirect的区别如下,但是上文redirect指的只是URI还是Action.forward元素,这两者是不同的。

Forward是container直接将request到一个别的组件,这种方式下,实际上也就是response之前,用户请求request对象可以经过多个组件处理。request的parameters会传递到新的组件,如果新的组件path也包含querystring,这部分参数也会加到request中,如果参数名重复,就覆盖旧的值。这种是Forward元素定义的forward对象缺省的转向方式。


Redirect方式利用的是HTTP协议中的redirect机制,让客户端发起新的请求,到新的URI。初始的参数和request上下文都不在了。只有ActionForward路径中定义的参数。这种方式需要在struts配置文件中,将Forward元素的redirect属性设置为true。


2.   Form-only action
包含一个自定义的form bean 和一个标准的ForwardAction类(Struts内置的)。这种用法可以用于一个action只有两种结果,其中之一是错误。

 

Java代码 复制代码
  1. <action path  = "/formOnlyAction"  
  2.            type  = "org.apache.struts.actions.ForwardAction"  
  3.            name  = "myForm"  
  4.            input = "/WEB-INF/jsp/error.jsp"  
  5.            parameter = "/WEB-INF/jsp/viewResult.jsp"  
  6.    />  
 <action path  = "/formOnlyAction"
            type  = "org.apache.struts.actions.ForwardAction"
            name  = "myForm"
            input = "/WEB-INF/jsp/error.jsp"
            parameter = "/WEB-INF/jsp/viewResult.jsp"
    />





2.1. Form-only调用顺序
1.         如果在指定范围内找不到该form bean的实例或者指定的范围是“request”类型,则创建一个form bean的实例。否则重用该form bean的实例。

2.         如果form bean定义了reset()方法,则调用(1)。

3.         Struts利用request参数来填充form bean实例,利用form bean的mutators。(译者注:即set***方法。)(2)

4.         如果“validate”属性没有显式的设为“false”,则struts调用form bean的validate()方法。(3)

5.         如果validate()方法返回非空的ActionErrors对象,则控制流程会被转到action mapping中“input”属性标志的URI。(4a)(译者注:validate()方法返回类型为void,ActionErrors对象是放在request中的)。

6.         如果validate()方法返回空的ActionErrors对象或者null,则控制流程会被转到action mapping中“parameter”属性标志的URI。(4b)


2.2. 结论和使用提示
1. 在这里没有放业务逻辑代码的action类,所有的客户代码都在form bean的reset() 或者validate()方法中。

2. validate()方法有两个作用:一是验证request参数,一是访问业务层。

3. 因为action mapping中没有包含“forward”元素,所以控制只能被转发,不能被重定向。

4. Form-only Action的一个可能的用处是reponse修饰,一个form bean能够从request中接受一个业务对象ID,然后从业务/持久层中查找该业务对象,填充form bean的字段,然后转发到一个JSP页面来显示数据。

5. 对于Form-only Action,配置成“session”范围是比较方便的,这样可以缓存数据。
3.   Action class-only action
Struts不要求为actionmapping定义个formbean,如下。

  

Java代码 复制代码
  1. <action path  = "/actionOnlyAction"  
  2.             type  = "com.acme.struts.MyAction"  
  3.             input = "/WEB-INF/jsp/error.jsp">   
  4.             <forward   path="/viewResult.do"/>   
  5.             <forward   path="/WEB-INF/jsp/error.jsp"/>   
  6.     </action>  
<action path  = "/actionOnlyAction"
            type  = "com.acme.struts.MyAction"
            input = "/WEB-INF/jsp/error.jsp">
            <forward   path="/viewResult.do"/>
            <forward   path="/WEB-INF/jsp/error.jsp"/>
    </action>


3.1. Action-class调用顺序
1.  Action类的execute()方法被调用。

2.  execute()方法返回一个ActionForward对象,其目标URI必须定义在forward元素里。


3.2. 结论和使用提示
1. 由于没有定义form bean ,所以struts传递给execute()方法的form参数是null。

2. 如果action类需要接受,则必须手工的从request中获得。所以这种方法只能用在没有或者很少需要从request中获得参数,否则还不如直接用form bean更方便些。

3. 控制可以被转发或者重定向到另一个action或者JSP页面。如果转发到JSP,要确保在制定范围内存在带有输出数据的form bean。

4. 这种方法不能用于HTML FORM,因为struts依赖于action mapping 中与此action关联的form bean 来定义此FORM。所以,你只能在链接(link)中使用此方法。



4.  JSP-only action
这种方式比较少用,更紧凑,比较容易出错。被用于从另外一个action转发,或者有其他方法获得所要的数据。

  

Java代码 复制代码
  1. <action path  = "/actionOnlyAction"  
  2.             type  = "com.acme.struts.MyAction"  
  3.             input = "/WEB-INF/jsp/error.jsp">   
  4.             <forward   path="/viewResult.do"/>   
  5.             <forward   path="/WEB-INF/jsp/error.jsp"/>   
  6.     </action>  
<action path  = "/actionOnlyAction"
            type  = "com.acme.struts.MyAction"
            input = "/WEB-INF/jsp/error.jsp">
            <forward   path="/viewResult.do"/>
            <forward   path="/WEB-INF/jsp/error.jsp"/>
    </action>




4.1. 调用顺序
1. Struts controller组件接受request。

2.  调用ForwardAction.execute()

3.  ForwardAction.execute()转发控制到“parameter”参数定义的action。

4.2. 结论和使用提示
1. 这种方式没有用到form bean,所以不会创建一个 form bean,也不会初始化、填充数据和传递到action类中。

2. 虽然这种方式称作JSP-only,但是如果需要,也可以转发到action。

3. 由于这个操作中没有form bean被创建,所以JSP依赖的form bean来自于指定范围中先前创建的form bean。form bean可以在先前的action中创建并转发到此action中

4. 这种方式的使用的非常少。例如,它可以作为转换码来转发到另一个action。 当应用被编译和部署后,可以利用这种action转换操作。


5.   Two actions, one form
Struts允许从一个action调用另一个action,这样就可能实现一个简单的责任链。

  

Java代码 复制代码
  1. <action path  = "/sourceAction"  
  2.            type  = "com.acme.struts.Action1"  
  3.            name  = "myForm"  
  4.            input = "/WEB-INF/jsp/error1.jsp">   
  5.            <forward   path="/targetAction.do"/>   
  6.    </action>  
 <action path  = "/sourceAction"
            type  = "com.acme.struts.Action1"
            name  = "myForm"
            input = "/WEB-INF/jsp/error1.jsp">
            <forward   path="/targetAction.do"/>
    </action>


   

Java代码 复制代码
  1. <action path  = "/targetAction"  
  2.             type  = "com.acme.struts.Action2"  
  3.             name  = "myForm"  
  4.             input = "/WEB-INF/jsp/error2.jsp">   
  5.             <forward   path="/WEB-INF/jsp/viewTarget.jsp"/>   
  6.     </action>  
<action path  = "/targetAction"
            type  = "com.acme.struts.Action2"
            name  = "myForm"
            input = "/WEB-INF/jsp/error2.jsp">
            <forward   path="/WEB-INF/jsp/viewTarget.jsp"/>
    </action>




5.1. 结论和使用提示
这种方式的顺序与full-action这种方式没有什么不同。问题是,struts会为目标action重复调用reset() 和validate()方法,并且也会为form bean 的属性重新赋值。要把form bean当作传输/命令对象,我们必须防止这些属性被重新赋值。

  解决方式依赖于目标action是如何被调用的。如果目标action是被转发的(forward),我们可以在HttpRequest对象中设置一个令牌来区别是否是链中的第一个action:

l  在form bean 的reset()方法中检测令牌。如果令牌没有找到,则表示是链中的第一个action。如果令牌找到,就不要复位form bean的属性了,因为这是一个链action。

l  在request中放置一个令牌。这个必须在reset()方法中做,因为该方法总是被调用而不是象validate()方法。如果struts-config.xml 中,该action mapping的“validate”属性被设为“false”,validate()方法就不会被调用。

l 在每个mutator中判断,这个action是否是链中的第一个,如果不是,就不要改变属性值了。

l 同样的判断在validate()方法。

没有必要从request对象中除掉令牌,因为request对象会被自动回收。

如果使用重定向来调用目标action,就不能使用request令牌了。因为request对象在重定向后会被重新创建。可以使用如下方法:

l 读action mapping 的名称。这个只在你定义了严格的调用顺序规则后才有用。如果struts-config.xml变了,则你也需要跟着改变。

l 在session或者更高的范围内存放一个令牌,但要确保链中的最后一个action结束后要除掉这个令牌。

l 在返回对象的URI上附加一个令牌。在重定向结束后会作为一个HTTP参数传递给目标action。这种方法需要做一些额外工作,但是值得一试。

重要:为了可预见的行为,在所有的action中使用相同的范围。



6.   Two actions, two forms
我们已经有了两个action,为什么不能拥有两个不同的form呢。

 

Java代码 复制代码
  1. <action path  = "/inputAction"  
  2.           type  = "com.acme.struts.Action1"  
  3.           name  = "inputForm"  
  4.           input = "/WEB-INF/jsp/error1.jsp">   
  5.           <forward   path="/outputAction.do" redirect="true"/>   
  6.   </action>  
  <action path  = "/inputAction"
            type  = "com.acme.struts.Action1"
            name  = "inputForm"
            input = "/WEB-INF/jsp/error1.jsp">
            <forward   path="/outputAction.do" redirect="true"/>
    </action>



   

Java代码 复制代码
  1. <action path  = "/outputAction"  
  2.             type  = "com.acme.struts.Action2"  
  3.             name  = "outputForm"  
  4.             input = "/WEB-INF/jsp/error2.jsp">   
  5.             <forward   path="/WEB-INF/jsp/viewTarget.jsp"/>   
  6.     </action>  
<action path  = "/outputAction"
            type  = "com.acme.struts.Action2"
            name  = "outputForm"
            input = "/WEB-INF/jsp/error2.jsp">
            <forward   path="/WEB-INF/jsp/viewTarget.jsp"/>
    </action>




6.1. 结论和使用提示
这个调用顺序和以前并没有什么不同,但是由于现在我们有了不同的form bean 和相应的实例,我们可以使编码更清晰。

这种设计可以用来处理web应用的输入和输出。源action接受请求,源form bean 验证输入数据。如果输入合法,则控制被重定向到输出action。Struts会重新给form bean的字段赋值,但是这里有个技巧:可以为字段定义不同的名称,或者更好一些,对输出form bean的字段只读,Struts使用accessors 和mutators去操纵form bean的字段,所以如果没有mutators就不能修改了。

由于是利用持久数据手工填写了输出form,所以就不需要保存输入form的值了。因此,就不需要转发,而是使用了重定向。这样,源action和目标action就解耦了。

这种方式的一个非常好的副作用是输出页面可以重新加载而不用重新运行输入action,避免了重复提交输入数据。

分享到:
评论

相关推荐

    struts的教程.doc

    Struts Action Mapping 9 使用ActionForward导航 10 Struts ActionForm Bean捕获表单数据 11 Struts的其他组件 12 Validation Framework for Struts 12 Struts TagLib 12 BeanUtils 12 Collections 13 ...

    Struts框架之构建Controller组件.rar

    Struts的Dispatcher Servlet(也称为Front Controller)是请求处理的核心,它负责拦截所有到达应用程序的请求,根据Action Mapping转发到对应的Action。 7. **Forward和Redirect**: 在Action执行完成后,可以...

    去掉.action去掉.do字样 隐藏struts2 URL地址action, strus1的扩展名do也是同理.zip

    Struts2和Struts1是两个非常著名的Java Web框架,它们在处理请求时通常会在URL中显式地显示.action或.do后缀。然而,为了提供更友好的用户体验和增强安全性,有时我们需要隐藏这些扩展名。本篇文章将详细介绍如何在...

    Struts-Action核心代码

    1. **初始化配置**:在Servlet容器启动时,ActionServlet会加载并解析`struts-config.xml`配置文件,获取所有Action配置信息,包括Action的映射、Form Bean定义、数据源等。 2. **请求分发**:当接收到HTTP请求时,...

    struts各种配置

    - **拦截器**:通过`&lt;servlet&gt;`和`&lt;servlet-mapping&gt;`元素定义拦截规则,将所有的请求转发到Struts的`ActionServlet`。 - **加载配置文件**:使用`&lt;init-param&gt;`元素指定`struts-config.xml`的位置。 - **配置多个...

    Struts中ActionError学习

    Struts是Java Web开发中的一款经典MVC框架,它的核心组件包括Action、ActionForm、Dispatcher Servlet(Controller)以及视图技术。在这个“Struts中ActionError学习”的主题中,我们将深入探讨ActionError这一机制...

    struts in action 源码

    在struts-config.xml中,Action Mapping定义了URL与Action类之间的关系。每个映射包括一个请求路径、对应的Action类和可能的结果(forward或redirect)。 **Tiles框架集成** Struts常与Tiles框架结合使用,使得...

    Struts in Action(Chinese)

    2. **配置文件**:Struts框架的配置文件主要包括struts-config.xml,用于定义Action、Form Bean、Action Mapping等,以及web.xml,用来配置Struts的初始化参数。 3. **Action类**:Action类是处理用户请求的核心,...

    struts中dispatchAction用法

    public ActionForward method1(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 处理方法1的业务逻辑 return mapping.findForward(...

    StrutsInAction.rar_Struts in Action_StrutsinAction_action _java

    1. **配置文件**:如struts-config.xml,它是Struts的核心配置文件,用于定义Action、Form Bean、Action Mapping等组件。 2. **Action类**:每个Action类对应一个用户请求,负责处理请求并调用服务层方法。 3. **...

    Struts 1 学习资料

    `mapping.getName()`返回Action的name属性,`mapping.getPath()`获取Action的路径,`mapping.getType()`则用于反射获取Action类的全限定名。`mapping.findForwards()`可以获取所有`&lt;forward&gt;`标签的name,而`mapping...

    关于action 不能用forward的问题

    在探讨“关于action不能用forward的问题”这一主题时,我们主要关注的是在Struts2框架中如何正确地使用forward机制来实现页面跳转,并解决在实际应用过程中遇到的相关问题。 ### Struts2框架简介 Struts2是基于MVC...

    struts教程1-Action与Struts导航

    Struts是Java Web开发中的一个开源框架,它主要用于构建基于MVC(Model-View-Controller)模式的应用程序。本教程将深入讲解Struts的核心组件——Action及其在Struts导航中的应用。 **一、Action类** 在Struts中,...

    struts调用流程总结,适用于初学者.

    Struts是一个经典的MVC(Model-View-Controller)框架,专为Java开发人员设计,用于构建Web应用程序。本文主要概述了Struts的工作流程,尤其针对初学者,旨在帮助理解其核心组件及其相互作用。 1. **ActionServlet*...

    Struts In Action by fx2002

    接着,书里会详细讲解配置文件struts-config.xml的作用,这是Struts框架的核心配置文件,定义了Action Mapping、Form Beans、DataSources等关键元素。学习如何编写和理解这个配置文件是掌握Struts的关键步骤。 书中...

    Struts1小demo

    2. **配置文件**:Struts1的核心配置文件是struts-config.xml,它定义了Action、Form Bean、ActionMapping、Forward等元素,描述了请求如何映射到特定的Action,以及Action执行后跳转的页面。 3. **Action**:...

    struts2工作原理图

    4. **Preparation Phase**:在找到Action Mapping后,Struts2会进行预处理,包括填充Action实例的属性(如果请求参数与Action属性匹配),以及执行拦截器(Interceptor)。拦截器是Struts2的一个强大特性,允许在...

    Struts1和Struts2的区别和对比

    最后,在Action执行的控制上,Struts1使用基于配置的Action Mapping,而Struts2引入了拦截器(Interceptor)的概念,通过拦截器链来控制Action的执行流程,提供了更高的灵活性和可扩展性。 综上所述,Struts2在设计...

    菜鸟学struts1必备 API

    1. Controller:在Struts1中,Controller由StrutsServlet和ActionServlet实现,它们负责解析HTTP请求,根据Action Mapping找到对应的Action执行。 2. Model:模型层通常包含业务逻辑和服务接口,Action通过调用...

    Struts1的开发过程

    3. 配置`struts-config.xml`:这是Struts的核心配置文件,用于定义Action、Form Bean、Action Mapping等。一个简单的配置示例如下: ```xml &lt;!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD ...

Global site tag (gtag.js) - Google Analytics