Struts2中的拦截器(Interceptor)用于拦截action。
一、定义一个拦截器MyInterceptor
package test.interceptor; public class MyInterceptor implements Interceptor { @Override public void destroy() { System.out.println("destroy"); } @Override public void init() { System.out.println("init"); } @Override public String intercept(ActionInvocation arg0) throws Exception { System.out.println("interceptor invoke"); arg0.invoke(); } }
通过以上代码,可以看出,定义一个拦截器的方法其实很简单,只需要实现Interceptor接口,并实现接口中定义的这三个方法即可。
二、配置拦截器
在struts.xml文件中配置刚才定义好的拦截器
<interceptors> <interceptor name="MyInterceptor" class="text.interceptor.MyInterceptor"> </interceptor> </interceptors>
到这一步,总算是把拦截器配置OK了,但是这仅仅是将拦截器声明好而已,这个时候,拦截器还无法正常工作的。因为拦截器是用来拦截Action的,到现在为止,我们还没有定义该拦截器用来拦截哪一个Action。那么要想让其工作,还要在想要进行拦截的Action中加入以下定义语句
<action name="XXX" class="xxx.xxx.xxx"> <result name="success">/index.jsp</result> <interceptor-ref name="MyInterceptor"></interceptor-ref> </action>
到目前为止,当调用这个Action的时候,拦截器就会很听话的跑起来了。可以,要注意一点,如果配置了全局的默认拦截器,又为某个Action定义了局部拦截器,这种情况下,全局的拦截器将失效。
呵呵,不用担心,问题肯定是有办法解决的,只需要将原来那个默认的拦截器栈也引用进来即可:
<action name="XXX" class="xxx.xxx.xxx"> <result name="success">/index.jsp</result> <interceptor-ref name="MyInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </action>
好的,问题解决了,但是这样显得很麻烦,那么有没有简便一些的方法呢?答案肯定是有的,不急,接着向下看。
三、拦截器初始参数
拦截器还可以带上初始参数,方法如下:
<interceptors> <interceptor name="MyInterceptor" class="text.interceptor.MyInterceptor"> <param name="hello">world</param> </interceptor> </interceptors>
然后在MyInterceptor.java中定义一个与param的name名称相同的变量,并为其生成Setter和Getter方法:
package test.interceptor; public class MyInterceptor implements Interceptor { private String hello = null; public void setHello(String hello){ this.hello = hello; } public String getHello(){ return this.hello; } @Override public void destroy() { System.out.println("destroy"); } @Override public void init() { System.out.println(this.hello); System.out.println("init"); } @Override public String intercept(ActionInvocation arg0) throws Exception { System.out.println("interceptor invoke"); arg0.invoke(); } }
这样一来,Struts2就会自动将hello的值为MyInterceptor类中的hello变量赋值,就可以在程序中会用该值了。当然,我们还可以在使用拦截器的时候,重新为Param分配新值,方法如下:
<action name="XXX" class="xxx.xxx.xxx"> <result name="success">/index.jsp</result> <interceptor-ref name="MyInterceptor"> <param name="hello">welcome</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </action>
这样,在程序中,取到的值就是"welcome"了。
四、自定义拦截器栈
下面我们先看一下如何自定义一个拦截器栈。
<interceptors> <interceptor name="MyInterceptor" class="text.interceptor.MyInterceptor"> <param name="hello">world</param> </interceptor> <interceptor-stack name="MyStack"> <interceptor-ref name="MyInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors>
好了,一个自定义的拦截器栈就这样成型了,在定义拦截器栈的时候,可以包含拦截器或者拦截器栈。
下面,就可以在Action中直接引用自定义的这个MyStack拦截器栈,而不用引用多个拦截器了。看,是不是方便了一些啊。
五、自定义默认拦截器栈
其实呢,还有更方便的一种方式,因为呀,一个<package></package>元素里面可以定义一个默认的拦截器,这样的话,该package中的所有Action就默认带上了这个拦截器。定义方法非常的简单,但记住,一个Package中有且只有一个默认拦截器。
<default-interceptor-ref name="MyStack" />
只需要在Package元素中加入上面这一句即可,这个包当中的所有Action就会被套上MyStack拦截器。哈哈。这下可真方便了。
小结:
1、如果配置了全局的默认拦截器,又为某个Action单独定义了局部拦截器,全局拦截器将失效。
2、一个<package></package>中,有且只有一个默认拦截器