SpringMVC拦截器preHandle、postHandle、afterCompletion方法执行顺序

3,578 阅读2分钟

1.示意图

image.png

分析:

客户端发的请求,先到拦截器1,执行preHandle1,如果该方法返回false,则不放行,后面所有方法都不再执行;如果返回true,则顺着拦截器链到达下一个拦截器的preHandle

如果所有拦截器preHandle都放行了,则可以正常访问到controller层的方法,执行完毕后,倒回去执行postHandle2、postHandle1~~~

最后客户端完成视图解析后,逆序调用拦截器的afterCompetion方法,即越靠近控制层的拦截器的afterCompetion方法越先执行

2.代码

2.1拦截器1

public class MyInterCeptor1 implements HandlerInterceptor {

    //controller方法执行前 执行,返回true,则放行;返回false,则拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle111.....");
        return true;
    }

    //controller方法执行后 视图解析前 执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle111....");
    }


    //都完成后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion111 ....");
    }
}

2.2拦截器2

public class MyInterCeptor2 implements HandlerInterceptor {

    //controller方法执行前 执行,返回true,则放行;返回false,则拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle222.....");
        return true;
    }

    //controller方法执行后 视图解析前 执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle222....");
    }


    //都完成后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion222....");
    }
}

2.3配置拦截器

<mvc:interceptors>
    <!--拦截器1 -->
    <mvc:interceptor>
        <!--指定要拦截的资源-->
        <mvc:mapping path="/**"/>
        <!--指定拦截器-->
        <bean class="com.itheima.interceptor.MyInterCeptor1"></bean>
    </mvc:interceptor>

    <!--拦截器2-->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.itheima.interceptor.MyInterCeptor2"></bean>
    </mvc:interceptor>
</mvc:interceptors>

注意: 配置顺序影响拦截器的顺序,配在前面的拦截器位于拦截器链的最前面(即更靠近客户端)

3.测试

image.png

4.总结

1.preHandle方法的返回值决定是否放行,该方法在控制层方法执行前执行

2.postHandle方法在控制层方法执行后,视图解析前执行(可以在这里修改控制层返回的视图和模型)

3.afterCompletion方法在视图解析完成后执行,多用于释放资源