Struts2拦截器

关于拦截器

1.概念:动态拦截Action的对象,提供了一种机制,使得开发者在定义的action执行前后加执行的代码;封装大量的功能的组件;也可以在一个action执行前组织其执行,也就是说它提供了一种可以提取action中的重复代码,统一管理和执行的方式。不同的拦截器完成不同的功能。

2.拦截器链:即拦截器栈(Interceptor chain->Interceptor Stack),将拦截器按一定顺序链接成一条链,当访问到被拦截的方法或字段时,拦截器栈中的拦截器就会按顺序执行其中定义的拦截器。

3.拦截器和过滤器的区别:

      3.1:过滤器是servlet中的规范,任何web项目都可以使用

      3.2:  拦截器是struts2框架中的模块

      3.3:过滤器可以过滤任何内容,拦截器只能拦截目标action

 4.通常情况下,struts2中会执行一组默认的拦截器

拦截器底层原理

1.AOP思想(面向切面编程,约定大于配置,spring的重点)

在不修改源码的基础上对已有的方法进行动态增强

在struts2中,拦截器就是对Action进行增强(将复刻代码提出来,放在拦截器中统一管理和执行)

2.责任链模式(动态代理)

在action方法执行之前执行默认拦截器,执行过程使用AOP思想(action没有直接调用拦截器的方法,而是使用配置文件方式进行操作)

在执行多个默认的拦截器的时候,使用责任链模式(拦截器1执行完毕之后->放行->执行拦截器2->拦截器2执行完毕后放行->执行拦截器3->拦截器3执行完毕放行->action)

自定义拦截器

1.目的:通过自定义拦截器,补充系统默认拦截器中不具备的功能

2.常用方法:

   2.1:实现Interceptor接口

2.2:继承AbstractInterceptor

3.继承MethodFilterInterceptor

拦截器结构描述

以MethodFilterInterceptor为例

它不仅继承了AbstractInterceptor,还可以指定不拦截的方法

其中的核心为doIntercept(ActionInvocation actionInvocation)

放行即通过actionInvocation对象执行invoke方法(注意,该方法并不是反射)

当不放行而要拦截并引导到方法时(不执行action类),返回一个返回值name即可(拦截器最终会回到action,返回name即在通知action执行方法的哪一个)

拦截器放行之后的情况   --执行拦截器的方法后,执行action中的被拦截的方法,相当于调用action中的被拦截的方法

拦截器返回为null的情况 --不执行action中的方法。

拦截器返回放行的情况 ---执行拦截器的方法后,执行action中的被拦截的方法,相当于调用action中的被拦截的方法,推荐使用

在action中配置拦截器

1.在被拦截的action所在package标签中声明拦截器(interceptors/interceptor标签):注意package中如果与其它标签,interceptors标签必须放在最前面,否则编译无法通过。

2.在action中使用声明的拦截器(interceptor-ref标签)

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <!--设置字符集-->
    <constant name="struts.i18n.encoding" value="utf-8"></constant>
    <!--&lt;!&ndash;导入其他的配置文件&ndash;&gt;-->
    <!--设置为开发者模式,可以打印出更详细的错误信息-->
    <constant name="struts.devMode" value="true"></constant>
    <!--<include file="work.xml"></include>-->
    <include file="hello.xml"></include>
    <package name="dupei2" extends="struts-default" namespace="/ehome">
        <interceptors>
            <interceptor name="interceptor" class="com.bj169.interceptor.Interceptor1"></interceptor>
            <!--声明拦截器栈-->
            <interceptor-stack name="myDefaultStack">
                <interceptor-ref name="interceptor">
                    <!--设置方法是否拦截,excludeMethods代表不拦截-->
                    <!--<param name="excludeMethods">show</param>-->
                </interceptor-ref>
            </interceptor-stack>
        </interceptors>

        <action name="demo1" class="com.bj169.action.Demo1Action" method="show">
            <interceptor-ref name="interceptor"></interceptor-ref>
            <!--系统默认拦截器-->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <result name="success">/debug.jsp</result>
            <result name="index">/index.jsp</result>
        </action>
    </package>
</struts>
package com.bj169.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;


