Spring MVC自定义拦截器需实现HandlerInterceptor接口,重写preHandle(返回boolean控制放行/拦截)、postHandle(视图渲染前修改ModelAndView)和afterCompletion(请求结束后资源清理、日志记录)三个方法,并通过WebMvcConfigurer注册。

Spring MVC 的自定义拦截器通过实现 HandlerInterceptor 接口完成,核心是重写三个方法:preHandle(请求处理前)、postHandle(视图渲染前)、afterCompletion(整个请求完成后)。关键在于注册拦截器并理解各方法的执行时机和返回值含义。
实现 HandlerInterceptor 接口
创建一个类实现 org.springframework.web.servlet.HandlerInterceptor,按需重写三个方法:
-
preHandle:返回
boolean。返回true表示放行,继续执行后续拦截器或目标处理器;返回false中断流程,不再执行后续拦截器和 Controller 方法,通常需手动写响应(如返回 JSON 错误)。 -
postHandle:在 Controller 方法执行完毕、DispatcherServlet 渲染视图前调用。可修改
ModelAndView(如添加通用属性),但不能修改响应体(此时响应尚未写出)。 -
afterCompletion:无论请求是否成功(包括抛异常),都会执行。适合做资源清理、日志记录、性能统计等。第三个参数
Exception ex非空表示处理过程中发生了异常。
编写一个登录检查拦截器示例
比如校验用户是否已登录(Session 中存在 user):
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("user") == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("{\"code\":401,\"msg\":\"未登录\"}");
return false; // 拦截
}
return true; // 放行
}
<pre class="brush:php;toolbar:false;">@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 可选:向所有页面添加当前时间
if (modelAndView != null) {
modelAndView.addObject("serverTime", System.currentTimeMillis());
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 记录请求耗时或异常信息
long startTime = (Long) request.getAttribute("_start_time");
if (startTime != null) {
System.out.println("Request completed in " + (System.currentTimeMillis() - startTime) + "ms");
}
}}
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
立即学习“Java免费学习笔记(深入)”;
注册拦截器到 WebMvcConfigurer
Spring Boot 2.0+ 推荐通过配置类实现 WebMvcConfigurer 并重写 addInterceptors:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.excludePathPatterns("/login", "/static/**", "/error") // 不拦截登录页、静态资源、错误页
.addPathPatterns("/**"); // 拦截所有其他路径
}
}注意顺序:多个拦截器按注册顺序执行 preHandle(正序),postHandle 和 afterCompletion 则逆序执行。
在 preHandle 中记录开始时间供 afterCompletion 使用
若需统计耗时,可在 preHandle 中把时间戳存入 request 属性,afterCompletion 中读取:
- 在
preHandle开头加:request.setAttribute("_start_time", System.currentTimeMillis()); - 在
afterCompletion中取出并计算差值(如上例所示) - 避免使用静态变量或 ThreadLocal 存储,防止并发问题或内存泄漏

















