• (转)Struts 拦截器


    一、拦截器是怎么实现: 

    实际上它是用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方法。否则容易造成死循环。

  • 相关阅读:
    .IllegalArgumentException: Mapped Statements collection does not contain 异常一例【我】
    Spring配置文件里加载路径中的通配符
    线程池使用Callable示例【我】
    使用Callable和Future接口创建线程
    Java线程池(Callable+Future模式)
    集合切割
    draw call 理解和优化
    Unity 3d导入3dMax模型 产生若干问题
    3dmax做的模型导入U3d后 当模型靠近摄像机时镂空问题
    不管多少个空格替换为一个空格
  • 原文地址:https://www.cnblogs.com/zuiyirenjian/p/3980381.html
Copyright © 2020-2023  润新知