在Struts2中自定义拦截器,需要继承Interceptor接口,在该接口中定义了3个方法:
- void init():该方法在拦截器执行拦截之前执行,主要用于打开一些一次性资源,如数据库连接等。
- String intercept(AvtionInvocation invocation) throws Exception :在该方法体内定义需要执行的拦截动作,invocation参数是对被拦截的Action的引用,我们可以通过调用该参数的invoke()方法,将控制权转给下一个拦截器或者是被拦截Action的execute()方法。
- void destroy() :与init()方法对应,在拦截器执行拦截之后执行,主要用于关闭打开的资源。
Struts2定义了一个AbstractInterceptor类,他提供了对Interceptor接口中init和destroy方法的空实现,简化了用户在自定义拦截器时的操作。
举个例子,定义一个登陆Action的拦截器:
package com.test.interceptor;
import java.util.Date;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.test.action.LoginAction;
public class SimpleInterceptor extends AbstractInterceptor {
//拦截器的名称
private String name;
public void setName(String name) {
this.name = name;
}
/**
* 拦截Action方法的interceptor方法
*/
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//取得被拦截的Action实例
LoginAction loginAction = (LoginAction)invocation.getAction();
System.out.println(name + "拦截器的动作-----------------" +
"开始执行登陆Action的时间为: " + new Date());
//取得开始执行Action的时间
long start = System.currentTimeMillis();
//执行该拦截器的后一个拦截器或者直接指定Action的execute方法
String result = invocation.invoke();
System.out.println(name + "拦截器的动作-----------------" +
"执行完登陆Action的时间为: " + new Date());
//取得执行完成的时间
long end = System.currentTimeMillis();
System.out.println(name + "拦截器的动作-----------------" +
"执行完该Action的时间为" + (end - start) + "毫秒");
return result;
}
}
然后,我们在struts.xml文件中配置拦截器:
<interceptors> <!-- 配置SimpleInterceptor拦截器 --> <interceptor name="mySimple" class="com.test.interceptor.SimpleInterceptor"> <param name="name">简单拦截器</param> </interceptor> </interceptors> <action name="login" class="com.test.action.LoginAction"> <result name="success">result.jsp</result> <!-- 拦截器一般配置在result元素之后 --> <!-- 引用系统默认的拦截器 --> <interceptor-ref name="defaultStack"/> <!-- 在Action中引用自定义拦截器 --> <interceptor-ref name="mySimple"> <param name="name">改名后的简单拦截器一</param> </interceptor-ref> <interceptor-ref name="mySimple"> <param name="name">改名后的简单拦截器二</param> </interceptor-ref> </action>完成。另外,我们在配置文件中重复引用了同一个拦截器,只是为它赋予了不同的名称,通过结果我们可以看到,拦截器的引用顺序与执行顺序有一定的关系:配置在前面的拦截器,如果是在被拦截方法执行之前的拦截动作,则会先执行;如果是在被拦截方法执行之后的拦截动作,则会后执行。