坠落凡间的struts2(5)---拦截器

工作原理

拦截器的工作原理其实就是动态代理关于动态代理请看我的另一篇博文

http://blog.csdn.net/senssic/article/details/10564311


系统定义拦截器


位于struts-default.xml文件中

处理类                     拦截器名称                  作用
Alias Interceptor alias 在不同请求之间将请求参数在不同名字件转换,请求内容不变
Chaining Interceptor chain 让前一个Action的属性可以被后一个Action访问,现在和chain类型的result()结合使用。
Checkbox Interceptor checkbox 添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox。
Cookies Interceptor cookies 使用配置的name,value来是指cookies
Conversion Error Interceptor conversionError 将错误从ActionContext中添加到Action的属性字段中。
Create Session Interceptor createSession 自动的创建HttpSession,用来为需要使用到HttpSession的拦截器服务。
Debugging Interceptor debugging 提供不同的调试用的页面来展现内部的数据状况。
Execute and Wait Interceptor execAndWait 在后台执行Action,同时将用户带到一个中间的等待页面。
Exception Interceptor exception 将异常定位到一个画面
File Upload Interceptor fileUpload 提供文件上传功能
I18n Interceptor i18n 记录用户选择的locale
Logger Interceptor logger 输出Action的名字
Message Store Interceptor store 存储或者访问实现ValidationAware接口的Action类出现的消息,错误,字段错误等。
Model Driven Interceptor model-driven 如果一个类实现了ModelDriven,将getModel得到的结果放在Value Stack中。
Scoped Model Driven scoped-model-driven 如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model调用Action的setModel方法将其放入Action内部。
Parameters Interceptor params 将请求中的参数设置到Action中去。
Prepare Interceptor prepare 如果Acton实现了Preparable,则该拦截器调用Action类的prepare方法。
Scope Interceptor scope 将Action状态存入session和application的简单方法。
Servlet Config Interceptor servletConfig 提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问。
Static Parameters Interceptor staticParams 从struts.xml文件中将中的中的内容设置到对应的Action中。
Roles Interceptor roles 确定用户是否具有JAAS指定的Role,否则不予执行。
Timer Interceptor timer 输出Action执行的时间
Token Interceptor token 通过Token来避免双击
Token Session Interceptor tokenSession 和Token Interceptor一样,不过双击的时候把请求的数据存储在Session中
Validation Interceptor validation 使用action-validation.xml文件中定义的内容校验提交的数据。
Workflow Interceptor workflow 调用Action的validate方法,一旦有错误返回,重新定位到INPUT画面
Parameter Filter Interceptor N/A 从参数列表中删除不必要的参数
Profiling Interceptor profiling 通过参数激活profile

自定义拦截器

方法
实现Interceptor接口
继承AbstractInterceptor类
拦截器:
[java]  view plain copy print ?
  1. package org.senssic.intercept;  
  2.   
  3. import com.opensymphony.xwork2.ActionInvocation;  
  4. import com.opensymphony.xwork2.interceptor.Interceptor;  
  5. import com.opensymphony.xwork2.util.logging.Logger;  
  6. import com.opensymphony.xwork2.util.logging.LoggerFactory;  
  7.   
  8. public class SIntercept implements Interceptor {  
  9.     private static final Logger LOG = LoggerFactory.getLogger(SIntercept.class);  
  10.     private static final long serialVersionUID = 1L;  
  11.     private String param;  
  12.   
  13.     @Override  
  14.     public void destroy() {  
  15.         System.out.println(param + ":大灰狼死了…………");  
  16.     }  
  17.   
  18.     @Override  
  19.     public void init() {  
  20.         System.out.println(param + ":大灰狼抓羊初始化了………………");  
  21.     }  
  22.   
  23.     @Override  
  24.     public String intercept(ActionInvocation invocation) throws Exception {  
  25.         System.out.println("我是个拦截器咿呀咿呀一,正在拦截呢…………");  
  26.         invocation.invoke();  
  27.         LOG.debug("拦截器: '" + invocation.getProxy().getNamespace() + "/"  
  28.                 + invocation.getProxy().getActionName() + "' { "new String[0]);  
  29.         return null;  
  30.     }  
  31.   
  32.     public String getParam() {  
  33.         return param;  
  34.     }  
  35.   
  36.     public void setParam(String param) {  
  37.         this.param = param;  
  38.     }  
  39.   
  40. }  

