今天看了看拦截器,不由得想对拦截器做个描述,在我们进行项目拦截器编写的时候,让我们先把前期的配置给搭建好。
首先我们需要在web.xml中配置信息如下
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.summer.action.server</param-value>
</init-param>
</filter>
// org.apache.struts2.dispatcher.FilterDispatcher这个已经过时了、
// org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecute替代以上
// <filter>
// <filter-name>struts2</filter-name>
// <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
// </filter>
<struts>
<package name="methodFilter" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor11" class="com.sharme.interceptor.MyInterceptor11">
<param name="hello">world</param>
</interceptor>
<!--<param name="hello">world</param>表示为拦截器增加一个名为hello值为world的属性-->
<!--但是这里也只是为hello赋了初值为world,如若在下面的<action>中配置使用该拦截器的时候-->
<!--增加了<param name="hello">welcome</param>,那么则最后拦截器累中的hello属性值即为welcome-->
<interceptor name="myInterceptor21" class="com.sharme.interceptor.MyInterceptor21"/>
</interceptors>
<action name="methodFilter" class="com.sharme.action.MethodFilterAction" method="test">
<result name="success">/methodFilteResult.jsp</result>
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="myInterceptor11"/>
</action>
</struts>
以上是对于 "方法过滤拦截器" 的使用:
默认的情况下,拦截器会拦截Action中的所有的方法,这里不包括setter或getter方法,这时就可以使用方法过滤拦截器指定的方法,这是一种更加
细化的拦截器的配置方式,它可以细化到拦截具体的某个方法,而不是拦截某个Action,因为拦截Action是一种粗粒度的实现方式,使用includeMethods
指明拦截器所要拦截的方法。使用excludeMethods指明拦截去不再拦截的方法,这里excludeMethods和includeMethods是在MethodFilterInterceptor
类中定义的成员变量,而且只要includeMethods进来的方法就一定会被拦截,而不管是否已经把它excludeMethods在外了
也就是说includeMethods的优先级要高于excludeMethods
也可以使用<param name="includeMethods"/>在上面定义拦截器的时候指定全局性的过滤的方法
区别:对方法的过滤有全局性和局部性的区分。而当发生冲突时,就依照就近原则,以局部性的配置为准,所谓的发生冲突,指的是类似于
全局中有一个includeMethods配置,而局部中也有一个includeMethods配置,另外,还有一种情况,假设全局性过滤定义为<param name="includeMethods">
test</param>而在局部性过滤中定义为<param name="excludeMethods">test</param>将生效,即拦截Action中的test()方法,这个时候全局中配置的拦截
局部中配置的是不拦截,二者并没有发生冲突,所有仍是以includeMethods优先级高,可以认为在局部的配置中,已经隐含的把<param name="includeMethods">
test</param>继承过来了
实现Interceptor接口的自定义拦截器MyInterceptor.java
public class MyInterceptor implements Interceptor{
//这里属性名要与struts.xml配置的<param name=""/>中的name值相同
//然后struts2会自动将struts.xml中配置的world值赋值到这里的hello属性中
//前提是要提供setter和getter方法,只要符合JavaBean的要求即可
private String hello;
public String getHello(){return hello;}
public void setHello(String hello){this.hello=hello;}
//initialization method
public void init(){
System.out.println("----MyInterceptor initialization method invoked---");
}
//destory method
public void destory(){
System.out.println("----MyInterceptor destory method invoked-----");
}
public String interceptor(ActionInvocation invocation)throws Exception{
System.out.println("----MyInterceptor invoked begin");
//调用invoke()方法
//还有下一个拦截器的话,执行下一个拦截器
//如何没有下一个拦截器的话,就执行Action中的方法
String result=invocation.invoke();
System.out.println("--MyInterceptor invoked finish--------");
return result;
}
}
------下面来谈谈Struts2的拦截器------------
struts2中的拦截器,实际上就是用来拦截Action的。它就相当于入口和出口一样,把Action的相关方法包裹在中间了
,过滤器可以组成过滤器链,也就是有多个过滤器来过滤相同的东西。拦截器同样也有拦截器链,在struts2中称为
拦截器栈,拦截器执行的顺序是按照配置的顺序执行的。
假设先配置myInterceptor1,再配置myInterceptor2,所有在执行时,先执行myInterceptor1,后执行myInterceptor2
,但是结束时,先执行myInterceptor2,后执行myInterceptor1,就好stack,压栈和弹栈的过程
过程是:先会进入第一个拦截器,出来后再进入第二个拦截器,以此类推,最后进入Action的execute()方法,之后是进行
相反地顺序。
因此invoke就是用来判断,若还有下一个拦截器,就调用下一个拦截器,否则,直接跳到Action的execute方法
------------继承了AbstractInterceptor类的自定义拦截器MyInterceptor3
public class MyInterceptor3 extends AbstractInterceptor{
public String interceptor(ActionInvocation invocation)throws Exception{
System.out.println("---------MyInterceptor3 invoked begin");
String result=invocation.invoke();
System.out.println("---------MyInterceptor3 invoked finish-----");
return result;
}
}
继承AbstractInterceptor类的拦截器就不需要自己去实现init和destory方法了,在我们应用之中,更多的时候还是
继承AbstractInterceptor而不是实现Interceptor
-------------继承MethodFilterInterceptor拦截器
public class MyInterceptor4 extends MethodFilterInterceptor{
protected String doIntercept(ActionInvocation invocation)throws Exception{
System.out.println("------MyInterceptor4 invoked begin");
String result=invocation.invoke();
System.out.pritnln("----MyInterceptor4 invoked finish-----");
}
}
MethodFilterInterceptor拦截器继承了AbstractInterceptor,他就是一个拦截某一个具体的方法的过滤拦截器。
而MethodFilterInterceptor类已经自动实现好了Intercept方法,实际上MethodFilterInterceptor类中的Intercept
方法真正执行的是它本身的一个doIntercept()抽象方法,因此我们需要拦截某一个方法时候:只要继承
methodFilterInterceptor类,然后实现doIntercept