1.自定义拦截器
首先要编写自定义拦截器类,需要实现接口Interceptor,并且实现接口的方法
destory在拦截器销毁时调用
init在程序启动时加载拦截器,初始化调用
interceptor拦截器主要调用方法
public class MyInterceptor implements Interceptor {
private static final long serialVersionUID = 1L;
@Override
public void destroy() {
System.out.println("destory");
}
@Override
public void init() {
System.out.println("init");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("MyInterceptor1");
String result = invocation.invoke();
return result;
}
}
还需要再struts.xml中配置拦截器
packeage一般需要继承struts-default,然而在struts-default中定义了许多拦截器,可以查看strus2-core.jar中源文件struts-default.xml,并且可以看到
<default-interceptor-ref name="defaultStack"/>指定默认的拦截器栈,在action中如果特别指定了拦截器或者拦截器栈,那么默认的拦截器栈则不会再起作用,所以在action中配置拦截器不仅要指定自己写的拦截器,还要指定defaultStack
<struts>
<package name="struts" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor1" class="cn.com.baiwen.interceptor.MyInterceptor1"></interceptor>
</interceptors>
<action name="login" class="cn.com.baiwen.action.LoginAction">
<result name="success">/result.jsp</result>
<interceptor-ref name="myInterceptor1"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
<action name="register" class="cn.com.baiwen.action.RegisterAction">
<result name="success">/result.jsp</result>
<result name="input">/register.jsp</result>
</action>
</package>
</struts>
2.拦截器参数传递
拦截器和过滤器一样是可以传递参数的,interceptor-ref标签下面定义param子标签,name属性和标签内容,name属性需要和自定义标签类中的成员变量一致(默认set,get方法),标签内容为参数值
public class MyInterceptor1 implements Interceptor {
private static final long serialVersionUID = 1L;
private String hello;
public String getHello() {
return hello;
}
public void setHello(String hello) {
this.hello = hello;
}
@Override
public void destroy() {
System.out.println("destory");
}
@Override
public void init() {
System.out.println("init");
System.out.println(hello);
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("MyInterceptor1");
String result = invocation.invoke();
return result;
}
}
<struts>
<package name="struts" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor1" class="cn.com.baiwen.interceptor.MyInterceptor1"></interceptor>
</interceptors>
<action name="login" class="cn.com.baiwen.action.LoginAction">
<result name="success">/result.jsp</result>
<interceptor-ref name="myInterceptor1">
<param name="hello">world</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
<action name="register" class="cn.com.baiwen.action.RegisterAction">
<result name="success">/result.jsp</result>
<result name="input">/register.jsp</result>
</action>
</package>
</struts>
3.自定义拦截器栈,和设置默认拦截器栈
可以自动义拦截器栈,并且指定默认的拦截器栈为哪个,这样就不需要再每个action下面去特意指定拦截器了
<struts>
<package name="struts" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor1" class="cn.com.baiwen.interceptor.MyInterceptor1">
<param name="hello">world</param>
</interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor1"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 指定默认的拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<action name="login" class="cn.com.baiwen.action.LoginAction">
<result name="success">/result.jsp</result>
</action>
<action name="register" class="cn.com.baiwen.action.RegisterAction">
<result name="success">/result.jsp</result>
<result name="input">/register.jsp</result>
</action>
</package>
</struts>
3.拦截器之AbstractInterceptor
很多时候拦截器的destory和init方法是用不到的,所以在xwork-core.jar中定义了抽象类AbstractInterceptor,查看源码可以看到该类实现了Interceptor接口,空实现destory和init方法,并且提供了抽象的方法intercept
public abstract class AbstractInterceptor implements Interceptor {
/**
* Does nothing
*/
public void init() {
}
/**
* Does nothing
*/
public void destroy() {
}
/**
* Override to handle interception
*/
public abstract String intercept(ActionInvocation invocation) throws Exception;
}
所以我们只需要继承AbstractInterceptor并且实现其抽象方法即可
public class MyInterceptor2 extends AbstractInterceptor {
private static final long serialVersionUID = 1L;
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("MyInteceptor2");
String result = invocation.invoke();
return result;
}
}
4.拦截器之MethodFilterInterceptor
这个拦截器可以通过参数传递,自定义需要拦截的方法和不需要拦截的方法,类继承AbstractInterceptor,并且有两个参数(excludeMethods,includeMethods),提供抽象方法doIntercept,所以继承这个类,需要实现doIntercept方法,并且在xml中传递参数(参数为action中的方法名称,多个可以使用“,”分割),如果方法名在两个参数中都存在,则按照includeMethods,执行拦截,所以includeMethods比excludeMethods等级要高,例如:
<action name="login" class="cn.com.baiwen.action.LoginAction">
<result name="success">/result.jsp</result>
<interceptor-ref name="myInterceptor3">
<param name="excludeMethods">>method1,method2</param>
<param name="includeMethods">method1</param>
</interceptor-ref>
</action>
如上配置,拦截器依然会执行method1
5.拦截器执行顺序
定义多个拦截器,拦截器进入的顺序为在xml中配置在前的先进入拦截器,但是后出拦截器,不多说,举例说明:
public class MyInterceptor1 implements Interceptor {
private static final long serialVersionUID = 1L;
private String hello;
public String getHello() {
return hello;
}
public void setHello(String hello) {
this.hello = hello;
}
@Override
public void destroy() {
System.out.println("destory");
}
@Override
public void init() {
System.out.println("init");
System.out.println(hello);
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("MyInterceptor1 start");
String result = invocation.invoke();
System.out.println("MyInterceptor1 end");
return result;
}
}
public class MyInterceptor2 extends AbstractInterceptor {
private static final long serialVersionUID = 1L;
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("MyInteceptor2 start");
String result = invocation.invoke();
System.out.println("MyInteceptor2 end");
return result;
}
}
<struts>
<package name="struts" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor1" class="cn.com.baiwen.interceptor.MyInterceptor1">
<param name="hello">world</param>
</interceptor>
<interceptor name="myInterceptor2" class="cn.com.baiwen.interceptor.MyInterceptor2">
</interceptor>
<interceptor name="myInterceptor3" class="cn.com.baiwen.interceptor.MyInterceptor3">
</interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor1"></interceptor-ref>
<interceptor-ref name="myInterceptor2"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 指定默认的拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<action name="login" class="cn.com.baiwen.action.LoginAction">
<result name="success">/result.jsp</result>
</action>
<action name="register" class="cn.com.baiwen.action.RegisterAction">
<result name="success">/result.jsp</result>
<result name="input">/register.jsp</result>
</action>
</package>
</struts>
在myStack中myIterceptor1引入在前,所以先执行,然后执行myInterceptor2,但是拦截器执行推出时则相反,以上例子后台打印为:
MyInterceptor1 start
MyInteceptor2 start
MyInteceptor2 end
MyInterceptor1 end