/**
 * @ClassName Interceptor1
 * @Description TODO
 * @Author Administrator
 * @Date 2018/12/3 0003 10:26
 * @Version 1.0
 **/
public class Interceptor1 extends MethodFilterInterceptor {

    @Override
    public String doIntercept(ActionInvocation actionInvocation) throws Exception {
        System.out.println("拦截器1开始运行");
        return actionInvocation.invoke();
//        System.out.println("拦截器2开始运行");
//        return "success";
    }
}

拦截器的返回值

拦截器返回的是action执行的方法的返回值,那么,如果拦截器同时存在放行和return呢?

package com.bj169.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;


/**
 * @ClassName Interceptor1
 * @Description TODO
 * @Author Administrator
 * @Date 2018/12/3 0003 10:26
 * @Version 1.0
 **/
public class Interceptor1 extends MethodFilterInterceptor {

    @Override
    public String doIntercept(ActionInvocation actionInvocation) throws Exception {
        System.out.println("拦截器1开始运行");
        actionInvocation.invoke();
        System.out.println("拦截器2开始运行");
        return "success";
    }
}

jsp页面在拦截器执行完毕后才会显示,所以,执行到放行的时候,jsp的内容是暂存在缓冲区的,不管最后return的是什么,都显示的是缓冲区的内容(即放行得到的结果)。意思就是执行放行后action方法中返回的页面,而不是拦截器返回的页面。

添加其他默认拦截器

自定义拦截器会让默认拦截器失效,手动添加一次,引用defaultStack即可),根据实际情况,如果不需要使用默认中的功能,则不需配置

设置拦截器栈 (完整代码)

拦截器会对action中所有方法都进行拦截,需要对指定的方法不进行拦截(在interceptor-ref中进行配置),使用param标签并配置不拦截的方法名称(不是name名称,而是action的method属性,例如execute()),多个不拦截的方法可以用,隔开。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <!--设置字符集-->
    <constant name="struts.i18n.encoding" value="utf-8"></constant>
    <!--&lt;!&ndash;导入其他的配置文件&ndash;&gt;-->
    <!--设置为开发者模式,可以打印出更详细的错误信息-->
    <constant name="struts.devMode" value="true"></constant>
    <!--<include file="work.xml"></include>-->
    <include file="hello.xml"></include>
    <package name="dupei2" extends="struts-default" namespace="/ehome">
        <interceptors>
            <interceptor name="interceptor" class="com.bj169.interceptor.Interceptor1"></interceptor>
            <!--声明拦截器栈-->
            <interceptor-stack name="myDefaultStack">
                <!--引入系统默认拦截器,不需要的话可以不用-->
                <interceptor-ref name="defaultStack"></interceptor-ref>
                <!--引用自定义拦截器-->
                <interceptor-ref name="interceptor">
                    <!--设置方法是否拦截,excludeMethods代表不拦截-->
                    <param name="excludeMethods">show</param>
                </interceptor-ref>
            </interceptor-stack>
        </interceptors>

        <action name="demo1" class="com.bj169.action.Demo1Action" method="show">
            <!--引用自定义拦截器栈-->
            <interceptor-ref name="myDefaultStack"></interceptor-ref>
            <result name="success">/debug.jsp</result>
            <result name="index">/index.jsp</result>
        </action>
    </package>
</struts>
package com.bj169.action;

import com.bj169.entity.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;


/**
 * @ClassName Demo1Action
 * @Description TODO
 * @Author Administrator
 * @Date 2018/11/29 0029 9:35
 * @Version 1.0
 **/
public class Demo1Action extends ActionSupport {

    public String show() {
        System.out.println("action中的show方法");
        return "index";
    }
    
}
package com.bj169.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;


/**
 * @ClassName Interceptor1
 * @Description TODO
 * @Author Administrator
 * @Date 2018/12/3 0003 10:26
 * @Version 1.0
 **/
public class Interceptor1 extends MethodFilterInterceptor {

    @Override
    public String doIntercept(ActionInvocation actionInvocation) throws Exception {
        System.out.println("拦截器1开始运行");
        return actionInvocation.invoke();
//        System.out.println("拦截器2开始运行");
//        return "success";
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值