一,基本信息
拦截器是Struts2框架中的一个核心对象,可以动态增强Action对象的功能。在Struts2框架中,很多功能是通过拦截器实现的,例如表单的重复提交,对象类型的转换,文件的上传。
当客户端发送请求时,会被Struts2的过滤器所拦截,此时Struts2对请求持有控制权,Struts2会创建Action的代理对象,并通过一系列的拦截器对请求进行处理。最后在交给指定的Action进行处理。在这期间,拦截器对象作用于Action,Result前后,可以在Action和Result前后进行任何操作。
拦截器栈(Interceptor Stack): 将拦截器按一定的顺序联结成一条链. 在访问被拦截的方法时, Struts2 拦截器链中的拦截器就会按其之前定义的顺序被依次调用(如果采用默认的拦截器,这个顺序的设置是在struts-default.xml文件中)
二,自带与自定义的拦截器
在Struts2 API中,存在一个名称为com.opensymphony.xwork2.interceptor的包。该包的对象是Struts2内置的一些拦截器对象,它们具有不同的功能。
1.Struts2自带的拦截器;
2.Interceptor
在这些对象中,Interceptor接口是Struts2框架中定义的拦截器对象,其他的拦截器(内置的或自定义的)都直接或间接实现于此接口。
Interceptor包含了3个方法:
public interface Interceptor extends Serializable{
void destroy();
void init();
String intercept(ActionInvocation invocation) throws Exception)
}
- destroy()方法:指示拦截器的生命周期结束,在拦截器被销毁前调用,用于释放拦截器在初始化时占用的一些资源。
- init()方法:用于对拦截器进行一些初始化操作,该方法在拦截器被实例化后,intercept()执行前进行操作
- intercept()方法:用于执行Action对象中的请求处理方法,以及在Action的前后进行一些操作,动态的增强Action的功能。
注意:
只有调用了intercept()方法中的invocation参数的invoke()方法,才可以执行Action对象的请求方法(如果不调用,不会执行下面的拦截器和Action方法,Struts2会渲染自定义拦截器Intercept方法返回值对应的result)。
3.AbstractInterceptor
Interceptor是一个接口,如果通过这个接口创建拦截器,就需要实现它的三个方法。但是在实际开发中,只需要intercept()这个方法。为了简化程序,可以通过Struts2 API 中的AbstractInterceptor对象创建拦截器对象
AbstractInterceptor是一个抽象类,它实现了Interceptor接口。因为AbstractInterceptor已经对Interceptor接口的init()方法与destroy()方法。所以通过继承AbstractInterceptor对象创建拦截器,就不需要实现这两个方法,只需要实现intercept()方法。
4.自定义拦截器
步骤:
(1)自定义一个拦截器的类
- 可以实现Interceptor接口
- 可以继承AbstractInterceptor抽象类
(2)在struts.xml文件中进行配置
注册拦截器
在需要使用的Action中引用上述定义的拦截器。
代码示例:
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="timer" class=".."/>
<interceptor name="logger" class=".."/>
</interceptors>
<action name="login" class="tutorial.Login">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
<result name="input">login.jsp</result>
<result name="success"type="redirect-action">...</result>
</action>
</package>
可以将多个拦截器合并在一起作为一个堆栈调用,当一个拦截器堆栈被附加到一个Action,要想Action执行,必须执行拦截器堆栈的每一个拦截器
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="timer" class=".."/>
<interceptor name="logger" class=".."/>
<interceptor-stack name="myStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
</interceptor-stack>
</interceptors>
<action name="login" class="tutuorial.Login">
<interceptor-ref name="myStack"/>
<result name="input">login.jsp</result>
<result name="success" type="redirect-action">...</result>
</action>
</package>
注意:有一个拦截器堆栈比较特殊,它会应用在默认的每一个Action上
<interceptor-stack name="defaultStack">
.....
</interceptor-stack>
每一个拦截器都可以配置参数,有两种方式配置参数:一针对每一个拦截器定义参数,二是针对一个拦截器堆栈统一定义所有的参数
<interceptor-ref name="validation">
<param name="excludeMethods">myValidationExcudeMethod</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">myWorkflowExcludeMethod</param>
</interceptor-ref>
或者:
<interceptor-ref name="defaultStack">
<param name="validation.excludeMethods">myValidationExcludeMethod</param>
<param name="workflow.excludeMethods">myWorkflowExcludeMethod</param>
</interceptor-ref>
每一个拦截器都有两个默认的参数:
excludeMethods:过滤掉不适用拦截器的方法和
includeMethods:使用拦截器的方法