美文网首页
SSH框架之Struts2的拦截器(四)

SSH框架之Struts2的拦截器(四)

作者: Seapp | 来源:发表于2019-04-15 16:40 被阅读0次

    第一节:Struts2的拦截器

    1.1 拦截器的概述:

    拦截器,在AOP(Aspect - Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。
    在WebWork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一些机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个Action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。
    谈到拦截器,还有一个词——拦截器链(Interceptor Chain,在Struts2中称为拦截栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

    1.2 拦截器的实现原理:

    拦截器方法都是通过代理的方式来调用的。当请求送达Struts2的ServletDispatcher时,Struts2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。
    Struts2拦截器是可插拔的,拦截器是AOP的一种实现。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。

    1.3 拦截器的执行流程

    1.4 自定义拦截器

    若需要实现拦截器类,就需要直接或间接的实现com.opensymphony.xwork2.interceptor接口,其接口定义代码如下:

    import com.opensymphony.xwork2.ActionInvocation;
    import java.io.Serializable;
    
    public interface Interceptor extends Serializable {
        void destroy();
    
        void init();
    
        String intercept(ActionInvocation var1) throws Exception;
    }
    

    该接口提供了三个方法,其具体介绍如下:

    • void init():该方法在拦截器被创建后会立即被调用,它在拦截器的生命周期内只被调用一次,可以在该方法中对相关资源进行必要的初始。
    • void destroy():该方法与init方法相对应,在拦截器被销毁之前,将调用该方法来释放和拦截器相关的资源。它在拦截器的生命周期内,也只被调用一次。
    • String intercept(ActionInvocation invocation)throws Exception:该方法是拦截器的核心方法,用来添加真正执行拦截工作的代码,实现具体的拦截操作。它返回一个字符串作为逻辑视图,系统根据返回的字符串跳转到对应的视图资源。每拦截一个动作请求,该方法都会被调用一次。该方法的ActionInvocation参数包含了被拦截Action的引用,可以通过该参数的invoke()方法,将控制权给下一个拦截器或者转给Action的execute()方法。
      如果需要自定义拦截器,只需要实现Interceptor接口的三个方法即可。然而在实际的开发中,除了实现Interceptor接口可以自定义拦截器外,更常用的一种方式是继承抽象拦截器类AbstracIntercepter。该类实现了Interceptor接口,并且提供了init()方法和destory()方法的空实现。使用时,可以继承该抽象类,而不用实现那些不必要的方法。拦截器类AbstractInterceptor中定义的方法如下所示:
    public abstract class AbstractInterceptor implements Interceptor {
        public AbstractInterceptor() {
        }
    
        public void init() {
        }
    
        public void destroy() {
        }
    
        public abstract String intercept(ActionInvocation var1) throws Exception;
    }
    

    从上述代码中可以看出,AbstractInterceptor类已经实现了Interceptor接口的所有方法,一般情况下,只需继承AbstractInterceptor类,实现interceptor()方法就可以创建自定义拦截器。
    只有当自定义的拦截器需要打开系统资源时,才需要覆盖AbstracInterceptor类的init()方法和destroy()方法。与实现Interceptor接口相比,继承AbstractInterceptor类的方法更为简单。

    1.5 拦截器的配置

    • 拦截器
      要想让拦截器起作用,首先要对它进行配置。拦截器的配置是在struts.xml文件中完成的,它通常以<interceptor>标签开头,以</interceptor>标签结束。定义拦截器的语法格式如下:
     <interceptors>
                <interceptor name="interceptorDemo01" class="com.seapp.struts2.interceptor.MyInterceptor02">
                    <param name="paramName">paramValue</param>
                </interceptor>
            </interceptors>
    

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

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

    在上述的语法中,interceptorStackName值表示配置的拦截器的名称;interceptorName值表示拦截器的名称。除此之外,在一个拦截器栈中还可以包含另一个拦截器栈,示例代码如下:

    <interceptors>
                <!--声明拦截器-->
                <interceptor name="interceptor" class="com.seapp.struts2.interceptor.MyInterceptor">
                    
                </interceptor>
                
                <interceptor name="interceptorDemo01" class="com.seapp.struts2.interceptor.MyInterceptor02">
                    <param name="paramName">paramValue</param>
                </interceptor>
                <!--定义一个拦截器栈myStack,该拦截器栈中包含两个拦截器和一个拦截器栈-->
                <interceptor-stack name="myStack">
                    <interceptor-ref name="defaultStack"/>
                    <interceptor-ref name="interceptor"/>
                    <interceptor-ref name="interceptorDemo01"/>
                </interceptor-stack>
                
            </interceptors>
    

    在上述代码中,定义的拦截器栈是myStack,在myStack栈中,除了引用了两个自定义的拦截器interceptor和interceptorDemo01外,还引用了一个内置拦截器栈defaultStack,这个拦截器是必须要引入的。

    相关文章

      网友评论

          本文标题:SSH框架之Struts2的拦截器(四)

          本文链接:https://www.haomeiwen.com/subject/oxeuwqtx.html