@MrXiao
2017-12-21T08:08:43.000000Z
字数 4295
阅读 1140
Struts2
struts2中很多的核心功能都是拦截器完成的。比如:params(封装动态参数)、staticParams(静态参数封装)、i18n(国际化)、modelDrivern(模型驱动)、servletConfig(注入servletAPI)等。
作用:在执行动作前或后进行拦截
<default-interceptor-ref name="defaultStack"/>
<interceptor-stack name="defaultStack"><interceptor-ref name="exception"/><interceptor-ref name="alias"/><interceptor-ref name="servletConfig"/><interceptor-ref name="i18n"/><interceptor-ref name="prepare"/><interceptor-ref name="chain"/><interceptor-ref name="scopedModelDriven"/><interceptor-ref name="modelDriven"/><interceptor-ref name="fileUpload"/><interceptor-ref name="checkbox"/><interceptor-ref name="datetime"/><interceptor-ref name="multiselect"/><interceptor-ref name="staticParams"/><interceptor-ref name="actionMappingParams"/><interceptor-ref name="params"/><interceptor-ref name="conversionError"/><interceptor-ref name="validation"><param name="excludeMethods">input,back,cancel,browse</param></interceptor-ref><interceptor-ref name="workflow"><param name="excludeMethods">input,back,cancel,browse</param></interceptor-ref><interceptor-ref name="debugging"/><interceptor-ref name="deprecation"/></interceptor-stack>

结论:
动作方法执行前:拦截器会按照顺序依次进行拦截
执行动作方法
返回结果视图
拦截器会按照原来的顺序的相反顺序再次进行拦截
执行过程中:ActionInvocation保存了需要用到的数据
熟悉拦截器的体系:所有的拦截器都直接或间接的实现了Interceptor接口

public class MyInterceptor extends AbstractInterceptor {private static final long serialVersionUID = -828084112876621948L;@Overridepublic String intercept(ActionInvocation invocation) throws Exception {System.out.println("MyInterceptor拦截前");String invoke = invocation.invoke();//放行System.out.println("MyInterceptor拦截后");return invoke;}}
在struts.xml中注册拦截器,可以针对单个action配置,也可全局配置
针对单个action配置
首先在package中声明拦截器
<interceptors><interceptor name="myInterceptor" class="com.topvision.s2sm.plantform.interceptor.MyInterceptor"></interceptor></interceptors>
然后在action中声明引用该拦截器
<action name="loginTest" class="com.topvision.s2sm.login.action.LoginAction" method="loginTest"><!--如果没有声明拦截器,默认使用struts-default.xml中的defaultStack如果声明了,则defaultStack失效--><interceptor-ref name="myInterceptor"></interceptor-ref><result>/WEB-INF/jsp/login/login.jsp</result><result name="input">/error.jsp</result></action>
但是一般不用这种,因为Struts2有这么一种机制,一旦为Action指定了拦截器,那么就不会再为这个Action执行默认拦截器了,即defaultStack这个拦截器栈中的拦截器都不会执行,也就是说,这个Action没有输入校验、没有参数注入、没有国际化、没有…,这是不行的,所以我们需要在这个元素中再引用defaultStack拦截器栈。
全局配置(常用)
创建一个拦截器栈,包含默认拦截器栈和自定义拦截器。
<package name="default" extends="struts-default"><interceptors><!-- 自定义拦截器 --><interceptor name="myInterceptor" class="com.topvision.s2sm.plantform.interceptor.MyInterceptor"></interceptor><!-- 自定义拦截器栈 --><interceptor-stack name="myStack"><interceptor-ref name="defaultStack"/><interceptor-ref name="myInterceptor"/></interceptor-stack></interceptors><!-- 指定默认拦截器 --><default-interceptor-ref name="myStack"></default-interceptor-ref>
是AbstractInterceptor的子类:
setIncludeMethods(String includeMethods):设置需要拦截的方法,多个方法用逗号分隔
setExcludeMethods(String excludeMethods):设置不需要拦截的方法,多个方法用逗号分隔
public class MethodInterDemo extends MethodFilterInterceptor{private static final long serialVersionUID = -9060068603523571867L;@Overrideprotected String doIntercept(ActionInvocation invocation) throws Exception {//拦截前操作String invoke = invocation.invoke();//拦截后操作return invoke;}}
配置xml
<package name="default" extends="struts-default"><interceptors><!-- 自定义拦截器 --><interceptor name="myInterceptor" class="com.topvision.s2sm.plantform.interceptor.MyInterceptor"></interceptor><interceptor name="methodInterceptor" class="com.topvision.s2sm.plantform.interceptor.MethodInterDemo"></interceptor><!-- 自定义拦截器栈 --><interceptor-stack name="myStack"><interceptor-ref name="defaultStack"/><interceptor-ref name="myInterceptor"/><interceptor-ref name="methodInterceptor"/></interceptor-stack></interceptors><!-- 指定默认拦截器 --><default-interceptor-ref name="myStack"></default-interceptor-ref></package>
设置指定action
<package name="login" namespace="/" extends="default"><action name="loginTest" class="com.topvision.s2sm.login.action.LoginAction" method="loginTest"><interceptor-ref name="myStack"><!-- 设置不需要methodInterDemo拦截的方法 --><param name="methodInterDemo.excludeMethods">loginTest</param><!-- 设置需要methodInterDemo拦截的方法 --><param name="methodInterDemo.includeMethods">aaa</param></interceptor-ref><result>/WEB-INF/jsp/login/login.jsp</result><result name="input">/error.jsp</result></action></package>