拦截的action类:
[java]  view plain copy print ?
  1. package org.senssic.action;  
  2.   
  3. import com.opensymphony.xwork2.ActionSupport;  
  4.   
  5. public class InterceptAction extends ActionSupport {  
  6.   
  7.     private static final long serialVersionUID = 1L;  
  8.     private String name;  
  9.     private int age;  
  10.   
  11.     public String getName() {  
  12.         return name;  
  13.     }  
  14.   
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18.   
  19.     public int getAge() {  
  20.         return age;  
  21.     }  
  22.   
  23.     public void setAge(int age) {  
  24.         this.age = age;  
  25.     }  
  26.   
  27.     @Override  
  28.     public String execute() {  
  29.         System.out.println("俺是拦截器action");  
  30.         return SUCCESS;  
  31.     }  
  32. }  

拦截器的配置:
[html]  view plain copy print ?
  1. <package  name="mystruts2" namespace="/" extends="struts-default">  
  2.     
  3.           <!-- 拦截器栈的配置,注:拦截器和拦截器栈的配置差不多,但是如果配置好自定义拦截器,则默认系统拦截器  
  4.                    将不起作用,所以我们需要写一个拦截器栈将默认的拦截器也包含进来。  
  5.          -->  
  6.         <interceptors>  
  7.         <interceptor name="SIntercept" class="org.senssic.intercept.SIntercept">  
  8.           <param name="param">senssic</param>  
  9.         </interceptor>  
  10.            <interceptor-stack name="mystack">  
  11.              <interceptor-ref name="defaultStack"></interceptor-ref><!--defaultStack是系统默认配置的拦截器栈位于struts-default.xml中 -->  
  12.              <interceptor-ref name="SIntercept"></interceptor-ref>  
  13.            </interceptor-stack>  
  14.         </interceptors>  
  15.        <action name="InterceptAction" class="org.senssic.action.InterceptAction">  
  16.            <interceptor-ref name="mystack"></interceptor-ref>  
  17.            <result>/page/intercept.jsp</result>  
  18.         </action>  
  19.      
  20.      </package>  

拦截成功:

方法过滤拦截器

业务类中可能存在多个业务方法,不同的业务方法需要拦截的数据不一样
通过继承MethosFilterInterceptor这一抽象类可以实现对方法的拦截
通过重写setExcludeMethod(Stirng methodName)与 setIncludeMethod(Stirng methodName)来排除或包含需要拦截的方法
如果某一方法同时出现在上面两个方法的对数中,则会被拦截
业务方法拦截器:
[java]  view plain copy print ?
  1. package org.senssic.intercept;  
  2.   
  3. import com.opensymphony.xwork2.ActionInvocation;  
  4. import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;  
  5.   
  6. public class MMIntercept extends MethodFilterInterceptor {  
  7.   
  8.     @Override  
  9.     protected String doIntercept(ActionInvocation paramActionInvocation)  
  10.             throws Exception {  
  11.         System.out.println("我是拦截方法的,就是业务方法,只要在xml中配置拦截我的方法,我就可以起作用了");  
  12.         paramActionInvocation.invoke();  
  13.         return null;  
  14.     }  
  15.   
  16. }  

拦截的业务方法action:
[java]  view plain copy print ?
  1. package org.senssic.action;  
  2.   
  3. import com.opensymphony.xwork2.ActionSupport;  
  4.   
  5. public class MMinterceptAction extends ActionSupport {  
  6.   
  7.     private static final long serialVersionUID = 1L;  
  8.     private String name;  
  9.     private int age;  
  10.   
  11.     public String getName() {  
  12.         return name;  
  13.     }  
  14.   
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18.   
  19.     public int getAge() {  
  20.         return age;  
  21.     }  
  22.   
  23.     public void setAge(int age) {  
  24.         this.age = age;  
  25.     }  
  26.   
  27.     @Override  
  28.     public String execute() {  
  29.         System.out.println("我是主业务方法");  
  30.         return SUCCESS;  
  31.     }  
  32.   
  33.     public String method() {  
  34.         System.out.println("我是业务方法一");  
  35.         return SUCCESS;  
  36.     }  
  37.   
  38.     public String methods() {  
  39.         System.out.println("我是业务方法二");  
  40.         return SUCCESS;  
  41.     }  
  42. }  

xml的配置:

