spring之自定义拦截器:HandlerInterceptor 控制请求生死权
HandlerInterceptor
- HandlerInterceptor 执行流程图
- 定义拦截器
HandlerInterceptor 执行流程图
┌───────────────────────────────────┐│ 客户端发起请求 │└───────────────────────────────────┘│▼┌───────────────────────────────────┐│ Filter 链 (Servlet 过滤器) ││ - 最先执行,可做全局安全/编码处理 │└───────────────────────────────────┘│▼┌───────────────────────────────────┐│ Interceptor.preHandle() ││ - 请求到达 Controller 前调用 ││ - 返回 true → 继续执行 ││ - 返回 false → 请求被拦截,直接结束 │└───────────────────────────────────┘│(如果放行,继续)▼┌───────────────────────────────────┐│ Controller 方法执行 ││ (业务逻辑 / Service 调用) │└───────────────────────────────────┘│▼┌───────────────────────────────────┐│ Interceptor.postHandle() ││ - Controller 执行完成后调用 ││ - 渲染视图前,可以修改 ModelAndView ││ - 常用于统计耗时、追加数据 │└───────────────────────────────────┘│▼┌───────────────────────────────────┐│ 视图渲染 / JSON 响应返回客户端 │└───────────────────────────────────┘│▼┌───────────────────────────────────┐│ Interceptor.afterCompletion() ││ - 请求完成后调用 ││ - 可用于异常记录、资源清理 │└───────────────────────────────────┘
preHandle
位置:Controller 执行前
作用:权限校验、登录状态校验、请求日志
返回 false → 直接中断,不进入 Controller
postHandle
位置:Controller 执行后,视图渲染前
作用:性能统计、响应数据增强
afterCompletion
位置:视图渲染完成后(请求生命周期的最后一步)
作用:异常日志、清理资源(如 MDC、ThreadLocal)
定义拦截器
@Component
public class CustomInterceptor implements HandlerInterceptor {// Controller 方法执行前调用(相当于门禁检查)@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {long start = System.currentTimeMillis();request.setAttribute("startTime", start);// 示例:检查用户是否登录String token = request.getHeader("Authorization");if (token == null || !token.equals("valid-token")) {response.setContentType("application/json;charset=UTF-8");response.getWriter().write("{\"code\":401, \"msg\":\"未登录或 token 无效\"}");return false; // ❌ 阻止继续进入 Controller}return true; // ✅ 放行}// Controller 执行后,视图渲染前调用@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) {// 示例:接口响应时间统计long start = (long) request.getAttribute("startTime");long cost = System.currentTimeMillis() - start;System.out.println("接口耗时:" + cost + "ms");}// 请求完成后调用(如异常日志收集)@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {if (ex != null) {System.err.println("请求出现异常:" + ex.getMessage());}}
}
- 注册拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate CustomInterceptor customInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(customInterceptor).addPathPatterns("/**") // 拦截所有请求.excludePathPatterns("/login", "/error"); // 排除登录、错误页}
}
常见使用场景
-
统一登录校验 / 权限控制
→ 在 preHandle 阶段校验 JWT / Token,决定是否放行。 -
接口性能监控
→ 在 postHandle 或 afterCompletion 里计算耗时,上报到日志/监控系统。 -
统一请求日志
→ 在 preHandle 打印请求参数、afterCompletion 打印响应状态。 -
分布式链路追踪
→ 在 preHandle 生成 traceId,放入 MDC;在 afterCompletion 清理。