zoukankan      html  css  js  c++  java
  • struts2 拦截器【转】

    看了浪曦的STRUTS2的视频之后,才发现拦截器是多么滴好用,以下是转载内容:
    拦截器的作用主要就是拦截东西,拦截什么呢?当然是'action'了,在执行'action'之前 拦截器会起作用,执行一些预先处理的代码,
    接着区执行action中相关的方法,之后,流程又会回到拦截器里面,接着去执行后续的一些操作。

    先看配置,这些配置都是在struts.xml里面的。配置相当简单,不过底层都是很复杂的。在这章之前,我专门看了下动态代理,感觉真的是开发者花了不少的心血,

    首先先建一个包,放我们的interceptor。
    过滤器和拦截器是非常相似的,public interface Filter类里面有三个方法:
    init(FilterConfig filterConfig),destroy(),doFilter(ServletRequest request,ServletResponse response,FilterChain chain),
    这里面的doFilter()方法是最重要的,在struts2中就相当于拦截的那个方法。

    先写一个拦截器,在struts2中要实现一个接口 这个接口是什么呢?在哪呢?是webwork是我们以前听的最多的关于拦截器的框架,
    struts2用了其中一个核心的东西,这个东西在是什么呢?是xwork恩,有了它才可以拦截,好了我们在哪找呢?
    在com.opensymphony.xwork2.interceptor中找,里面有个Interceptor 这是个接口,里面也有三个方法,
    有init,destroy和intercept三个方法,而在struts2里面的所有的拦截器都继承这个接口!

    就依照这个接口写一个拦截器类,呵呵!
    package com.interceptor;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.Interceptor;

    public class MyInterceptor implements Interceptor{
        private String hello;//一定要写
        get和set方法
        public void destroy() {
           System.out.println("destory");
        }
        public void init() {
           System.out.println("init");
        }
        public String intercept(ActionInvocation invoker) throws Exception {
           System.out.println("intercept");
           String result=invoker.invoke();
        //  System.out.println("finish1");
           return result;
        }
    }

    为了看这些是怎么实现的,加入了一些打印!
    Intercept方法返回一个字符串,这个里面最重要的是ActionInvocation 也是个抽象的接口,里面有个invoke() 方法
              作用:Invokes the next step in processing this ActionInvocation. 即调用下一个拦截器,如果有的话!
    为了,让struts2知道我们写了个拦截器,就在struts。Xml中配置一下。
    <package name="struts2" extends="struts-default">
    <interceptors>
       <interceptor name="myinterceptor" class="com.interceptor.MyInterceptor">
                  <param name="hello">world</param>
               </interceptor>
    </interceptors>

    注释:action是写的一个注册页面,也可以随便用个action 在这个点上是不影响需要检验结果的

    <action name="register" class="com.test.action.RegisterAction" >
               <result name="input">/register.jsp</result>
               <result name="success">/success.jsp</result>
    </package>

    好了到了这里 拦截器也配置好了,但是拦截器是拦截action的,怎么才能让action被拦截呢?
    一般的情况下,放在result后面 怎么写呢?好了,如下:
    <interceptor-ref name="myinterceptor">
    </interceptor-ref>

    这样就可以让aciton被拦截了,到此,好了,可以运行程序了:
    输出结果是:启动服务器init被打出
    运行后提交action 输出intercept
    这个就是初步的一个拦截器。



    =======在此可能出现一个问题,是什么呢?如果就我们做的登陆而言,当然登陆大家都做的很多了,可以想一下,有数据转换,有验证数据是否符合我们的要求====

    Ok 如果按照上述运行的话,当数据转换,验证出错的时候,就不会有提示,为什么呢? 这里就和struts2的默认拦截器有关系!

    这里可以打开一个文件看一下,看了就会明白,是什么文件呢?struts-default。Xml
    这里定义的很多的东西,和我们的程序相关的非常紧密
    首先这里有个
    <package name="struts-default" abstract="true">和struts.Xml里面的
    <package name="struts2" extends="struts-default">有什么一样呢?很明显可以猜到struts.Xml中继承的就是default。Xml中的struts-default。
    这个里面还有个<interceptors>和</interceptors>这个是定义拦截器的,仔细看可以发现里面有个validation 如此可以猜想,
    validation 也是定义的一个拦截器,可是最后当登陆出错后没有提示信息呢?肯定是相关的东西没有执行,以前的执行了,现在没执行,
    在新加了个拦截器后,这样说明了,是现有的拦截器取代了原有的拦截器,这个是我仅能想到的!结果就是这个样子的。那么我们手工吧把原来的默认拦截器加入,这样可以吗?
    答案是可以的!添加如下!

    接着上面result后面添加一个把!
    <interceptor-ref name="defaultStack"></interceptor-ref>

    这样还可以说明:如果我们没有添加拦截器的话,默认的拦截器会自动添加到里面。


    拦截器栈
    过滤器可以组成过滤器链,就是可以有多个过滤器来去过滤一个组件,拦截器也是,只不过是叫拦截器栈(相当于串拦截器)。
    拦截器栈先把拦截器逐个执行,接着执行action方法,之后又按照相反的顺序回到最后的一个拦截器,再回到视图。

    拦截器栈是怎么构成的呢?继续看struts-default.Xml这个文件!里面有这些东西:
                <interceptor-stack name="defaultStack">
                    <interceptor-ref name="static-params"/>
                    <interceptor-ref name="params"/>
                    <interceptor-ref name="conversionError"/>
                </interceptor-stack>

      <interceptor-stack name="validationWorkflowStack">
                    <interceptor-ref name="defaultStack"/>
                    <interceptor-ref name="validation"/>
                    <interceptor-ref name="workflow"/>
               </interceptor-stack>

    这里面看见了 栈是什么样的结构,是由很多个预先定义好的拦截器构成,而且也可以再加上拦截器栈组成,就如此就组成了!



    还有这行代码:
    <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
    这个是定义默认的拦截器,竟然是默认的当然只可能有一个!是把!

    好了,到了这里,就来有进一步学习struts2的拦截器把!让我们自己配置自己的拦截器栈!
    在开始 的时候我们添加的第一个myinterceptor拦截器的时候我添加了一个参数

    <param name="hello">world</param> 这里我们可以通过配置文件,给拦截器添加一个参数,那这个在拦截器中怎么取得的呢?
    了解过滤器的朋友都知道,里面有个init(FilterConfig filterConfig)方法这样可以取值,而在struts2中没有这么麻烦,做法吗,
    上面其实已经给出来了!
    private String hello;
        get和set方法

    写个变量,然后加上get和set方法,当然变量的名字必须和设定的参数是相同的,这个是赋值成功的前提条件

    此时,运行,成功输出:world   这里的参数使用是在定义拦截器的时候,还有一种是在使用拦截器的时候添加参数。怎么做呢?

    定义拦截器的情况:

    <interceptor name="myinterceptor" class="com.interceptor.MyInterceptor">
                  <param name="hello">world</param>
    </interceptor>

    使用拦截器的时候的情况:
    <interceptor-ref name="myinterceptor">
                  <param name="hello">zhuxinyu</param>
    </interceptor-ref>

    这下知道了吗,还有,当出现如上引用的时候给同样的参数设置了不同的值,会显示那一个呢,在运行的时候?
    结果是:zhuxinyu  很明显 覆盖了第一个  结论是:使用的时候比定义的时候更加厉害,这叫撒,县官不如现管!
    好了,把这些零散的东西搞完了,真的开始解决更多的知识!

    拦截器栈,在struts2里面,其实是把拦截器和拦截器栈一样的对待。可以把拦截器栈当作一个拦截器看待,同样的引用。
    现在定义一个拦截器栈把!

    同样在<interceptors> </interceptors>里面定义

    <interceptor-stack name="mystack">
               <interceptor-ref name="myinterceptor"></interceptor-ref>
               <interceptor-ref name="defaultStack"></interceptor-ref>
    </interceptor-stack>

    看见了没,一个引用第一次定义的myinterceptor拦截器,一个引用默认的拦截器,怎么引用呢,和开始的一个样,呵呵!

    <interceptor-ref name=" mystack ">
    </interceptor-ref>

    呵呵 ,这样看是不是比刚才简单呢?把两次引用换成一次!运行结果呢?和上次一样,而且都成功!

    当然我们也可以自己定义一个默认的拦截器,这样在程序中怎么做呢?呵呵,定义如下
    <default-interceptor-ref name="mystack"></default-interceptor-ref>
    这里引用的就是上面的mystack拦截器,这样在程序中如果不在action中加入拦截器,它同样可以执行相应的工作,
    前面已经说过了,如果不加入任何拦截器的引用,它将把默认的拦截器加入。


    我们在做拦截器的时候,刚才实现了Interceptor接口,里面有三个方法,但是一般的情况下init()和destroy()方法我们用不上,
    最关心的就是intercept(ActionInvocation invoker){}方法,所以怎么办呢?其实,struts2给我们提供了一个简化的拦截器类,这个是什么呢?

    MethodFilterInterceptor  这是一个抽象的类,里面实现了init()和destroy()方法,所以只要我们继承这个类,就不用再多写这两个方法!

    为了验证是对的,就写了个方法,实现如下:

    public class MyInterceptor2 extends AbstractInterceptor{
      protected String doIntercept(ActionInvocation invocation) throws Exception {
           System.out.println("my interceptor2");
           String result=invocation.invoke();
           return result;
        }
    }

    就是这样一个简单的东西,呵呵,把它和其他的拦截器一样的配置,运行,呵呵就可以出来结果了!
    当然在这里还需要指出一点,你安放的拦截器的顺序,其实也就是拦截器执行的顺序!但是拦截器,不只是在执行execute()方法之前要执行,
    而且在execute()方法之后也要执行。给出如下两个拦截器说明:

    1
    public String intercept(ActionInvocation invoker) throws Exception {
           System.out.println("intercept1");
           String result=invoker.invoke();
           System.out.println("finish1");
           return result;
        }

    2

    public String intercept(ActionInvocation invoker) throws Exception {
           System.out.println("intercept2");
           String result=invoker.invoke();
           System.out.println("finish2");
           return result;
        }

    在配置顺序也是一二,结果会输出什么呢?

    intercept1  intercept2 finish2  finish1  这里执行拦截器的过程是正着来的,回来的时候是反着的。就像你要进一个很多门的房间一样。
    进去一个,开一个门,为了让自己能回来的方便一些,这个打开的门就不要关着了,当你把所有的门进去了后,然后回来,再逐个关门。
    这样的过程就像是这个拦截器执行的过程。

    最后讲一个方法过滤拦截器,顾名思义,过滤的是方法。其实在struts2中可以在一个action类中写很多个与aciton的execute方法类似的方法。
    只要在struts。Xml中的action添加一个属性就可以了这个属性是method比如:

    <action name="register"class="com.test.action.RegisterAction" method="test">当然在action类中也有个test()方法

    这个拦截器可以细化到拦截到具体的哪一个方法。如果不是方法过滤拦截器 哪么它可能将与execute()方法类似的方法都执行。
    比如说上面的test()方法。如此这样照成很多的不必要。于是这种拦截器就显的格外的重要。
    在这个类继承后实现的不是inteceptor()方法而是doIntercept(),可是做好这个类后如何配置继承MethodFilterInterceptor这个类呢?
    如下(为了实现过滤方法加入了几个参数,其他的都相同):

    <interceptor-ref name="myinterceptor2">
                  <param name="includeMethods">execute,test</param>
    </interceptor-ref>

    includeMethods  包含execute,test这两个方法,结果执行了这个拦截器,如果改成excludeMethods ,就不会执行了,也可以再加下面的一个参数
    <param name="excludeMethods">execute,test</param>
    不排除execute,test这两个方法 可是又加入又排除到底执行吗?答案是执行的,必定结果是最能说明问题的!呵呵!

  • 相关阅读:
    HDU 4472 Count DP题
    HDU 1878 欧拉回路 图论
    CSUST 1503 ZZ买衣服
    HDU 2085 核反应堆
    HDU 1029 Ignatius and the Princess IV
    UVa 11462 Age Sort
    UVa 11384
    UVa 11210
    LA 3401
    解决学一会儿累了的问题
  • 原文地址:https://www.cnblogs.com/pond/p/5330728.html
Copyright © 2011-2022 走看看