Struts2中的拦截器概述

在开始讲解之前,先分享一篇不错的关于Struts2拦截器的讲解博客:Struts2拦截器详解

一、拦截器的概述

拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问前,进行拦截,然后在之前或在之后加入某些操作。拦截是AOP的一种实现策略。现实开发中有很多的应用场景,比如:用户登录检查、登录日志记录以及权限检查等等。

Struts2的执行流程如下图:

拦截器是一种可以在让用户在Action执行之前和Result执行之后进行一些功能处理的机制。 而且拦截器在action执行之前和result执行之后的顺序是相反的,即:Interceptor1—Interceptor2—Interceptor3—Action—Result–Interceptor3—-Interceptor2—-Interceptor1。

struts2里面封装的功能都是在拦截器里面。有很多拦截器,但不是每次这些拦截器都执行,每次执行默认的拦截器。

Struts2里面默认的拦截器位置:struts2-core-2.xxxx.jar—->struts-default.xml,在这里面配置了很多的拦截器,但是只执行默认配置的那些拦截器。

拦截器链,又叫拦截器栈,就是将拦截器按照一定的顺序联

二、拦截器的原理

大部分时候,拦截器方法都是通过代理的方式来调用的。当请求到达Struts2的ServletDiapatcher时,Struts2会查找配置文件,并根据其配置实例化相应的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。另外,Struts2中的拦截器都是可插拔的。

三、自定义拦截器

方法一:实现Interceptor接口

com.opensymphony.xwork2.interceptor.Interceptor接口的代码如下:

public interface Interceptor extends Serializable{
    void init();
    void destroy();
    String intercept(ActionInvocation invocation)throws Exception; 
}

可以看出来,该接口提供了三个方法,具体介绍如下:

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

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

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

方法二:继承AbstractInterceptor类(常用,更简单一点)

除了实现Interceptor接口外,实际开发中更常用的是继承抽象拦截器类:AbstractInterceptor。该类实现了Interceptor接口,并且提供了init()和destroy()方法的空实现。使用时可以直接继承该抽象类,而不用实现那些不必要的方法。

public abstract class AbstractInterceptor implements Interceptor{
    public void init(){}
    public void destroy(){}
    public abstract String intercept(ActionInvocation invocation) throws Exception; 
}

四、拦截器的配置

拦截器的配置是在struts.xml文件中完成的,它通过<interceptor>标签开头。

1、拦截器的配置

<interceptor name="interceptorName" class="interceptorClass">
    <param name="paramName">paramValue</param>
</interceptor>

name属性用来指定拦截器的名称,class属性用来指定拦截器的实现类。有时定义拦截器需要传入参数,这时需要使用<param>标签,其中name属性用来指定参数的名称,paramValue表示参数的值。

2、拦截器栈的配置

在实际开发中,经常需要在Action执行前同时执行多个拦截器动作,如:用户登录检查、登录日志记录以及权限检查等,这时,可以把多个拦截器组成一个拦截器栈。在使用时,可以将栈内的多个拦截器当成一个整体来引用。当拦截器栈被附加到一个Action上时,在执行Action之前必须先执行拦截器栈中的每一个拦截器。

定义拦截器栈使用<interceptors>元素和<interceptor-stack>子元素,当配置多个拦截器时,需要使用<interceptor-ref>元素来指定多个拦截器,配置语法如下:

<interceptors>
    <interceptor-stack name="interceptorStackName">
        <interceptor-ref name="interceptorName1"/>
        <interceptor-ref name="interceptorName1"/>
        ...
    </interceptor-stack>
</interceptors>

在上述语法中,interceptorStackName值表示配置的拦截器栈的名称,interceptorName表示拦截器的名称。另外,在一个拦截器栈中还可以包含其他拦截器栈,配置语法如下:

<package name="default" extends="struts-default" namespace="/">
    <!-- 声明拦截器 -->
    <interceptors>
        <interceptor name="interceptor1" class="interceptorClass">
        <interceptor name="interceptor2" class="interceptorClass">
        <!-- 定义一个拦截器栈myStack,该拦截器栈中包含两个拦截器和一个拦截器栈 -->
        <interceptor-stack name="myStack">
            <!-- defaultStack这个内置的拦截器栈是必须要引入的 -->
            <interceptor-ref name="defaultStack"/>
            <interceptor-ref name="interceptor1"/>
            <interceptor-ref name="interceptor2"/>
        </interceptor-stack>
    </interceptors>
</package>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值