慎重改动,以下文章引用本文:
https://www.malaoshi.top/show_1EFE3ahx0m1.html
https://www.malaoshi.top/show_1EF5rcqjTdOJ.html
介绍
相当于 JAVAWEB中的过滤器Filter,用于拦截请求,可以在 请求(Controller)前 和 请求(Controller)后 做其他处理
Interceptor拦截器是 链式的,可以有多个Interceptor,SpringMVC会根据添加顺序一个接一个的执行
链式的理解
相当于学校保安,大门口有保安,校园里有保安、寝室楼有保安,从大门口进寝室楼,要经过多个保安
常见应用场景
日志记录:记录请求信息的日志,以便进行 IP监控、信息统计、计算PV(Page View)等。
登录检查:检查当前请求是否已经登录,如果没有返回到登录页面;
权限检查:防止普通用户访问管理员页面
性能监控:有时系统在某段时间无原因卡顿,可以通过拦截器在请求之前记录开始时间,在处理完后记录结束时间,结束时间 减去 开始时间,就是请求的处理时间
源码分析
实现 HandlerInterceptor 接口,该接口源码如下:
jdk1.8后,接口支持 default方法:
package org.springframework.web.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
jdk1.7前:
package org.springframework.web.servlet;
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;
}
执行过程
preHandle()方法
在 Controller之前 执行,可以用来做一些编码处理、安全限制之类的操作。
该方法返回
true,则继续执行 Controller;返回false表示流程中断,不会调用其他的拦截器,此时需要通过response产生响应。当有多个拦截器时,所有的 Interceptor 中的
preHandle()方法都会在 Controller 之前调用,执行顺序:先添加的先执行
postHandle()方法
在 Controller执行后,在渲染视图之前执行(在DispatcherServlet进行视图的渲染之前执行)
当有多个拦截器时,所有的Interceptor中的
postHandle()方法都会在 Controller 之后调用,执行顺序:先添加的后执行注意: controller抛异常时不执行此方法
afterCompletion()方法
最后执行,即:在视图渲染完毕再执行。
无论是否出错都会执行这个方法(类似于try-catch-finally中的finally),一般用于 清理资源


