`

《研磨struts2》 第六章 拦截器 之 6.2 预定义的拦截器

阅读更多

6.2  预定义的拦截器

6.2.1  预定义的拦截器

一起来看看Struts2中已经定义好的预定义拦截器。Struts2的预定义拦截器都定义在struts-default.xml文件的struts-default包内,定义如下:

 

java代码:
  1. <interceptors>  
  2.             <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>  
  3.             <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>  
  4.             <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>  
  5.             <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>  
  6.             <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>  
  7.             <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />  
  8.             <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />  
  9.             <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />  
  10.             <interceptor name="externalRef" class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>  
  11.             <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>  
  12.             <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>  
  13.             <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>  
  14.             <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>  
  15.             <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>  
  16.             <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>  
  17.             <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>  
  18.             <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>  
  19.             <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>  
  20.             <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>  
  21.             <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>  
  22.             <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>  
  23.             <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>  
  24.             <interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>  
  25.             <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>  
  26.             <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>  
  27.             <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>  
  28.             <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>  
  29.             <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>  
  30.             <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />  
  31.             <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />  
  32.             <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />  
  33.             <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />  
  34.             <interceptor name="jsonValidation" class="org.apache.struts2.interceptor.validation.JSONValidationInterceptor" />  
  35.             <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />  
  36.             <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />  
  37. </interceptors>  

由于很多拦截器都是与具体的功能相关联的的,因此这里不去介绍所有的预定义拦截器,只介绍几个常用的,其他的在以后的章节里碰到了再说。

1params拦截器

这个拦截器是必不可少的,因为就是由它偷偷的把请求参数设置到相应的Action的属性去的,并自动进行类型转换。

2staticParams拦截器

将struts.xml配置文件里定义的Action参数,设置到对应的Action实例中,Action参数使用<param>标签,是<action>标签的子元素。

struts.xml的示例如下:

 

java代码:
  1. <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">  
  2.             <param name="account">test</param>  
  3. </action>  

这要求Action中一定要有一个account的属性,并有相应的getter/setter方法。运行的时候,Action的account属性在初始化过后,会接到这里的赋值“test”。

       注意:params拦截器和staticParams拦截器都会为Action的属性赋值,如果碰到了都要赋同一个值呢,比如request里面有account参数,而struts.xml中也有account参数,最终的值是谁?

       其实是Action初始化过后,就会把struts.xml中配置的数据设置到Action实例中相应的属性上去。然后,把用户请求的数据设置到Action实例中相应的属性上去。

       很明显最后的值是用户请求中account的数据。

3prepare拦截器

在Action执行之前调用Action的prepare()方法,这个方法是用来准备Action执行之前要做的工作。它要求我们的Action必需实现com.opensymphony.xwork2.Preparable接口

4modelDriven拦截器

如果Action实现ModelDriven接口,它将getModel()取得的模型对象存入OgnlValueStack中。

5chain拦截器

将前一个执行结束的Action属性设置到当前的Action中。它被用在ResultType为“chain”所指定的结果的Action中,该结果Action对象会从值栈中获得前一个Action对应的属性,它实现Action链之间的数据传递。

6execption拦截器

顾名思义,在抛出异常的时候,这个拦截器起作用。它是我们第五章讲的Struts2的错误处理机制(<exception-mapping>)的基础,任何应用都应该引用这个拦截器,而且引用的时候,最好把它放在第一位,让它能捕获所有的异常。

7validation拦截器

调用验证框架读取 *-validation.xml文件,并且应用在这些文件中声明的校验。

8token拦截器

核对当前Action请求(request)的有效标识,防止重复提交Action请求 。使用标签<s:token>可以生成表单令牌,该标签会在session中设置一个预期的值并且在表单中创建一个隐藏的input字段。Token拦截器会检查这个令牌,如果不合法,将不会执行action,注意这个拦截器需要手工添加,还需要配置一个invalid.token的result。

9tokenSession拦截器

扩展了token拦截器的功能,当提交无效的Action请求标识时,它会跳转回到第一次成功后的页面。

10conversionError拦截器

用来处理框架进行类型转化(Type Conversion)时的出错信息。它将存储在ActionContext中的类型转化(Type Conversion)错误信息转化成相应的Action字段的错误信息,保存在堆栈中。根据需要,可以将这些错误信息在视图中显示出来

11fileUpload拦截器

用来处理文件上传

12workflow拦截器

Action默认的工作流,如果action实现了Validateable接口,那么interceptor会调用action的validate()方法;如果action实现了ValidationAware接口,那么interceptor将会检查action是否包含错误信息。如果包含任何错误信息,那么interceptor将会返回input,而不让action执行。

13servletConfig拦截器

这个拦截器提供Action直接对Servlet API的访问,把Servlet API的对象注入到Action中。包括:ServletRequestAware、ServletResponseAware、ParameterAware、SessionAware、ApplicationAware。

14timer拦截器

记录ActionInvocation余下部分执行的时间,并做为日志信息记录下来,便于寻找性能瓶颈。

15logger拦截器

在日志信息中输出要执行的Action信息 ,这样,在调试的时候,就能很快的定位到这个对应的Action了。

先看这么多,其他的预定义拦截器,随着后面的学习再慢慢的展开。

6.2.2  预定义的拦截器栈

在了解了Struts2中预定义的拦截器之后,来看看拦截器栈。

       先回顾一下在前面的所有示例,在struts.xml中进行配置的时候,是否有看到任何关于拦截器(interceptor)的身影呢?

       答案很明显,是没有看到。也就是说,前面做了这么多示例,既没有声明拦截器,也没有引用拦截器,但是前面又说我们已经使用拦截器了,这到底是怎么回事呢?

       其实是因为Struts2有默认的拦截器配置,也就是说,虽然我们没有主动去配置任何关于拦截器的东西,但是Struts2会使用默认引用的拦截器。

由于Struts2的默认拦截器声明和引用都在这个Struts-default.xml里面,因此我们需要到这个文件的struts-default包里去看一下。找到struts-default.xml这个文件中的struts-default包,只留下其中关于拦截器的部分,定义如下:

 

java代码:
  1. <package name="struts-default" abstract="true">  
  2.        <interceptors>  
  3.             ……就是前面看到的预定义的拦截器部分,这里就省略了  
  4.             ……接下来有很多拦截器栈的定义,这里就省略了,看看下面缺省的拦截器栈的定义  
  5.             <!--接下来是defaultStack拦截器栈的定义-->  
  6.             <interceptor-stack name="defaultStack">  
  7.                 <interceptor-ref name="exception"/>  
  8.                 <interceptor-ref name="alias"/>  
  9.                 <interceptor-ref name="servletConfig"/>  
  10.                 <interceptor-ref name="i18n"/>  
  11.                 <interceptor-ref name="prepare"/>  
  12.                 <interceptor-ref name="chain"/>  
  13.                 <interceptor-ref name="debugging"/>  
  14.                 <interceptor-ref name="scopedModelDriven"/>  
  15.                 <interceptor-ref name="modelDriven"/>  
  16.                 <interceptor-ref name="fileUpload"/>  
  17.                 <interceptor-ref name="checkbox"/>  
  18.                 <interceptor-ref name="multiselect"/>  
  19.                 <interceptor-ref name="staticParams"/>  
  20.                 <interceptor-ref name="actionMappingParams"/>  
  21.                 <interceptor-ref name="params">  
  22.                   <param name="excludeParams">dojo\..*,^struts\..*</param>  
  23.                 </interceptor-ref>  
  24.                 <interceptor-ref name="conversionError"/>  
  25.                 <interceptor-ref name="validation">  
  26.                     <param name="excludeMethods">input,back,cancel,browse</param>  
  27.                 </interceptor-ref>  
  28.                 <interceptor-ref name="workflow">  
  29.                     <param name="excludeMethods">input,back,cancel,browse</param>  
  30.                 </interceptor-ref>  
  31.             </interceptor-stack>  
  32.        </interceptors>  
  33.   
  34.         <default-interceptor-ref name="defaultStack"/>  
  35.     </package>  

由于篇幅问题,并没有罗列出所有的拦截器栈。但是上面的部分就已经把要观察的问题都列举出来了。

       仔细观察,上面的配置可以分为三个部分。

  • <interceptor>
  • <interceptor-stack>
  • <default-interceptor-ref>

         那么,到底谁是声明,谁是引用呢?

1首先,<interceptor>元素用来定义一个拦截器,这里仅仅是一个定义,还没有任何一个Action来引用它。里面的name属性作为唯一标志,而class属性就是这个拦截器的实现类。拦截器的实现类都应该是com.opensymphony.xwork2.interceptor.Interceptor这个接口的实现类。

    2其次,<interceptor-stack>定义了一个拦截器栈,这个栈中可以引用其他已经定义好的拦截器。拦截器栈简化了动作类Action在引用拦截器时的操作。

因为大多数动作类Action在引用拦截器的时候都不会仅仅引用一个拦截器,而是引用一组拦截器,而多个动作类Action大概又会引用同一组拦截器,这时候,为了引用的方便,可以把多个拦截器组合成一个拦截器栈。Action在引用的时候,只需要引用这个拦截器栈就可以了,而不是引用每一个拦截器。如下图所示:

图6.2 拦截器栈原理图

上图的左半部分,描述了没有拦截器栈的情况,每个Action都需要配置自己要的拦截器,这里面有很多是重复的劳动,比如Action1需要拦截器1和2,Action2也需要拦截器1和2,在没有拦截器栈的情况下,他们必须分别配置,重复劳动。

       上图的右半部分,描述了有拦截器栈的情况,可以把Action1和Action2公共需要的拦截器组合成一个拦截器栈,在Action配置的时候,只需要引用这个拦截器栈就可以了,而不需要一个一个罗列里面的拦截器。

注意:<interceptor-ref>里面的name 属性,不仅仅可以写一个已经定义好的拦截器,还可以写一个已经定义好的拦截器栈。

6.2.3  预定义拦截器的配置使用

在了解到Struts2里面有那么多的预定义拦截器之后,究竟如何来使用这些拦截器呢?有两种方式:

1:在struts.xml的Action配置里面,引用需要使用的拦截器。

先看一下struts-2.1.dtd对于<action>元素的定义:

 

java代码:
  1. <!ELEMENT action (param|result|interceptor-ref|exception-mapping)*>  

action元素后面出现的interceptor-ref子元素后面用*来修饰,这说明一个action元素可以有不限个数的interceptor-ref子元素。

那么在<action>元素中,如何使用<interceptor-ref>子元素呢?其实很简单,只需要在<action>元素中,配置需要的<interceptor-ref>子元素就可以了,<interceptor-ref>子元素里面配置需要使用的拦截器的名称,比如:

 

java代码:
  1. <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">  
  2.             <param name="account">test</param>  
  3.          <result>/s2impl/welcome.jsp</result>  
  4.          <interceptor-ref name="staticParams"/>  
  5.          <interceptor-ref name="basicStack"/>  
  6. </action>  

<interceptor-ref>子元素中的name,不仅仅可以是一个已经定义好的拦截器的名称,还可以是一个已经定义好的拦截器栈的名称。上面的示例,就引用了一个拦截器和一个拦截器栈。

2:在包上声明包内所有的Action都使用的拦截器

先看一下struts-2.1.dtd对于<package>元素的定义:

 

java代码:
  1. <!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>  

package元素后面出现的default-interceptor-ref子元素后面用“?”来修饰,这说明一个package元素只能有0个或1个default-interceptor-ref子元素。

其实,在配置自己的package的时候所扩展的struts-default包里面,就已经定义了一个<default-interceptor-ref>,在Struts-default.xml中定义的struts-default包内,有如下定义:

 

java代码:
  1. <default-interceptor-ref name="defaultStack"/>  

正是因为有这个定义,前面的示例中,我们都没有主动去配置拦截器,但实际上,是有拦截器在运行并执行很重要的工作,只不过是使用的默认的拦截器,我们不知道罢了。

当然现在就知道了,如果我们没有去配置拦截器,默认就会运行名称为“defaultStack”的拦截器栈里面定义的那些拦截器。可能有朋友会问,到底有哪些拦截器,看看上面的预定义拦截器,或者到Struts-default.xml中定义的struts-default包内去查看,里面都有。

6.2.4  拦截器的调用顺序

在学习了预定义拦截器的配置使用之后,接下来看看<action>元素引用拦截器的调用顺序。在拿到一个动作类的声明<action>元素后,如何找到它引用的拦截器呢?

       1:首先,要找它自己有没有声明拦截器的引用,即<action>元素有没有<interceptor-ref>子元素,如果有,则不用继续再找,直接使用这些拦截器,如果没有,下一步。

2:其次,找这个<action>所在的包有没有声明默认的拦截器引用,即<package>元素的<default-interceptor-ref>子元素, 如果有,则不用继续再找,直接使用这些拦截器,如果没有,下一步。

       3:最后,递归地寻找这个包的父包有没有声明默认的拦截器引用,直到找到有拦截器引用就为止。

       特别注意:这三个地方的定义是覆盖的关系,什么意思呢?就是如果<action>里面声明了拦截器引用,那么就以它的为准,其他的定义就无效了。也即是<action>里面的拦截器引用声明会覆盖<package>里面的缺省拦截器声明,而<package>里面的缺省拦截器声明又会覆盖父包的<package>里面的缺省拦截器声明,以此类推。

举个例子来说,如果你先有一个Action的配置如下:

 

java代码:
  1. <package name="helloworld"  extends="struts-default">  
  2.         <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">  
  3.             <param name="account">test</param>  
  4.             <result>/s2impl/welcome.jsp</result>  
  5.         </action>  
  6. </package>  

这个配置下,helloworldAction是有拦截器的,它自己没有声明拦截器引用,它所在的包也没有声明默认的拦截器引用,但是它的父包,也就是struts-default包里面声明了默认的拦截器引用,也就是前面看到的“defaultStack”,因此helloworldAction是有拦截器的,就是在“defaultStack”引用的所有拦截器。

如果这个时候,你在Action的配置里面添加了一个拦截器的引用,配置如下:

 

java代码:
  1. <package name="helloworld"  extends="struts-default">  
  2.         <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">  
  3.             <param name="account">test</param>  
  4.             <result>/s2impl/welcome.jsp</result>  
  5.             <interceptor-ref name="staticParams"/>  
  6.         </action>  
  7.     </package>  

这个配置下,helloworldAction也是有拦截器的,但是它只有一个拦截器,那就是“staticParams”。也就是说,helloworldAction配置里面有拦截器的引用,那么它将覆盖掉包或者父包里面定义的缺省引用。

也正是因为拦截器的配置是这种“覆盖”的关系,所以在<action>中配置拦截器的引用的时候,为了具有缺省的拦截器的引用,通常的做法是在后面加上对“defaultStack”的引用,示例如下:

 

java代码:
  1. <package name="helloworld"  extends="struts-default">  
  2.         <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">  
  3.             <param name="account">test</param>  
  4.             <result>/s2impl/welcome.jsp</result>  
  5.             <interceptor-ref name="staticParams"/>  
  6.             <interceptor-ref name="defaultStack"/>  
  7.         </action>  
  8.     </package>  

6.2.5  实践一下

       已经学了不少预定义拦截器的知识了,来小小地综合运用一下。假如有如下的struts.xml,示例如下:

 

java代码:
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.0.dtd">  
  5.   
  6. <struts>  
  7.     <constant name="struts.devMode" value="true" />  
  8.     <constant name="struts.locale" value="zh_CN"/>  
  9.     <constant name="struts.i18n.encoding" value="gb2312"/>  
  10.   
  11.     <package name="helloworld"  extends="struts-default">  
  12.         <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">  
  13.             <result name="toWelcome">/s2impl/welcome.jsp</result>  
  14.         </action>  
  15.     </package>  
  16. </struts>  

因为需要使用到struts-default.xml,因此简单的回顾一下,struts-default.xml配置示意如下:

 

java代码:
  1. <package name="struts-default" abstract="true">  
  2.     ...  
  3. <interceptors>  
  4. <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>  
  5. <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>  
  6. <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>  
  7. <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />  
  8. <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>  
  9. <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>  
  10. <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>  
  11. <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>  
  12. <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>  
  13.         …  
  14. <interceptor-stack name="defaultStack">  
  15. <interceptor-ref name="exception"/>  
  16. <interceptor-ref name="alias"/>  
  17. <interceptor-ref name="servletConfig"/>  
  18. <interceptor-ref name="i18n"/>  
  19. <interceptor-ref name="prepare"/>  
  20. <interceptor-ref name="chain"/>  
  21. <interceptor-ref name="debugging"/>  
  22. <interceptor-ref name="scopedModelDriven"/>  
  23. <interceptor-ref name="modelDriven"/>  
  24. <interceptor-ref name="fileUpload"/>  
  25. <interceptor-ref name="checkbox"/>  
  26. <interceptor-ref name="multiselect"/>  
  27. <interceptor-ref name="staticParams"/>  
  28. <interceptor-ref name="actionMappingParams"/>  
  29. <interceptor-ref name="params">  
  30. <param name="excludeParams">dojo\..*,^struts\..*</param>  
  31. </interceptor-ref>  
  32. <interceptor-ref name="conversionError"/>  
  33. <interceptor-ref name="validation">  
  34. <param name="excludeMethods">input,back,cancel,browse</param>  
  35. </interceptor-ref>  
  36. <interceptor-ref name="workflow">  
  37. <param name="excludeMethods">input,back,cancel,browse</param>  
  38. </interceptor-ref>  
  39. </interceptor-stack>  
  40. </interceptors>  
  41.   
  42. <default-interceptor-ref name="defaultStack"/>  
  43.     ...  
  44. </package>  

1:请问:helloworldAction引用了timer这个拦截器了吗?

       可以在struts-default.xml里面看到,在<interceptor>的声明中,有一个名为timer的拦截器:<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>

       但是怎么判断helloworldAction是否引用了timer呢?很简单,按照前面讲述的拦截器的调用顺序:

(1)先来看看这个<action>里面有没有声明拦截器引用?

       很明显没有,这个<action>元素没有<interceptor-ref>子元素,那就下一步。

(2)再看看这个包有没有声明默认的拦截器引用?

答案也很明显,是没有,这个<package>元素没有<defult-interceptor-ref>元素。

(3)接着看这个包的父包有没有声明默认的拦截器引用?

这个包的父包是struts-default,前面已经讲过,struts-default包里面有缺省的拦截器引用,它引用了“defaultStack”这个拦截器栈。

好了,找到一个了,那就停止寻找,helloworldAction会使用这个“defaultStack”拦截器栈里面所引用的所有拦截器。

(4)接下来,就来看看“defaultStack”拦截器栈里面是否引用了“timer”拦截器?

       仔细查看上面给出的struts-default.xml的定义,很明显,在“defaultStack”拦截器栈里面并没有引用名称为“timer”的拦截器。

(5)注意,这个时候还没完,因为< interceptor-ref>元素中的name属性不仅仅可以写一个拦截器的名字,还可以出现一个更小的拦截器栈的名字,还需要一一检查,出现的各个<interceptor-ref >是否引用了一个更小的拦截器栈,而这个更小的拦截器栈又是否引用了timer拦截器?

经过仔细排查,最终也没有发现有引用timer拦截器的拦截器栈。

(6)结论:折腾了这么一大圈,终于可以说helloworldAction没有引用timer拦截器了。

2:如何让helloworldAction引用timer拦截器呢?

timer拦截器是struts2的预定义拦截器之一,可以用来记录Action运行的时间。根据前面的示例,可以看到,默认的情况下是没有引用timer的。

如果现在想要引用timer拦截起来输出Action运行的时间,简单的使用示例如下。

(1)修改<action>元素的定义,添加上对timer拦截器的引用,别忘了同时添加上对缺省拦截器栈的引用,示例配置如下:

 

java代码:
  1. <package name="helloworld"  extends="struts-default">  
  2.         <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">  
  3.             <result name="toWelcome">/s2impl/welcome.jsp</result>  
  4.             <interceptor-ref name="timer"/>  
  5.             <interceptor-ref name="defaultStack"/>  
  6.         </action>  
  7. </package>  

(2)Action就用最简单的写法,示例如下:

 

java代码:
  1. public class HelloWorldAction extends ActionSupport {  
  2.     private String account;  
  3.     private String password;  
  4.     private String submitFlag;  
  5.       
  6.     public String execute() throws Exception {  
  7.         this.businessExecute();  
  8.         return "toWelcome";  
  9.     }  
  10.     public void businessExecute(){  
  11.         System.out.println("用户输入的参数为==="+"account="+account+",password="+password+",submitFlag="+submitFlag);  
  12.     }  
  13.     //属性对应的getter/setter方法,省略了  
  14. }  

(3)登录页面没有改变,去访问登录页面,填入用户名和密码,然后点击登录按钮,观察后台,可以看到其输出结果,示例如下:

 

java代码:
  1. 用户输入的参数为===account=test,password=test,submitFlag=login  
  2. 2010-10-25 22:11:20 com.opensymphony.xwork2.util.logging.jdk.JdkLogger info  
  3. 信息: Executed action [//helloworldAction!execute] took 151 ms.  

其中,加粗的部分就是添加上timer拦截器之后,所输出的结果。通过这个结果可以看出执行helloworldAction的execute方法,共耗费151毫秒。

       注意:不同的机器运行的结果可能是不同的。

(4)这个示例的意义,通过示例实际使用timer拦截器,来学习如何使用预定义的拦截器,也就是说其他的预定义拦截器的使用方式,和这个示例使用timer拦截器的方式大同小异。

3:同包的其他Action也想要引用timer拦截器,该怎么办呢?

       现在需求变化了,不仅仅是helloworldAction需要引用timer拦截器了,同一个包内的其他Action也要引用timer拦截器。

       一个办法就是沿用老办法,让其他Action也跟helloworldAction一样,同时引用timer拦截器和defaultStack拦截器栈。

但是,这种做法不够好,有些重复劳动。简便的做法是,我们自行定义一个拦截器栈,在这个拦截器栈里面引用timer和缺省的拦截器栈,然后在包上指定默认的拦截器引用,而包下所有的Action都直接使用这个默认的引用就好了。接下来示例一下。

(1)先增加一个Action,示例代码如下:

 

java代码:
  1. package cn.javass.action.action;  
  2. import com.opensymphony.xwork2.ActionContext;  
  3. public class SecondAction extends ActionSupport {  
  4.     public String execute() throws Exception {  
  5.         System.out.println("现在SecondAction进行处理");  
  6.         return "toWelcome";  
  7.     }  
  8. }  

(2)然后修改struts.xml,添加一个自定义的拦截器栈,并指定包默认的拦截器引用就是这个拦截器栈,然后单独的Action就不用再引用拦截器了,示例配置如下:

 

java代码:
  1. <package name="helloworld"  extends="struts-default">  
  2.         <interceptors>  
  3.             <interceptor-stack name="myStack">  
  4.                 <interceptor-ref name="timer"/>  
  5.                 <interceptor-ref name="defaultStack"/>  
  6.             </interceptor-stack>  
  7.         </interceptors>  
  8.         <default-interceptor-ref name="myStack"/>  
  9.           
  10.         <action name="helloworldAction" class="cn.javass.action.action.HelloWorldAction">  
  11.             <result name="toWelcome">/s2impl/welcome.jsp</result>  
  12.         </action>  
  13.         <action name="secondAction" class="cn.javass.action.action.SecondAction">  
  14.             <result name="toWelcome">/s2impl/welcome.jsp</result>  
  15.         </action>  
  16.     </package>  

上面的配置做了三件事:

  • 定义了一个新的拦截器栈,在这个拦截器栈中,先引用timer拦截器,再引用defaultStack拦截器栈,如下:
    java代码:
    1. <interceptors>  
    2. <interceptor-stack name="myStack">  
    3. <interceptor-ref name="timer"/>  
    4. <interceptor-ref name="defaultStack"/>  
    5. </interceptor-stack>  
    6. </interceptors>  

  • java代码:
    1. <default-interceptor-ref name="myStack"/>  
    在包上定义默认的拦截器引用为这个新定义的拦截器栈,如下:

       自己去运行测试一下,看看效果。

私塾在线网站原创《研磨struts2》系列

转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4058.html

欢迎访问http://sishuok.com获取更多内容

分享到:
评论
1 楼 jidu01 2013-10-15  
配置timer的控制台信息输出,需要配置log4j

相关推荐

    研磨Struts2配书视频对应的演示源代码

    2. **拦截器(Interceptors)**:Struts2的核心之一是其拦截器机制,它们在Action执行前后执行一系列预定义或自定义的操作。这些拦截器可以用于登录验证、日志记录、性能监控等。源代码中可能包含了不同类型的拦截器...

    研磨Struts2

    - **配置文件(struts.xml)**:定义了应用程序的行为,包括Action映射、拦截器配置等。 - **结果(Result)**:定义了Action执行完毕后的结果,如重定向、转发等。 - **值栈(ValueStack)**:用来存储Action、...

    研磨Struts2配书视频对应的PPT

    Struts2框架的拦截器是其一大特色,它允许开发者定义一系列预定义或自定义的行为,这些行为在请求被处理前和后执行。例如,登录验证、日志记录、性能监控等都可以通过拦截器实现。通过灵活的拦截器链,开发者可以...

    《研磨Struts 2》PDF版本下载.txt

    相比于第一代Struts框架,Struts 2提供了更多的功能,如拦截器、动态方法调用、更强大的表单处理机制等,并且它与Spring和Hibernate等其他Java EE技术栈的集成更加紧密。 ### Struts 2的特点 1. **强大的表单处理...

    研磨struts2 高清版

    由于文件较大,我把这个文档切割为2部分,这是第一部分,请下载完第一部分后一定要下载第二部分,否则不能阅读。

    研磨struts

    11. **Interceptor**:拦截器是Struts2中的另一个重要特性,它们在Action执行前后插入,提供了日志、权限检查、事务控制等功能。拦截器链可以根据需要定制,提高了代码的复用性和可扩展性。 12. **其他重要知识**:...

    研磨Struts2 高清完整版.part2

    研磨Struts2 高清完整版,请和第一部分一起下载啊

    研磨Struts2_12859679_高清完整版.part2.rar

    研磨Struts2_12859679_高清完整版

    研磨Struts2-高清-完整目录-2011年10月

    研磨Struts2-高清-完整目录-2011年10月,分享给所有需要的人

    研磨设计模式(完整带书签).part2.pdf

    第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11章 代理模式(Proxy) 第12章 ...

    研磨设计模式-part2

    第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11章 代理模式(Proxy) 第12章 ...

    研磨设计模式(完整带书签).part1.pdf

    第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11章 代理模式(Proxy) 第12章 ...

    研磨设计模式.part2(共4个)

    第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11章 代理模式(Proxy) ...

    研磨设计模式-part4

    第6章 工厂方法模式(Factory Method) 第7章 抽象工厂模式(Abstract Factory) 第8章 生成器模式(Builder) 第9章 原型模式(Prototype) 第10章 中介者模式(Mediator) 第11章 代理模式(Proxy) 第12章 ...

Global site tag (gtag.js) - Google Analytics