Java中拦截器的使用实现步骤
作者:墨香染城城
一、拦截器的作用与执行时机
- 三个核心方法:
- preHandle(): 在Controller方法执行前调用(用于权限验证等)
- postHandle(): 在Controller方法执行后、视图渲染前调用(可修改ModelAndView)
- afterCompletion(): 在请求完全结束后调用(资源清理、日志记录)
- 执行流程:

二、实现步骤
步骤1:创建自定义拦截器
实现继承 HandlerInterceptor 接口:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class AuthInterceptor implements HandlerInterceptor {
// Controller执行前调用
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("--- preHandle executed ---");
// 示例:验证登录
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login"); // 重定向到登录页
return false; // 中断请求
}
return true; // 放行请求
}
// Controller执行后、视图渲染前调用
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("--- postHandle executed ---");
// 可修改ModelAndView数据
if (modelAndView != null) {
modelAndView.addObject("timestamp", System.currentTimeMillis());
}
}
// 请求完全结束后调用(视图渲染完毕)
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
System.out.println("--- afterCompletion executed ---");
// 资源清理或记录请求耗时
}
}步骤2:注册拦截器到Spring MVC
创建配置类实现 继承 WebMvcConfigurer 接口:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/**") // 拦截所有路径
.excludePathPatterns("/login", "/css/**"); // 排除路径
}
}步骤3:测试Controller
@RestController
public class TestController {
@GetMapping("/home")
public String home() {
return "Welcome to home page!";
}
@GetMapping("/login")
public String login() {
return "Login page";
}
}三、关键配置详解
- 路径匹配规则:
- addPathPatterns("/admin/**"):拦截以 /admin/ 开头的所有路径
- excludePathPatterns("/public/**"):排除静态资源
- 多拦截器顺序:
registry.addInterceptor(new LogInterceptor()).order(1); // 数字越小优先级越高 registry.addInterceptor(new AuthInterceptor()).order(2);
执行顺序:
LogInterceptor.preHandle → AuthInterceptor.preHandle → Controller →
AuthInterceptor.postHandle → LogInterceptor.postHandle →
视图渲染 → AuthInterceptor.afterCompletion → LogInterceptor.afterCompletion
四、常见使用场景
- 身份认证:在 preHandle() 中校验Session/Token
- 日志记录:在 afterCompletion() 记录请求耗时
- 参数预处理:在 preHandle() 中统一处理请求参数
- 全局数据注入:在 postHandle() 中向Model添加公共数据
五、拦截器 vs 过滤器(Filter)
特性 | 拦截器 (Interceptor) | 过滤器 (Filter) |
归属 | Spring MVC 机制 | Servlet 规范 |
作用范围 | 仅针对Controller请求 | 所有请求(包括静态资源) |
依赖 | 可访问Spring容器中的Bean | 无法直接使用Spring Bean |
执行时机 | Controller方法前后 | Servlet处理前后 |
实例化 | 受Spring管理(支持依赖注入) | 由Web服务器管理 |
提示:优先使用拦截器处理Controller相关逻辑,过滤器更适合处理底层Servlet请求(如编码转换)。
六、最佳实践
- 避免阻塞操作:拦截器中不要执行耗时任务(影响吞吐量)
- 谨慎使用postHandle:如果Controller有 @ResponseBody,postHandle 不会生效(无视图渲染)
- 注入Bean的正确方式:
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Autowired // 拦截器本身需由Spring管理
private UserService userService;
}
// 注册时从容器获取
registry.addInterceptor(authInterceptor); 通过以上步骤,您可以在Spring Boot中高效实现拦截逻辑。根据实际需求组合多个拦截器,构建灵活的处理链。
七、HandlerInterceptor 和 WebMvcConfigurer
在 Spring Boot 项目中,当创建拦截器时,我们需要处理两个独立的接口:HandlerInterceptor 和 WebMvcConfigurer
1. HandlerInterceptor 接口需要重写的方法
当创建自定义拦截器时,需要实现 HandlerInterceptor 接口并重写它的三个核心方法:
方法 | 说明 | 是否必须重写 |
preHandle() | 在 Controller 方法执行前调用 | ✅ 通常必须 |
postHandle() | 在 Controller 方法执行后、视图渲染前调用 | ⚠️ 可选 |
afterCompletion() | 在请求完全结束后调用 | ⚠️ 可选 |
public class AuthInterceptor implements HandlerInterceptor {
// 必须重写(最常用)
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// 认证逻辑
return true; // 返回 true 放行请求
}
// 可选重写
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) {
// 后处理逻辑
}
// 可选重写
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
// 清理资源
}
}2. WebMvcConfigurer接口需要重写的方法
当注册拦截器时,需要实现 WebMvcConfigurer 接口,但只需重写一个方法:
方法 | 说明 | 是否必须重写 |
addInterceptors() | 注册自定义拦截器并配置拦截规则 | ✅ 必须 |
其他方法(与拦截器无关,可选重写):
- addCorsMappings():配置跨域
- addResourceHandlers():静态资源处理
- addViewControllers():视图控制器
- 等 20+ 个默认方法(Java 8+ 的接口默认方法)
示例实现:
@Configuration
public class WebConfig implements WebMvcConfigurer {
// 必须重写(唯一需要重写的方法)
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/**") // 拦截所有路径
.excludePathPatterns("/login"); // 排除登录页
}
// 其他方法不需要重写(除非有特殊需求)
// 例如跨域配置(可选)
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
}3. 完整流程图示

4. 关键注意事项
- HandlerInterceptor 方法重写规则
- preHandle() 必须返回 boolean(true=放行,false=中断)
- postHandle() 仅在返回视图时生效(对 @ResponseBody 无效)
- afterCompletion() 总是执行(即使 Controller 抛出异常)
- WebMvcConfigurer 最佳实践
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired // 推荐注入拦截器(不要new实例)
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 设置多拦截器顺序
registry.addInterceptor(new LogInterceptor()).order(0);
registry.addInterceptor(authInterceptor).order(1)
.addPathPatterns("/secure/**");
}
}常见错误 :
- 错误1:忘记在配置类加 @Configuration
- 错误2:在 WebMvcConfigurer 中重写了不需要的方法
- 错误3:在拦截器中 new 实例(应使用依赖注入)
5. 两种接口的关系总结
特性 | HandlerInterceptor | WebMvcConfigurer |
角色 | 定义拦截逻辑 | 注册拦截器 |
重写方法 | preHandle() | addInterceptors() |
使用场景 | 业务逻辑实现 | 配置管理 |
实例数量 | 每个拦截器一个实现类 | 整个项目只需一个配置类 |
注解要求 | @Component(可选) | @Configuration(必须) |
💡 简单记忆:
- HandlerInterceptor:定义 "做什么"(拦截逻辑)
- WebMvcConfigurer:定义 "对谁做"(拦截路径)
总结
到此这篇关于Java中拦截器的使用实现的文章就介绍到这了,更多相关Java拦截器使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
