**

SpringMVC拦截器

**

SpringMVC拦截器配置方法:

1、Spring-MVC配置文件:

<mvc:interceptors>
        <!-- 登录拦截 -->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!-- 不作拦截的路径 至于拦截路径下方 -->
            <mvc:exclude-mapping path="/login"/>
            <mvc:exclude-mapping path="/toLogin"/>
            <!-- 资源访问 -->
            <mvc:exclude-mapping path="/static/**"/>
            <bean class="cn.demo.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
        <!-- 测试拦截器 -->
        <mvc:interceptor>
        <!-- 拦截器作用路径 -->
            <mvc:mapping path="/test/**"/>
            <!-- 拦截器编辑-->
            <bean class="cn.demo.interceptor.TestInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

2、拦截器实现

实现 HandlerInterceptor 接口

public class TestInterceptor implements HandlerInterceptor{
/**
* 拦截到请求后 先进入preHandle方法 进行处理
* return true 则进入请求路径
* return false 则结束请求
*/
    @Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("处理请求:"+httpServletRequest.getRequestURL().toString());
        return true;
    }
/**
* 请求完成后进入该方法
* 处理请求后,渲染页面前
*/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("========处理请求后,渲染页面前======");
        modelAndView.addObject("post","interceptor change view before rendering");
    }
/**
* 最后执行此方法
* 视图渲染结束了,请求处理完毕
*/
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("========视图渲染结束了,请求处理完毕====");
    }
}

3、SpringMVC拦截器实现原理

用户请求到DispatherServlet中,DispatherServlet调用HandlerMapping查找Handler,HandlerMapping返回一个拦截器链(HandlerExecutionChain),springmvc中的拦截器是通过HandlerMapping发起的。

HandlerInterceptor 接口提供了三个方法:
1、preHandle():这个方法在业务处理器处理请求之前被调用。如果该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器(即Controller)去进行处理,则返回true;如果不需要再调用其他的组件去处理请求了,则返回false;
2、postHandle():这个方法在业务处理器处理完请求后,但是DispatcherServlet向客户端返回请求前被调用,在该方法中对用户请求request进行处理;
3、afterCompletion():这个方法在DispatcherServlet完全处理完请求后被调用,可以在该方法中进行一些资源清理的工作;

4、多个拦截器执行顺序

1、拦截器执行顺序是按照Spring配置文件中定义的顺序而定的。

2、会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则按顺序加载完preHandle方法。

3、然后执行主方法(自己的controller接口),若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。

4、在主方法执行完业务逻辑(页面还未渲染数据)时,按倒序执行postHandle方法。若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的postHandle方法和afterCompletion(postHandle都执行完才会执行这个,也就是页面渲染完数据后,执行after进行清理工作)方法。(postHandle和afterCompletion都是倒序执行)