Struts2之拦截器(拦截客户端对Action访问)

 一、概述

 

拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截,然后再之前或之后加入某些操作,拦截器是AOP的一种策略。

在WebWork的中文文档的解释为,拦截器是动态拦截Action调用对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后代码,也可以在一个Action前阻止其执行。同时,也是提供了一种可以提取Action中可重用的部分的方式。

拦截器链(Intercepor Chain,在Struts2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的书序被调用。

二、执行流程

客户端向服务器发送一个Action的请求,执行核心过滤器(doFilter)方法。在这个方法中,调用executeAction()方法,在这个方法内部调用dispatcher.serviceAction();在这个方法内部创建一个Action代理,最终执行的是Action代理中的execute(),在代理中执行的execute方法中调用ActionInvocation的invoke方法。在这个方法内部递归执行一组拦截器(完成部分功能),如果没有下一个拦截器,就会执行目标Action,根据Action的返回的结果进行页面跳转。

Struts2拦截器是可插拔的,拦截器是AOP的一种实现。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。

三、自定义拦截器方式

1.实现Interceptor接口

拦截器生命周期,随项目的启动而创建,随项目关闭而销毁

(1)void init():该方法在拦截器被创建后立即被调用,它在拦截器的生命周期只被调用一次,可以在该方法中对相关资源进行必要的初始化。

(2)void destroy():该方法与init方法相对应,在拦截器实例被销毁之前,将调用该方法来释放和拦截器有关的资源,它在拦截器的生命周期内,也只被调用一次。

(3)String intercept(ActionInvocation invocation):该方法是拦截器的核心方法,用来添加真正执行工作的代码,实现具体的拦截操作。它返回一个字符串作为逻辑视图,系统根据返回的字符串跳转到对应的视图资源。每拦截一个动作请求,该方法就会被调用一次。该方法的ActionInvocation参数包含了被拦截的Action的引用,可以通过该参数的invoke()方法,将控制权转给下一个拦截器或者转给Action的execute()方法,使用时,可以直接继承抽象类,而不用实现那么不必要的方法。

public class LoginInterceptor implements Interceptor{
	@Override
	public void destroy() {
		
	}
	@Override
	public void init() {
		
	}
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		return null;
	}
}

2.继承AbstractInterceptor类

AbstractInterceptor帮我们实现了init和destory方法,我们不要实现这两个方法,只需要实现intercept方法

public class LoginInterceptor extends AbstractInterceptor{
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		
		return null;
	}
}

3.继承MethodFilterInterceptor类(常用)

public class LoginInterceptor extends MethodFilterInterceptor{

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		
		return null;
	}

}

四、自定义拦截器流程

public class LoginInterceptor extends MethodFilterInterceptor{
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		//前处理
		System.out.println("Action执行的前处理");
		//放行,将控制权转交给下一个拦截器
		invocation.invoke();
                //后处理
		System.out.println("Action执行的后处理");
		
		//不放行,直接跳转到一个结果页面,不执行后续的拦截器以及Action,直接交给Result处理结果.进行页面跳转
		return "success";
	}
}

1.方式一,不采用拦截器栈

1'' 注册自定义拦截器

    <!-- 注册自定义拦截器 -->
    <interceptors>
        <interceptor name="loginIntercepter" class="com.mark.web.interceptor.LoginInterceptor"></interceptor>
        <interceptor name="demoIntercepter" class="com.mark.web.interceptor.DemoInterceptor"></interceptor>
    </interceptors>

2'' 在想要拦截的Action下引入拦截器(使用自定义拦截器会使默认拦截器失效,所以需要手动引入)

<action name="hello_*" class="com.mark.struts2.Action.LoginAction" method="{1}">
    <!-- 引用默认拦截器-->
    <interceptor-ref name="defaultStack"></interceptor-ref>

    <!-- 引用自定义拦截器-->
    <interceptor-ref name="loginIntercepter">
        <!--  指定哪些方法不拦截
        <param name="excludeMethods">loginUser</param> -->
        <!-- 指定哪些方法拦截 -->
        <param name="includeMethods">loginUser</param>
    </intercept> 

    <interceptor-ref name="demoIntercepter">
        <!--  指定哪些方法不拦截
        <param name="excludeMethods">test2</param> -->
        <!-- 指定哪些方法拦截 -->
        <param name="includeMethods">test1</param>
    </intercept>      
       
    <result name="success" type="dispatcher">/login.jsp</result>
</action>

2.方式二,采用拦截器栈

1'' 注册自定义拦截器与拦截器栈,并且可以定制拦截方法 

    <!-- 注册自定义拦截器 -->
    <interceptors>
        <interceptor name="loginIntercepter" class="com.mark.web.interceptor.LoginInterceptor"></interceptor>
        <interceptor name="demoIntercepter" class="com.mark.web.interceptor.DemoInterceptor"></interceptor>

        <!-- 配置拦截器栈 -->
        <interceptor-stack name="loginStack">
            <!-- 引入自定义的拦截器 -->
            <interceptor-ref name="loginIntercepter">
                <!--  指定哪些方法不拦截
                <param name="excludeMethods">loginUser</param> -->
                <!-- 指定哪些方法拦截 -->
                <param name="includeMethods">loginUser</param>
            </interceptor-ref>
            
            <interceptor-ref name="DemoInterceptor">
                <!--  指定哪些方法不拦截
                <param name="excludeMethods">test2</param> -->
                <!-- 指定哪些方法拦截 -->
                <param name="includeMethods">test1</param>
            </interceptor-ref>

            <!-- 引入默认的拦截器栈(20个) -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
        </interceptor-stack>
    </interceptors>

2'' 在想要拦截的Action下引入拦截器栈

<action name="hello_*" class="com.mark.struts2.Action.LoginAction" method="{1}">
    <!-- 引用拦截器栈-->
    <interceptor-ref name="loginStack"></interceptor-stack>

    <result name="success" type="dispatcher">/login.jsp</result>
</action>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值