说是三种方法,实际上是一种方法,其实只要这个类实现了Interceptor接口,即可成为一个拦截器类。
第一种方法就是 直接实现Interceptor接口,这样的话,就要实现这个接口中的三个方法。
第二种方法是 继承自AbstractInterceptor类,这是个抽象类,实现了Interceptor接口,并且对里面的init()和destroy()方法进行空实现,而把intercept()方法设置为抽象方法,让继承它的子类去实现,这样的话,子类只要实现这个intercept()方法就可以了,比直接实现接口要简单一些。
第三种方法是
继承自MethodFilterInterceptor,这个类叫做方法过滤拦截器,这个类继承自AbstractInterceptor,并且提供了一种机制,即可以指定对Action中某些方法进行拦截或者是不拦截,所谓拦截不拦截,指的就是拦截器中的intercept()方法是否被执行了,若没有执行,就是没有拦截,若执行了,就是拦截了。
第一、二种方法这里就不详细说明了,主要说一下第三种方法,即MethodFilterInterceptor的使用。
首先来看一下这个类的部分代码:
public abstract class MethodFilterInterceptor extends AbstractInterceptor { protected transient Logger log = LoggerFactory.getLogger(getClass()); protected Set<String> excludeMethods = Collections.emptySet(); protected Set<String> includeMethods = Collections.emptySet(); public void setExcludeMethods(String excludeMethods) { this.excludeMethods = TextParseUtil.commaDelimitedStringToSet(excludeMethods); } public Set<String> getExcludeMethodsSet() { return excludeMethods; } public void setIncludeMethods(String includeMethods) { this.includeMethods = TextParseUtil.commaDelimitedStringToSet(includeMethods); } public Set<String> getIncludeMethodsSet() { return includeMethods; } @Override public String intercept(ActionInvocation invocation) throws Exception { if (applyInterceptor(invocation)) { return doIntercept(invocation); } return invocation.invoke(); } protected boolean applyInterceptor(ActionInvocation invocation) { String method = invocation.getProxy().getMethod(); // ValidationInterceptor boolean applyMethod = MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, method); if (log.isDebugEnabled()) { if (!applyMethod) { log.debug("Skipping Interceptor... Method [" + method + "] found in exclude list."); } } return applyMethod; } protected abstract String doIntercept(ActionInvocation invocation) throws Exception; }
可以看到这里面有两个成员变量:includeMethods和excludeMethods,并且有对应的get/set方法,这两个变量的类型为String类型的集合,即可以放置多个String类型的数据,其实,这两个变量就是用来存放要拦截或者是不拦截的方法的名称的。includeMethods存放要进行拦截的方法名,excludeMethods存放不进行拦截的方法名。
在其中还实现了intercept方法,在里面经过某个判断后,调用了一个doIntercept()方法,这个方法是抽象的,就是要其子类去实现的。那么这个判断是什么呢?这个判断就是根据includeMethods和excludeMethods中存放的方法名,进行判断是否要对其进行拦截。
因为在类中已经实现了intercept()方法,而提供了一个抽象的doIntercept()方法,所以我们只要去实现这个抽象的方法,就可以实现针对到方法的拦截器了。
下面来个简单的例子
拦截器类: package com.suo.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; import com.suo.listeners.BeforeResultListener; public class MyInterceptor3 extends MethodFilterInterceptor { @Override protected String doIntercept(ActionInvocation invocation) throws Exception { System.out.println("before MyInterceptor3 invoke !"); String result=invocation.invoke(); System.out.println("after MyInterceptor3 invoke !"); return result; } }
配置拦截器:
<interceptor name="myInterceptor3" class="com.suo.interceptor.MyInterceptor3"></interceptor>
在action中引用拦截器:
<action name="action1" class="com.suo.actions.Action1" method="myExecute"> <result name="success" type="chain"> <param name="actionName">action2</param> </result> <interceptor-ref name="myInterceptor3"> <param name="includeMethods">myExecute</param> <param name="excludeMethods">execute</param><!--对myExecute进行拦截,对execute不拦截--> </interceptor-ref> </action>
其实,这里有一个疑问:
因为一个action只能指定一个执行的方法,即使你写了很多自定义的方法,但是它只会执行指定的方法,这里提供可以对多个方法进行拦截的机制有什么用呢?没有被指定的方法,是不会执行的,拦截它与不拦截它又能起什么作用呢