zoukankan      html  css  js  c++  java
  • SSH学习-拦截器的使用

    与Spring类似,Struts2也有拦截器Interceptor,拦截器是java动态拦截action请求的对象,其可以复用,扩展,适合封装通用的处理。下面将学习拦截器作用的时机,以及如何使用拦截器,做简单的记录。

    拦截器作用时机

    浏览器发送请求到服务端,正常会经历如下几步:浏览器发送请求→filter处理→action处理→result→返回浏览器。

    加上拦截器后的过程:浏览器发送请求→filter处理→拦截器处理→action处理→拦截器处理→result→返回浏览器。

    也就是说正常的访问过程,浏览器发送请求后,filter先进行处理,并读取struts.xml配置文件,进行action具体路径的匹配并处理,最后将结果返回给浏览器。如果加上拦截器,相当如filter接受到请求到转发给具体action处理前,先调用拦截器进行处理,处理完成后再交给action进行处理,然后action处理完请求后,拦截器再进行一次拦截处理,最后再将结果返回给result进行处理,返回给浏览器。

    拦截器的使用

    拦截器的使用基本就是三步:创建拦截器,注册拦截器,引用拦截器,接下来以一个简单的案例,说明如何使用拦截器。案例在SSH02的基础上进行,基本的Struts2+Spring的配置省略。

    (1)创建拦截器,需要创建一个拦截器类,并实现Interceptor接口,其中invocation.invoke()方法起到放行的作用,如果拦截器逻辑执行完能到这里,就将执行接下来的action请求对应的逻辑。

    package Controller;
    
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Controller;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.Interceptor;
    
    /**
     * 自定义拦截器,实现简单的拦截*/
    @Controller("demoInterceptor")
    @Scope("prototype")
    public class demoInterceptor implements Interceptor{
    
        public void destroy() {
            System.out.println("拦截器销毁了");
            
        }
    
        public void init() {
            System.out.println("拦截器初始化了");
            
        }
        
        //拦截逻辑写在这里
        public String intercept(ActionInvocation invocation) throws Exception {
            System.out.println("开始拦截");
            
            invocation.invoke();//action请求放行
            
            System.out.println("结束拦截");
            return null;
        }
    
    }

    (2)注册拦截器

    在package标签下,action标签前,注册拦截器,其中可以注册多个拦截器,name属性对应注册的拦截器名,class属性对应拦截器处理类。其中myInterceptor就是这次注册的拦截器名,其实现类为上面创建的demoInterceptor。

      <package name="demo" namespace="/hello" extends="struts-default">
        <!-- 添加自定义拦截器 -->
        <!-- 注册拦截器 -->
        <interceptors>
           <interceptor name="myInterceptor" class="demoInterceptor"></interceptor>
        </interceptors>
        <action name="helloStruts" class="helloStruts"> 
           <result name="success">
             /WEB-INF/helloStruts.jsp
           </result>
        </action>
      </package>

    (3)引用拦截器

    在action标签下,引用注册的拦截器,name属性值就是注册的拦截器名称。其中name属性值就是上面注册的拦截器名myInterceptor。补充引用拦截器配置后,上面的配置变成如下。

      <package name="demo" namespace="/hello" extends="struts-default">
        <!-- 添加自定义拦截器 -->
        <!-- 注册拦截器 -->
        <interceptors>
           <interceptor name="myInterceptor" class="demoInterceptor"></interceptor>
        </interceptors>
        <action name="helloStruts" class="helloStruts"> 
           <result name="success">
             /WEB-INF/helloStruts.jsp
           </result>
           <!-- 引用拦截器 -->
           <interceptor-ref name="myInterceptor"></interceptor-ref>
        </action>
      </package>

    部署测试结果

    Interceptor初始化

    在action逻辑处理前后执行了开始拦截和结束拦截

    浏览器输出结果

    测试结果说明拦截器按照上面说的正常执行了。

    拦截器栈失效问题

    如果不配置拦截器,框架会默认调用自己的拦截器,其在struts-default.xml中有配置,然后消息传递的数据也是拦截器进行处理的。如果引用了自己定义的拦截器,按照如上配置的话,系统默认的拦截器栈将撤销,导致部分功能不可以用,如消息传递机制失效,下面使用SSH01中的登录功能,配置自定义拦截器进行测试。

    (1)struts-default.xml中定义的拦截器栈

    (2)在登录验证中配置拦截器

      <!-- 登录,提交用户名和密码,采用基本属性提交方式 -->
      <package name="login" namespace="/login" extends="struts-default">
        <!-- 注册自定义拦截器,消息传递机制失效测试 -->
        <interceptors>
          <interceptor name="myInterceptor" class="com.boe.Filter.demoInterceptor"></interceptor>
        </interceptors>
        <!-- 进入登录页面,没有业务逻辑处理 -->
        <action name="toLogin">
          <result name="success">
            /WEB-INF/login.jsp
          </result>
        </action> 
        <!-- 验证用户名和密码 -->
        <action name="login" class="com.boe.Filter.Login">
          <result name="success">
            /WEB-INF/msg.jsp
          </result>
          <!-- 引入自定义拦截器 -->
          <interceptor-ref name="myInterceptor"></interceptor-ref>
        </action>
      </package>

    (3)登录验证

    测试发现,action方法中打印用户名和密码得到的结果都为null,说明没有获取到浏览器发送的数据。

    拦截器栈失效问题解决方法

    如果想同时实现系统默认的拦截器,以及自己定义的拦截器,需要定义一个拦截器栈,里面引入系统默认的拦截器栈,以及自己定义的拦截器。下面在域模型传递方式中,配置拦截器栈,并测试。

    (1)在登录中配置拦截器栈

      <!-- 登录,使用域模型传递方式 -->
      <package name="loginWithEntity" namespace="/loginWithEntity" extends="struts-default">
        <!-- 注册拦截器,并创建interceptor-stack,既导入自己写的拦截器也导入框架默认的拦截器栈 -->
        <interceptors>
          <!-- 自定义拦截器 -->
          <interceptor name="myInterceptor" class="com.boe.Filter.demoInterceptor"></interceptor>
          <interceptor-stack name="myInterceptorStack">
              <!-- 引入自己定义的拦截器和框架默认的 -->
              <interceptor-ref name="myInterceptor"></interceptor-ref>
              <interceptor-ref name="defaultStack"></interceptor-ref>
          </interceptor-stack>
        </interceptors>
        <!-- 进入登录页面 -->
        <action name="toLogin">
          <result name="success">
            /WEB-INF/loginWithEntity.jsp
          </result>
        </action>
        <!-- 登录验证 -->
        <action name="login" class="com.boe.Filter.LoginWithEntity">   
          <result name="success">
            /WEB-INF/msg.jsp
          </result> 
          <!-- 引入自己定义的拦截器栈 -->
          <interceptor-ref name="myInterceptorStack"></interceptor-ref>
        </action>
      </package>

    (2)登录验证

    测试发现配置自定义拦截器栈,并引入自定义的拦截器,以及框架默认的拦截器栈后,数据传递机制生效。说明框架默认的拦截器有获取数据的功能。其中自定义拦截器栈和拦截器标签名是同级关系。

    结论

    (1)Struts2的拦截器会作用于action请求开始前和结束后,其可以复用,扩展。

    (2)拦截器的配置按照三步走:创建拦截器,注册拦截器和引入拦截器。

    (3)配置自定义拦截器会有导致框架默认拦截器栈功能撤销的可能,如果想同时实现自定义拦截器和框架默认拦截器栈的功能,需将两者配置到自定义拦截器栈中,并在action引入后才能都生效。

  • 相关阅读:
    bzoj 1208: [HNOI2004]宠物收养所 (Treap)
    Bzoj 2431: [HAOI2009]逆序对数列 (DP)
    Bzoj 1055: [HAOI2008]玩具取名 (区间DP)
    线段树入门详解
    Bzoj 1087: [SCOI2005]互不侵犯King
    Bzoj 2748: [HAOI2012]音量调节 (DP)
    Bzoj 2752 高速公路 (期望,线段树)
    惨淡的模拟赛
    GSS4
    Bzoj 近期题目一句话题解
  • 原文地址:https://www.cnblogs.com/youngchaolin/p/10879344.html
Copyright © 2011-2022 走看看