• 31.自定义拦截器


    转自:https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html

    自定义拦截器需要特别注意的是不要忘记引入struts2默认的拦截器。为了实现某些操作,我们可以自定义拦截器,自定义拦截器有三种方式定义。分别为实现Interceptor接口,继承抽象类AbstractInterceptor,继承MethodFilterInteceptor类。

    方式一,实现Interceptor接口。重写String intercept(ActionInvocation invocation)方法。

    准备工作,新建struts2interceptor项目。构建一个登录环境:当我们点登录链接时,便成功登录(为了方便,这里不进行验证)。即在link.jsp页面中写如下链接:<a href="<%=request.getContextPath()%>/login.action">登录</a> 然后,我们点击此链接便可以登录。login.action在strutst.xml中的的配置如下:
    <package name="interceptor"  extends="struts-default">
        <action name="login" class="com.asm.LoginAction">

                         <result name="success">/success.jsp</result>

    </action>
    </package>
    com.asm.LoginAction为了简单,com.asm.LoginAction总是返回SUCCESS;这样请求这个Action总会返回到.../success.jsp页面。
    编写拦截器:MyInterceptor类,内容如下:
    package com.asm;

    import com.opensymphony.xwork2.ActionInvocation;

    import com.opensymphony.xwork2.interceptor.Interceptor;

    public class MyInterceptor implements Interceptor {

           public void destroy() {

           }

           public void init() {

           }

           public String intercept(ActionInvocation invocation) throws Exception {

                  System.out.println("开始拦截");

                  String result = invocation.invoke();

                  System.out.println("结束拦截");

                  return result;

           }

    }
    为了使用此拦截器,我们必须将此拦截器进行注册,随后再在要使用此拦截器的Action中引用。即首先在<package>中注册,内容如下:
    <interceptors>

           <interceptor name="myIpt" class="com.asm.MyInterceptor"></interceptor>

    </interceptors>

    注册完成后,如果我们要在login.action中使用此拦截器,只需要在<action>中增加如下内容:
    <interceptor-ref name="myIpt"></interceptor-ref>

    这样便成功为LoginAction配置了我们自定义的拦截器MyInterceptor,下面只需发布测试。

    实例流程分析:当我们为LoginAction配置了拦截器时,并且有客户端请求此Action时,会首先被此拦截器拦住,然后执行System.out.println("开始拦截"),随后我们调用invocation.invoke()方法,它会把请求继续传递给下一个拦截器,下一个拦截器也会继续执行相应代码后再调用invoke方法继续传递,直到请求到达最后一个拦截器,它会把请求传递给Action,比如,我们这里只用到了一个拦截器,当它执行完成后,会把请求直接转交到LoginAction处理,LoginAction处理完成后,它会返回结果给MyInterceptor拦截器。

    方式二、继承AbstractInterceptor抽象类,重写String intercept(ActionInvocation invocation)方法

    创建拦截器类MyAbstractInterceptor:主要代码如下:
    package com.asm;
    import com.opensymphony.xwork2.ActionInvocation;

    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

    public class MyAbstractInterceptor extends AbstractInterceptor {

           public String intercept(ActionInvocation invocation) throws Exception {

                  System.out.println("Abs开始拦截");

                  String result = invocation.invoke();

                  System.out.println("Abs结束拦截");

                  return result;

           }

    }

    然后注册此拦截器,在<interceptors>元素进行进行配置,内容如下:
    <interceptor name="myAbs" class="com.asm.MyAbstractInterceptor"></interceptor>

    随后再在LoginAction中引用此拦截器,即在<action name="login" ...>配置如下内容:
    <interceptor-ref name="myAbs"></interceptor-ref> 

    最后发布测试。

    方式三、继承MethodFilterInteceptor类,重写String doIntercept(ActionInvocation invocation) 方法。

    创建拦截器类MyMethodFilterInterceptor,主要代码如下:
    package com.asm;

    import com.opensymphony.xwork2.ActionInvocation;

    import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

    public class MyMethodFilterInterceptor extends MethodFilterInterceptor{

           protected String doIntercept(ActionInvocation invocation) throws Exception {

                  System.out.println("method开始拦截");

                  String result=invocation.invoke();

                  System.out.println("method结束拦截");

                  return result;

           }

    }

    然后注册此拦截器,在<interceptors>元素进行进行配置,内容如下:
    <interceptor name="myMet" class="com.asm.MyMethodFilterInterceptor">
    </interceptor>

    随后再在LoginAction中引用此拦截器,即在<action name="login" ...>配置如下内容:
    <interceptor-ref name="myMet"></interceptor-ref>

    最后发布测试。

    分析:当配置到此,实质便为LoginAction配置了三个拦截器,当我们点击登录时会在控制台打印出如下语句:
    开始拦截

    Abs开始拦截

    method开始拦截

    --先执行拦截器,再执行此Action

    method结束拦截

    Abs结束拦截

    结束拦截
    其实当我们点击登录时,本来是要访问LoginAction,最后会把LoginAction的执行结果传递给访问者。但是当我们配置了拦截器时,当我们去访问Action时,会首先被拦截,随后拦截器执行一些操作后才会继续把请求传递下去。下面作图说明拦截流程:


    结合现实理解:比如我们要去某楼层找某人(LoginAction)取一个资源(LoginAction处理后返回的结果,这里表现为success.jsp),(1)进楼层时会被大门保安拦截检查(第一个拦截器:MyInterceptor拦截器),(2)检查通过后再进电梯时会被电梯保安员检查(第二个拦截器:MyAbstractInterceptor拦截器),(3)检查通过后再上到某楼层会被楼层保安员检查(第三个拦截器:MethodAction拦截器

    ),(4)检查通过后会找到某个(LoginAction),并与某个交谈(LoginAction处理),随后某个人和我们会带着请求的资源出去,(5)出去时,会依次被楼层,电梯,大门保安员检查,最终检查通过。某个人把资源给我们(实质就是返回请求资源给客户端)。 其实拦截器的执行流程和过滤器差不多,所以我们不防用过滤器的眼光来看这些拦截器。
    注意:我们在为LoginAction配置拦截器时,都没使用默认的拦截器,是原因这里的测试可以不用,但是以后在我们使用自定义的拦截器是,一定要加上默认的拦截器,否则会导致许多不可预知的结果。
    补充:从上面的图并结合代码,我们可以看出拦截器的核心过程应该是ActionInvocation对这些拦截器回调处理,下面我们建立com.asm.interceptor.simulation来模拟这一过程,具体的代码参源文件,在此略去。在此我们作图分析ActionInvocation的实现过程:

    补充2:上面分别使用了三种方式来创建自定义的拦截器,第一种方式是最原始的实现方式(实现Interceptor接口),第二种方式的好处是我们可以不必重写所有的方法(继承AbstractInterceptor抽象类),较常用。第三种方式进行了扩展(继承MethodFilterInterceptor类),下面将会展示它的扩展性能。

  • 相关阅读:
    数组指针的一个易错点
    jQuery on()方法
    php 前一天或后一天的日期
    用jQuery监听浏览器窗口的变化
    jquery获取json对象中的key小技巧
    JQuery操作元素的属性与样式及位置
    用JQuery操作元素的style属性
    如何删除jsPlumb连接
    jsPlumb.jsAPI阅读笔记(官方文档翻译)
    Jquery empty() remove() detach() 方法的区别
  • 原文地址:https://www.cnblogs.com/sharpest/p/5587603.html
Copyright © 2020-2023  润新知