Struts2的基石(拦截器)

来源:互联网 发布:负责淘宝钻展投放的人 编辑:程序博客网 时间:2024/06/05 03:53

拦截器(Interceptor)是Struts2的基石,拦截器的主要作用是在Action执行之前和Result执行之后进行一些特定功能的处理机制。


如图,拦截器是用来负责在Action执行之前和Result执行之后处理一些功能的类。每个不同的拦截器,它们分别执行不同的功能处理,而运行的时机就是在Action执行之前和Result执行之后,需要注意的是在执行Action之前和Result之后,拦截器的执行顺序是正好相反的。

一、拦截器的好处

  • 1.简化Action的实现,可以把很多功能从Action中独立出来,大量减少了Action的代码书写。
  • 2.功能更单一,把功能从Action中分离出来,分散到不同的拦截器里面,这样使每个拦截器和Action的功能更加单一,便于维护。
  • 3.通用代码模块化和重用性,把Action中的功能分离出来,放到拦截器去实现,这样就能实现多个Action中通用的代码进行模块化,多个Action公用一个拦截器
  • 4.实现AOP,Struts2通过拦截器实现了AOP(面向切面编程),AOP是一种分散实现关注功能的编程模式。
  • 拦截器将通用需求功能从不相关的Action之中分离出来,能够使得很多Action共享同一个行为,一旦行为发生变化,不必修改很多Action,只要修改这个行为就可以了。
  • 二、预定义的拦截器
  • 在Struts-default.xml中,提供了很多预定义的拦截器
  • [html] view plaincopy
    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>  

几个常用的拦截器

1.params拦截器,把请求参数设置到相应的Action的属性去的,并自动进行类型转换。

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

注意:如果request里面有account参数,而struts.xml中也有account参数,Action中最终的值是谁?

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

3.prepare拦截器,在Action执行之前调用Action的prepare()方法,这个方法是用来准备Action执行之前要做的工作。它要求我们的Action必需实现com.opensymphony.xwork2.Preparable接口,一般都是与ModelDriven一起使用

4.modelDriven拦截器,如果Action实现ModelDriven接口,它将getModel()取得的模型对象存入OgnlValueStack中

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

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

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

8.timer拦截器,记录ActionInvocation余下部分执行的时间,并做为日志信息记录下来,便于查找性能优化。

预定义的拦截器栈

在struts-default.xml中给出了Struts2的默认的预定义拦截器栈defaultStack

  • [java] view plaincopy
    1. <interceptors>  
    2. <interceptor>。。。。  
    3. <interceptor-stack>。。。  
    4. <default-interceptor-ref>。。。。  
    5. </interceptors>  
    1.<interceptor>用来定义一个拦截器,仅仅是一个定义,还没有被Action来引用它。name属性作为唯一标志,而class属性就是这个拦截器的实现类的全类名。拦截器的实现类都应该是com.opensymphony.xwork2.interceptor.Interceptor这个接口的实现类
  • 2.<interceptor-stack>定义了一个拦截器栈,这个栈中可以引用其他已经定义好的拦截器。拦截器栈简化了动作类Action在引用拦截器时的操作。

    因为大多数动作类Action在引用拦截器的时候都不会仅仅引用一个拦截器,而是引用一组拦截器。Action在引用的时候,只需要引用这个拦截器栈就可以了,而不是引用每一个拦截器

    拦截器的调用顺序

  • (1).要找它自己有没有声明拦截器的引用,即<action>元素有没有<interceptor-ref>子元素,如果有,则不用继续再找,如果没有,(2)。

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

  •  (3):递归地寻找当前包的父包有没有声明默认的拦截器引用,直到找到有拦截器引用就为止

  • 注意:三者是覆盖关系


  • 三、自定义拦截器
所有的拦截器都要实现com.opensymphony.xwork2.interceptor.Interceptor接口

[java] view plaincopy
  1. public interface Interceptor {  
  2.     void destroy();  
  3.     void init();  
  4.     String intercept(ActionInvocation invocation) throws Exception;  
  5. }  
