Java拦截器案例如何编写配置:从零到实战的完整指南
目录导读
- 什么是拦截器?核心概念与作用
- 拦截器 vs 过滤器:本质区别与选型建议
- Spring MVC拦截器实战:编写配置步骤详解
- 完整案例:用户权限校验拦截器(含代码)
- 拦截器常见配置陷阱与解决方案
- 高频问答:开发者最常问的5个问题
什么是拦截器?核心概念与作用
拦截器(Interceptor) 是Java Web开发中一种面向切面编程(AOP)的实现机制,主要用于在请求处理流程的特定阶段(如Controller方法执行前、后、完成后)插入自定义逻辑。

核心作用包括:
- 身份认证与权限校验:拦截未登录用户访问受保护资源
- 请求日志记录:记录接口调用时间、参数、结果
- 性能监控:统计接口处理耗时
- 数据预处理:统一设置请求头、编码字符等
- 资源释放与清理:如关闭数据库连接、清除临时文件
工作流程:
请求 → 拦截器.preHandle() → Controller → 拦截器.postHandle() → 视图渲染 → 拦截器.afterCompletion() → 响应
当preHandle()返回false时,请求将被阻断,不再继续执行后续流程。
拦截器 vs 过滤器:本质区别与选型建议
很多开发者容易混淆这两个概念,以下是关键对比:
| 对比维度 | 拦截器(Interceptor) | 过滤器(Filter) |
|---|---|---|
| 依赖容器 | 基于Spring IoC容器 | 基于Servlet容器 |
| 作用范围 | 仅拦截Controller请求 | 拦截所有URL资源(包括静态文件) |
| 处理能力 | 可获取Spring Bean、AOP上下文 | 功能较基础,无Spring支持 |
| 典型场景 | 业务逻辑校验、参数处理 | 编码设置、跨域、XSS过滤 |
选型建议:
- 需要操作Spring Bean(如注入Service) → 用拦截器
- 纯Web层通用处理(如设置字符集) → 用过滤器
- 同时需要两种能力 → 可组合使用
Spring MVC拦截器实战:编写配置步骤详解
步骤1:创建拦截器类
实现HandlerInterceptor接口,并重写三个方法:
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 返回true放行,false拦截
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// Controller执行后、视图渲染前
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 请求完全处理后
}
}
步骤2:配置拦截规则(两种方式)
Java配置类(推荐)
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**") // 拦截路径
.excludePathPatterns("/api/login", // 排除路径
"/api/register",
"/error",
"/static/**"); // 静态资源排除
}
}
XML配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/api/**"/>
<mvc:exclude-mapping path="/api/login"/>
<mvc:exclude-mapping path="/api/register"/>
<bean class="com.example.interceptor.AuthInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
步骤3:注册与生效
- Spring Boot项目自动扫描
@Configuration类 - 传统Spring项目需在
spring-mvc.xml中开启<mvc:annotation-driven/>
完整案例:用户权限校验拦截器(含代码)
需求描述
拦截/admin/**下的所有请求,校验请求头中的Token是否有效,无效则返回401。
拦截器实现
public class TokenAuthInterceptor implements HandlerInterceptor {
@Autowired
private AuthService authService; // 注入Spring Bean必须配合@Component
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
String token = request.getHeader("Authorization");
if (token == null || !authService.validateToken(token)) {
response.setStatus(401);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write("{\"code\":401,\"msg\":\"无权限访问\"}");
return false;
}
// 将用户信息放入请求上下文
request.setAttribute("userId", authService.getUserId(token));
return true;
}
}
配置类
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注意:如果拦截器中使用了@Autowired,此处需要用@Bean注入
registry.addInterceptor(tokenAuthInterceptor())
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin/login");
}
@Bean
public TokenAuthInterceptor tokenAuthInterceptor() {
return new TokenAuthInterceptor();
}
}
关键:因为拦截器在Spring Bean容器创建前就被实例化,因此需通过@Bean方式注册。
测试验证
- 访问
/admin/dashboard(不带Token)→ 返回401 - 访问
/admin/dashboard(带有效Token)→ 返回正常数据 - 访问
/admin/login(排除路径)→ 可直接访问
拦截器常见配置陷阱与解决方案
陷阱1:拦截器不生效
- 原因:未实现
WebMvcConfigurer或Java配置类未被扫描 - 解决:检查
@Configuration注解,Spring Boot确保配置类在主启动类同层级或子包
陷阱2:静态资源被拦截
- 原因:未排除静态资源路径(如
/static/**,/css/**等) - 解决:
.excludePathPatterns("/static/**", "/webjars/**")
陷阱3:多个拦截器执行顺序混乱
- 规则:按注册顺序执行
preHandle(先注册先执行),postHandle和afterCompletion反向执行 - 正确做法:按业务依赖顺序注册,拦截器A(日志)→ 拦截器B(认证)
陷阱4:拦截器中注入失败
- 原因:拦截器通过
new创建,非Spring管理 - 解决:使用
@Bean方式注册,或使用@Component并通过registry.addInterceptor(this)注入
高频问答:开发者最常问的5个问题
Q1:拦截器可以访问Controller方法的参数吗?
A:可以。preHandle中的Object handler参数是HandlerMethod类型,可通过((HandlerMethod) handler).getMethod()获取方法对象,再通过getParameterAnnotations()获取参数注解和值。
Q2:如何让拦截器只拦截特定HTTP方法(如只拦截POST请求)?
A:在preHandle中通过request.getMethod()判断,
if (!"POST".equalsIgnoreCase(request.getMethod())) {
return true; // 非POST请求直接放行
}
Q3:拦截器抛出异常后如何处理?
A:在afterCompletion中捕获异常,或使用Spring的@ControllerAdvice统一异常处理,拦截器本身建议只做校验逻辑,异常交由全局处理器处理。
Q4:多个拦截器可不可以共享数据?
A:可以,通过HttpServletRequest.setAttribute()在不同拦截器和Controller间传递数据,例如前一个拦截器将用户信息放入请求上下文,后一个拦截器读取。
Q5:Spring Security和拦截器如何共存? A:Spring Security本质是一组过滤器链,拦截器在其后执行,最佳实践是:Security做整体安全(认证/授权),拦截器做业务特定逻辑(如接口调用频率限制)。
Java拦截器是构建可维护Web应用的利器,核心在于理解其生命周期、正确配置注册方式、以及处理与Spring容器的依赖关系,通过本文的案例和陷阱提示,你可以快速在企业项目中落地拦截器功能,遇到配置问题,优先检查注册方式是否正确、路径模式是否覆盖预期、以及Bean依赖是否生效。