zoukankan      html  css  js  c++  java
  • springMVC学习笔记五(拦截器详解)

    ===============================拦截器详解===================================
    类似于servlet中的过滤器filter


    拦截器常见的应用场景
    日志记录
    权限检查
    性能监控
    通用行为
    openSessionInView


    拦截器接口 
    public interface HandlerInterceptor {
      //实现拦截器的预处理
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
       throws Exception;
      //实现处理器的后处理
    void postHandle(
    HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
    throws Exception;
      //请求完毕后的回调方法
    void afterCompletion(
    HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    throws Exception;
    }




    拦载器适配器


    public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
     
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    throws Exception {
    return true;
    }
     
    @Override
    public void postHandle(
    HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
    throws Exception {
    }
     
    @Override
    public void afterCompletion(
    HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    throws Exception {
    }

    @Override
    public void afterConcurrentHandlingStarted(
    HttpServletRequest request, HttpServletResponse response, Object handler)
    throws Exception {
    }
    }






    运行流程
    HandlerInterceptor1.preHandle
    HandlerInterceptor2.preHandle
    handlerAdapter
    HandlerInterceptor2.postHandle
    HandlerInterceptor1.postHandle
    view渲染
    HandlerInterceptor2.afterCompletion
    HandlerInterceptor1.afterCompletion


    如果是 HandlerInterceptor2 中断的流程(preHandle 返回 false),此处仅调用它之前拦截器(HandlerInterceptor1HandlerInterceptor1)的 preHandle 返回 true 的 afterCompletion 方法。








    每个handlerMapping可以有自已的拦截器
    按order值的大小,顺序执行handlerMapping
    执行完拦截后,交给目标处理器 


    springMVC配置文件的三种配置方法:
    方法一:
    <!-- 拦截器 -->
    <mvc:interceptors>
    <bean class="cn.yue.mvc.MyInteceptor" />
    </mvc:interceptors>
    方法二:
    <!-- 拦截匹配的url -->
    <mvc:interceptors>
    <mvc:interceptor>
    <mvc:mapping path="/user/*" />
    <bean class="cn.yue.mvc.MyInteceptor" />
    </mvc:interceptor>
    </mvc:interceptors>


    方法三:
    <!-- handlerMapping上的拦截器 -->
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
    <list>
    <bean class="com.mvc.MyInteceptor"></bean>
    </list>
    </property>
    </bean>


    注:此时不能使用<mvc:annotation-driven />
















    --------------------------正常流程


    自定义拦截器
    public class NormalHandlerInterceptor1 extends HandlerInterceptorAdapter {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    System.out.println("=====NormalHandlerInterceptor1 preHandle=====");
    return super.preHandle(request, response, handler);
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    System.out.println("=====NormalHandlerInterceptor1 postHandle=====");
    super.postHandle(request, response, handler, modelAndView);
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    System.out.println("=====NormalHandlerInterceptor1 afterCompletion=====");
    super.afterCompletion(request, response, handler, ex);
    }


    }




    NormalHandlerInterceptor2同1一样只是打印信息不同


    自定义控制器
    public class TestHandlerIngerceptorController implements Controller {


    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    System.out.println("=TestHandlerInterceptor=");
    return new ModelAndView("test");
    }
    }






    spring配置文件中添加如下内容
    <!-- 测试自定义拦截器中方法的执行顺序 -->
    <bean name="/test"
    class="cn.yue.mvc.controller.TestHandlerIngerceptorController" />
    <bean id="handlerInterceptor1" class="cn.yue.mvc.interceptor.NormalHandlerInterceptor1" />
    <bean id="handlerInterceptor2" class="cn.yue.mvc.interceptor.NormalHandlerInterceptor2" />


    <!-- 指定拦截器链,拦截器的执行顺序就在此指定 -->
    <bean
    class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="interceptors">
    <list>
    <ref bean="handlerInterceptor1" />
    <ref bean="handlerInterceptor2" />
    </list>
    </property>
    </bean>


    测试:http://localhost:8089/test
    =====NormalHandlerInterceptor1 preHandle=====
    =====NormalHandlerInterceptor2 preHandle=====
    =TestHandlerIngerceptorController=
    =====NormalHandlerInterceptor2 postHandle=====
    =====NormalHandlerInterceptor1 postHandle=====
    ===============test.jsp
    =====NormalHandlerInterceptor2 afterCompletion=====
    =====NormalHandlerInterceptor1 afterCompletion=====








    ------------------------------中断流程
    修改NormalHandlerInterceptor2如下内容
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 正常流程
    // System.out.println("=====NormalHandlerInterceptor2 preHandle=====");
    // return super.preHandle(request, response, handler);
    // 中断流程
    System.out.println("=====HandlerInterceptor2 preHandle=====");
    response.getWriter().print("break");// 流程中断的话需要我们进行响应的处理
    return false;// 返回 false 表示流程中断


    }


    测试控制台输出结果如下:
    =====NormalHandlerInterceptor1 preHandle=====
    =====HandlerInterceptor2 preHandle=====
    =====NormalHandlerInterceptor1 afterCompletion=====




    拦截器的应用


    性能监控(记录请求的处理时间)




    登录检测
    为了加强通用性,最好使用servlet规范中的过滤器filter实现 

    参考:http://jinnianshilongnian.iteye.com/blog/1752171 
     
  • 相关阅读:
    阿里云“网红"运维工程师白金:做一个平凡的圆梦人
    3235 战争
    1291 火车线路(区间修改,区间最值)
    P3183 [HAOI2016]食物链
    P1189 SEARCH(逃跑的拉尔夫)
    P1794 装备运输_NOI导刊2010提高(04)
    P2347 砝码称重
    P1332 血色先锋队
    P1772 [ZJOI2006]物流运输
    P1038 神经网络
  • 原文地址:https://www.cnblogs.com/retacn-yue/p/6194263.html
Copyright © 2011-2022 走看看