自定义登录拦截器

判断用户是否登录,如果没有返回登录页面

[java] view plaincopy
  1. public class PermissionInterceptor implements Interceptor {  
  2.   
  3.     private static final long serialVersionUID = 1L;  
  4.   
  5.     @Override  
  6.     public void destroy() {  
  7.     }  
  8.   
  9.     @Override  
  10.     public void init() {  
  11.     }  
  12.   
  13.     @Override  
  14.     public String intercept(ActionInvocation invocation) throws Exception {  
  15.   
  16.         HttpSession session = ServletActionContext.getRequest().getSession();  
  17.         Object obj = session.getAttribute("user");  
  18.         if(obj==null){  
  19.             return "login";  
  20.         }else{  
  21.             return invocation.invoke();  
  22.         }  
  23.     }  
  24.   
  25. }  

配置struts.xml文件

创建父包

[html] view plaincopy
  1. <package name="mydefault" extends="struts-default">  
  2.         <interceptors>  
  3.             <interceptor name="PermissionInterceptor" class="cn.cil.interceptor.PermissionInterceptor"></interceptor>  
  4.             <interceptor-stack name="mydefaultStack">  
  5.                 <interceptor-ref name="PermissionInterceptor"></interceptor-ref>  
  6.                 <interceptor-ref name="defaultStack"></interceptor-ref>  
  7.             </interceptor-stack>  
  8.         </interceptors>  
  9.     </package>  
有需要使用自定义的权限拦截器,就可以继承这个pacjage

[html] view plaincopy
  1. <package name="struts" namespace="/user" extends="mydefault">  
  2.       
  3.         <action name="user_*" class="cn.cil.domain.User" method="{1}">  
  4.         <interceptor-ref name="mydefaultStack"></interceptor-ref>  
  5.             <result>/listUsers.jsp </result>  
  6.             <result name="input">/{1}.jsp</result>  
  7.             <result name="login">/login.jsp</result>  
  8.         </action>  
  9.         <action name="download" class="cn.cil.domain.User" method="download">  
  10.             <interceptor-ref name="mydefaultStack"></interceptor-ref>  
  11.             <result type="stream" name="success">  
  12.                     <param name="contentType">application/octet-stream</param>  
  13.                     <param name="inputStream">inputStream</param>  
  14.                     <param name="contentDisposition">attachment;filename=${filename}</param>  
  15.             </result>  
  16.             <result name="login">/login.jsp</result>  
  17.         </action>  
  18. </package>  

向拦截器传入参数

同一个拦截器为不同的Action服务的时候,需要根据传入的参数进行处理上的变化。比如说,一个记录日志的拦截器,可以根据配置来决定到底把日志记录在数据库还是文件里面。

可以把这种配置数据作为一个参数,在配置的时候设置值,会自动传入拦截器中

[html] view plaincopy
  1. <interceptor-ref name=“myInterceptor”>  
  2.                 <param name="param">params</param>  
  3.         </interceptor-ref>  

[java] view plaincopy
  1. public class MyInterceptor implements Interceptor{  
  2.     private String param;  
  3.     public void setParam(String param) {  
  4.         this.param = param;  
  5.     }  
  6.     public void destroy() {  
  7.     }  
  8.     public void init() {  
  9.     }  
  10.     public String intercept(ActionInvocation invocation) throws Exception {  
  11.         System.out.println("接到param的参数=="+this.param);  
  12.         if("params".equalsIgnoreCase(this.param)){  
  13.             System.out.println("记录日志到数据库");  
  14.         }else{  
  15.             System.out.println("记录日志到文件");  
  16.         }  
  17.         String result = invocation.invoke();  
  18.         return result;  
  19.     }     
  20. }  
注意setter方法,在初始化这个拦截器的时候,Struts2就会反射的调用对应的setter,把在<param>元素中配置的值设置到param属性上去
0 0
原创粉丝点击