Struts2的拦截器(Interceptor)是非常重要的概念,Struts2中的大多数的功能都是通过拦截器实现的。下面主要讲述一下Struts2中拦截器的实现原理,以及尝试自定义一个拦截器。
1 Struts2中拦截器的原理
在运行Action之前,Struts2会调用一大堆的拦截器,所有的拦截器调用完之后才会调用用户自定义的Action。如下图所示,Struts2在运行过程中,代码的运行过程如下:
a. 首先运行到StrutsPrepareAndExecuteFilter类,即下图的Struts2Filter;b. 然后调用Dispatcher的serviceAction()方法;
c. Dispatcher构建ActionProxy对象并调用proxy的execute()方法;
d. ActionProxy在执行execute()方法时调用ActioinInvocation对象的invoke方法;
e. ActioinInvocation对象的invoke()方法会依次取出所有的Interceptor,并执行Interceptor的intercept()方法。(关键步骤)
f. Interceptor的intercept()方法在执行的最后会回调ActionInvocation的invoke()方法,这样才好继续执行后面的Interceptor。
g. 当所有的Interceptor执行完成后, ActioinInvocation对象的invoke()会调用我们自定义的Action。
2 自定义Struts2的拦截器
自定义一个拦截器可以参考Struts2的源代码即可,源码怎么定义,我们就怎么定义。
2.1 定义拦截器
定义拦截器可以继承AbsactIntercepor抽象类,也可以实现Intercepor接口,这里我实现Intercepor接口用于计算Action的执行时间,如下:
public class MyInterceptor implements Interceptor {
public void destroy() {
}
public void init() {
}
public String intercept(ActionInvocation invocation) throws Exception {
long start = System.currentTimeMillis();
String r = invocation.invoke();
long end = System.currentTimeMillis();
System.out.println("action time = " + (end - start)); //算出action的执行时间
return r;
}
}
在intercept方法中必须调用invocation.invoke()方法,否则无法执行后面的拦截器和Action。
2.2 部署拦截器
部署拦截器是在struts.xml中进行部署。
首先得声明拦截器:
<interceptors>
<interceptor name="my" class="cn.edu.MyInterceptor"></interceptor>
</interceptors>
其次需要将拦截器加到action中去:
<interceptor-ref name="my"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
默认情况下,Struts2的拦截器是defaultStack,当我们自定义了拦截器加上去后不应该把原有的拦截器覆盖掉,因此需要协商两个拦截器(自定义的和defaultStack)。如上面代码。
其完整的struts.xml如下所示:
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="test" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="my" class="cn.edu.MyInterceptor"></interceptor>
</interceptors>
<action name="test" class="com.bjsxt.action.TestAction">
<result>/test.jsp</result>
<interceptor-ref name="my"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
2.3 测试运行
部署到tomcat上后,通过浏览器调用test.action,可以看到程序后台打印出来:
全文完。转载请注明出处。