拦截器的作用

Struts2架构的绝大部分功能都是通过拦截器来完成的。拦截器能够在执行action或者action的某个方法前,对用户请求进行预先处理。Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。Struts2中预先写好了大量的默认拦截器,只要action的包集成了struts-default包,这些内建的拦截器就能够自动发挥作用。如果想要向项目中添加自定义的拦截器,只需要在struts.xml文件中配置该拦截器即可。配置采用拦截器名-实现类的属性配置方式。除此之外,还可以将很多个拦截器打包,组成拦截器栈,使用interceptor-stack进行配置。拦截器栈不仅可以包含很多拦截器,还能够包含其它的拦截器栈。配置拦截器的时候还可以为拦截器配置参数,达到动态配置的效果。


拦截器的实现

Struts2规定用户自定义拦截器必须实现com.opensymphony.xwork2.interceptor.Interceptor接口。该接口声明了3个方法


void init();
void destroy();
String intercept(ActionInvocation invocation) throws Exception

init:在拦截器实例化后,执行拦截之前系统将回调此方法。此方法只被执行一次,主要用于初始化资源,比如数据库的链接。

destroy:在拦截器实例被销毁之前,系统会回调此方法以销毁init方法中打开的各种资源。

intercept(ActionInvocation invocation):该方法是用户需要实现的拦截功能。此方法会范湖一个字符串作为逻辑视图。invocation参数包含了被拦截的action的引用,可以使用getAction方法得到action实例。Intercept是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用invocation.invoke()方法即可,在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。如果不需要调用后续的方法,则返回一个String类型的对象即可,例如Action.SUCCESS

如果自定义的拦截器无需开关资源,则可以直接继承AbstractInterceptor类。这个类提供了init和destroy方法的空实现。


拦截器的配置

在struts.xml中配置拦截器,首先要先定义。然后在需要的action中标注。配置的时候要制定拦截器名字跟实现类。也可以使用拦截器栈打包使用。

<package name="cm" extends="struts-default">
<interceptors>
<interceptor name="first" class="com.cm.interceptor.my1"></interceptor>
<interceptor name="second" class="com.cm.interceptor.my2"></interceptor>
<interceptor name="third" class="com.cm.interceptor.my3"></interceptor>

<interceptor-stack name="bag1">
<interceptor-ref name="first" />
<interceptor-ref name="second" />

</interceptor-stack>
</interceptors>

<action name="asdf" class="adsg">

<interceptor-ref name="bag1"></interceptor-ref>
<interceptor-ref name="third"></interceptor-ref>

</action>

</package>

配置是在package下配置的。首先使用interceptor元素来定义拦截器。然后可以使用拦截器栈进行打包操作。使用的时候只需要在action中引用ref即可。ref就是引用的意思,通过名字引用实现定义好的拦截器。

每一个拦截器都可以配置参数,有两种方式配置参数,一是针对每一个拦截器定义参数,二是针对一个拦截器堆栈统一定义所有的参数。


如下代码能够实现在action之前跟之后分别进行操作:

public class OneInterceptor implements Interceptor{
    ...
    public String intercept(ActionInvocation act) throws Exception {
        //在Action之前执行的代码
        ......
        //开始执行Action
        String result=act.invoke();//
        //在Action之后的代码
        ......
        //结束拦截器
        return result;
    }
}