zoukankan      html  css  js  c++  java
  • struts2拦截器+监听器 .

    一、拦截器是怎么实现:

    实际上它是用Java中的动态代理来实现的

    二、拦截器在Struts2中的应用
    对于Struts2框架而言,正是大量的内置拦截器完成了大部分操作。像params拦截器将http请求中参数解析出来赋值给Action中对应的属性。Servlet-config拦截器负责把请求中HttpServletRequest实例和HttpServletResponse实例传递给Action……struts2内置的拦截器有很多,在此我就不一一列举了。

    那么怎么在struts2中定义自己的拦截器呢?

    很简单Struts2为我们提供了一个Interceptor接口,该接口源代码如下:

    publicinterface Interceptor extends Serializable {

        void destroy();

        void init();

        String intercept(ActionInvocation invocation) throws Exception;

    }

    1)    init():在拦截器执行之前调用,主要用于初始化系统资源。

    2)    destroty():与init()对应,用于拦截器执行之后销毁资源。

    3)    intercept():拦截器的核心方法,实现具体的拦截操作。与action一样,该方法也返回一个字符串作为逻辑视图。如果拦截器成功调用了 action,则返回一个真正的,也就是该action中execute()方法返回的逻辑视图,反之,则返回一个自定义的逻辑视图。

    通常我们使用拦截器并不需要申请资源,为此Struts2还为我们提供了一个AbstractInterceptor类,该类的init()和destroy()都是空实现。我们开发自己的拦截器只需要继承这个类就行了。

    下面创建一个判断用户是否登录的拦截器。代码如下:

    import java.util.Map;
    import com.opensymphony.xwork2.Action;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

    @SuppressWarnings("serial")
    public class CheckLoginInterceptor extends AbstractInterceptor {

        @SuppressWarnings("unchecked")
        public String intercept(ActionInvocation actionInvocation) throws Exception {
             System.out.println("begin check login interceptor!");

                // 检查Session中是否存在user

                Map session = actionInvocation.getInvocationContext().getSession();

                String username = (String) session.get("user");

                if (username != null && username.length() > 0) {

                    // 存在的情况下进行后续操作。

                    System.out.println("already login!");

                    return actionInvocation.invoke();

                } else {

                    // 否则终止后续操作,返回LOGIN

                    System.out.println("no login, forward login page!");

                    return Action.LOGIN;

                }
            }
        }


    创建好拦截器后,还不能使用,还需要我们在struts.xml中配置一下。

    下面看一下怎么配置拦截器。

    <interceptors>

               <interceptor name="checkLogin" class="com.myblog.interceptor.CheckLoginInterceptor" />

    </interceptors>

    这个定义好的拦截器在Action中怎么使用呢?使用方法很简单,如下:

    <action name=" " class=" " >

               <result> </result>

               <interceptor-ref name="checkLogin" />

    </action>

    一旦我们为某个action引用了自定义的拦截器,struts2默认的拦截器就不会再起作用,因此还需要引用默认拦截器。

    <action name=" " class=" " >

               <result> </result>

               <interceptor-ref name="checkLogin" />

                         <interceptor-ref name="defaultStack" />

    </action>

    但是我们这么做似乎也不太方便,因为如果拦截器checkLogin需要被多个action引用的话,每一个都要配置一遍太麻烦了。我们可以把它定义成默认的拦截器。

    <interceptors>

               <interceptor name="checkLogin" class="com.myblog.interceptor.CheckLoginInterceptor" />

               <!—-定义一个拦截器栈-->
               <interceptor-stack name="mydefault">

                  <interceptor-ref name="defaultStack" />

                  <interceptor-ref name="checkLogin" />

               </interceptor-stack>

    </interceptors>

    <default-interceptor-ref name="mydefault" />

    参数问题:即<param../>的使用:

    系统为拦截器指定参数有两个时机:

    1.定义拦截器时指定参数值(通过<interceptor .../>元素来定义拦截器,参数就是它下面的<param name="参数">参数值</param>):这种参数值是拦截器这个参数的默认数值。

    2.使用拦截器时指定参数值(通过<interceptor-ref.../>元素来使用拦截器参数就是它下面的<param name="参数">参数值</param>):这种参数值是当在Action中使用该拦截器时动态分配的参数值。


    无论在哪里里面配置,他的值都是传给拦截器类。


    另外,struts2还为我们提供了一个方法过滤的拦截器MethodFilterInterceptor类,该类继承 AbstractInterceptor类,重写了intercept(ActionInvocation invocation)并提供了一个新的方法doInterceptor(ActionInvocation invocation)抽象方法。该类的使用方法很简单,跟上例类似,就不举例了。这个拦截器与以往的拦截器配置有所不同。那就是可以指定哪些方法需要被拦截,那些不需要。通常在引用该拦截器时指定。


    <interceptor-ref name="  ">

           <param name="exculdeMethods"></param>

           <param name="includeMethods"></param>   

    </interceptor-ref>

    exculdeMethods:是不被拦截的方法,如果有多个以逗号分隔。
    includeMethods:需要被拦截的方法,如果有多个以逗号分隔。


    上面两个参数,在MethodFilterInterceptor类中都有对应的方法。

    如果一个方法同时在这两个方法中列出,则该方法会被拦截。



    struts2中提供了这种方法过滤的拦截器有如下几个:

    1.TokenInterceptor

    2.TokenSessionStoreInterceptor

    3.DefaultWorkflowInterceptor

    4.ValudationInterceptor



    三、覆盖特定拦截器的参数

    <拦截器名>.<参数名>



    <interceptor-ref name="my-stack">

        <!--second为拦截器名,name为参数名-->

        <param name="second.name">改名后的拦截器</param>

    </interceptor-ref>


    四、拦截结果的监听器

      实现拦截结果的监听器首先必须现实com.opensymphony.xwork2.interceptor.PreResultListener类
    并重写里面的方法beforeResult :


    public class MyListener implements PreResultListener {   

        public void beforeResult(ActionInvocation invocation, String resultCode) {   

            System.out.println(resultCode);   

        }  

    }

    参数介绍:

    1.虽然beforeResult方法也获得ActionInvocation类型的参数,但通过这个参数来控制Action的作用已经不再明显--因为Action的execute方法已经执行结束了。

    2.resultCode,这个参数就是被拦截Action的execute方法的返回值。


    然后再在拦截器里面调用

    invocation.addPreResultListener(new MyListener());

    拦截器结果监听器是在系统处理Result之前,在execute之后执行的。


    注意:不要在PreResultListener监听器的beforeResult方法中通过ActionInvocation参数调用invoke方法。否则容易造成死循环。

  • 相关阅读:
    开源的UML建模工具
    leetcode 559. Maximum Depth of N-ary Tree
    leetcode 9. Palindrome Number
    暗网 tor溯源困难根因——用户的请求会在分布全球的主机随机跳转三次,最终才到达服务器,这就造成了溯源的极其困难
    leetcode 374. Guess Number Higher or Lower
    RDP协议暴力破解
    清华大学 pip 源
    暴力破解研究论文
    利用ModSecurity防御暴力破解
    IRC BOT原来是利用IRC下发C&C命令——在xx云环境遇到了,恶意软件开的是6666端口
  • 原文地址:https://www.cnblogs.com/gexiaoshan/p/3303097.html
Copyright © 2011-2022 走看看