[html]  view plain copy print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE struts PUBLIC  
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">  
  5. <struts>  
  6. <package name="mystruts2" namespace="/" extends="struts-default">  
  7. <!-- 拦截器栈的配置,注:拦截器和拦截器栈的配置差不多,但是如果配置好自定义拦截器,则默认系统拦截器  
  8. 将不起作用,所以我们需要写一个拦截器栈将默认的拦截器也包含进来。  
  9. -->  
  10. <interceptors>  
  11. <interceptor name="SIntercept" class="org.senssic.intercept.SIntercept">  
  12. <param name="param">senssic</param>  
  13. </interceptor>  
  14. <interceptor name="methodIntercept" class="org.senssic.intercept.MMIntercept">  
  15. <param name="includeMethods">method,method2</param>  
  16. <param name="excludeMethods">execute</param>  
  17. </interceptor>  
  18. <interceptor-stack name="mystack">  
  19. <interceptor-ref name="defaultStack"></interceptor-ref><!--defaultStack是系统默认配置的拦截器栈位于struts-default.xml中 -->  
  20. <interceptor-ref name="SIntercept"></interceptor-ref>  
  21. <interceptor-ref name="methodIntercept"></interceptor-ref>  
  22. </interceptor-stack>  
  23. </interceptors>  
  24.  <action name="MMinterceptAction" class="org.senssic.action.MMinterceptAction" method="method">  
  25.         <interceptor-ref name="mystack"></interceptor-ref>  
  26.         <result>/page/intercept.jsp</result>  
  27.      </action>  
  28.        </package>  
  29.     </struts>  

其中的

[html]  view plain copy print ?
  1. <param name="includeMethods">method,method2</param>  
  2. <param name="excludeMethods">execute</param>  
就是位于

MethodFilterInterceptor中的


如果参数名写错,则拦截所用方法

结果:


拦截器的执行顺序

一个Action存在多个拦截器
在业务方法执行前按照配置顺序执行
在业务方法执行后按相反顺序执行

拦截结果监听器---对Result的拦截


上述拦截器在处理业务后,调用了其他代码处理,使得程序可读性变差,也不能精确的控制Action执行时序
可以使用拦截结果的监听器实现对Result的精确控制—发生在Action业务方法执行后,在result执行前
监听器代码:
[java]  view plain copy print ?
  1. package org.senssic.intercept;  
  2.   
  3. import com.opensymphony.xwork2.ActionInvocation;  
  4. import com.opensymphony.xwork2.interceptor.PreResultListener;  
  5.   
  6. public class R implements PreResultListener {  
  7.   
  8.     @Override  
  9.     public void beforeResult(ActionInvocation paramActionInvocation,  
  10.             String paramString) {  
  11.         System.out.println("我在result之前工作的,使用我的拦截器拦截的更加的精准。");  
  12.   
  13.     }  
  14.   
  15. }  

拦截器代码:
[java]  view plain copy print ?
  1. package org.senssic.intercept;  
  2.   
  3.   
  4. import com.opensymphony.xwork2.ActionInvocation;  
  5. import com.opensymphony.xwork2.interceptor.Interceptor;  
  6.   
  7.   
  8. public class RIntercept implements Interceptor {  
  9.   
  10.   
  11.     @Override  
  12.     public void destroy() {  
  13.         System.out.println("result之前的拦截器被销毁了");  
  14.   
  15.   
  16.     }  
  17.   
  18.   
  19.     @Override  
  20.     public void init() {  
  21.         System.out.println("result之前的拦截器被初始化了");  
  22.   
  23.   
  24.     }  
  25.   
  26.   
  27.     @Override  
  28.     public String intercept(ActionInvocation paramActionInvocation)  
  29.             throws Exception {  
  30.         System.out.println("result之前的拦截器被调用了,此处拦截的更加细致精确。");  
  31.         paramActionInvocation.addPreResultListener(new R());//注册监听器  
  32.         paramActionInvocation.invoke();  
  33.         return null;  
  34.     }  
  35.   
  36.   
  37. }  

action代码:
[java]  view plain copy print ?
  1. package org.senssic.action;  
  2.   
  3. import com.opensymphony.xwork2.ActionSupport;  
  4.   
  5. public class RAction extends ActionSupport {  
  6.   
  7.     @Override  
  8.     public String execute() {  
  9.         System.out.println("我是execute方法");  
  10.         return SUCCESS;  
  11.     }  
  12.   
  13. }  
xml配置文件:
[java]  view plain copy print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.3.dtd">  
  5.     <struts>  
  6.        <package  name="mystruts2" namespace="/" extends="struts-default">  
  7.           <interceptors>  
  8.           <interceptor name="RIntercept" class="org.senssic.intercept.RIntercept"></interceptor>  
  9. </interceptors>  
  10.  <action name="RAction" class="org.senssic.action.RAction">  
  11.       <interceptor-ref name="RIntercept"></interceptor-ref>  
  12.       <result>/page/intercept.jsp</result>  
  13.      </action>  
  14.        </package>  
  15.     </struts>  

运行结果:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值