Struts2拦截器详解

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值