本文目录导读:

在Java中,拦截器(Interceptor)的概念主要出现在Spring MVC(HandlerInterceptor)和Struts2框架中,最常用的是 Spring Boot + Spring MVC 的拦截器配置方式。
下面我会给你一个完整的、可直接运行的Spring Boot拦截器案例配置,包含登录权限校验的常见场景。
核心步骤
- 创建拦截器类:实现
HandlerInterceptor接口。 - 配置拦截器:创建一个配置类,实现
WebMvcConfigurer接口,并重写addInterceptors方法。
第一个:创建拦截器类 (Interceptor)
假设我们要创建一个拦截器,用于检查用户是否登录(拦截所有 路径,但放过登录页面和静态资源)。
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
/**
* 在请求处理之前执行 (Controller方法调用之前)
* @return true: 放行; false: 拦截并阻止后续流程
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 1. 检查 Session 或 Header 中是否有用户信息
Object user = request.getSession().getAttribute("user");
if (user == null) {
// 用户未登录 —— 拦截
System.out.println("拦截器触发:用户未登录,请求被拦截");
// 方式1:返回错误 JSON (适用于前后端分离)
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write("{\"code\":401,\"msg\":\"未登录,请先登录\"}");
// 方式2:重定向到登录页 (适用于传统Web项目)
// response.sendRedirect("/login");
return false; // 拦截
} else {
// 用户已登录 —— 放行
System.out.println("拦截器放行:用户已登录");
return true;
}
}
// 请求处理之后执行 (Controller方法调用之后,视图渲染之前)
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
// 通常用于对ModelAndView进行额外处理
}
// 整个请求完成之后执行 (视图渲染之后)
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception ex) throws Exception {
// 通常用于资源清理、日志记录
}
}
第二个:配置拦截器生效 (WebMvcConfigurer)
创建一个配置类,告诉Spring Boot哪些路径需要被拦截,哪些需要被排除。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration // 表明这是一个Spring配置类
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册我们上面创建的拦截器
registry.addInterceptor(new LoginInterceptor()) // 注入拦截器
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns( // 放行的路径
"/login", // 登录页面 API
"/register", // 注册页面 API
"/api/login", // 登录接口
"/api/register", // 注册接口
"/css/**", // 静态资源
"/js/**",
"/images/**",
"/error", // 错误页面
"/swagger-resources/**", // Swagger文档
"/v2/api-docs"
);
}
}
如果使用Spring Security
在实际企业项目中,权限校验更多使用 Spring Security 或 Shiro,但如果你只是想实现简单的请求拦截(比如日志记录、计时、或非常简单的权限检查),使用 HandlerInterceptor 即可。
多拦截器执行顺序
如果你有多个拦截器(比如一个日志拦截器、一个权限拦截器),注意:
- 添加的顺序 > 执行顺序
- 先添加的先执行
preHandle, 后添加的后执行postHandle。
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 顺序1:日志拦截器
registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
// 顺序2:权限拦截器
registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/api/**");
}
示例:完整的测试流程
- 启动项目。
- 访问
http://localhost:8080/api/user/list(假设它需要登录)。- 返回:
{"code":401,"msg":"未登录,请先登录"}
- 返回:
- 访问
http://localhost:8080/login。放行,正常返回。
- 先调用登录接口,再访问
/api/user/list。放行,正常执行业务。
常见问题与优化
-
乱码问题:在
preHandle中返回JSON时,记得设置response.setCharacterEncoding("UTF-8")。 -
排除路径失效:检查你的
addPathPatterns和excludePathPatterns路径格式是否正确, 表示下一级路径, 表示所有子孙路径。 -
注入Service:如果你在拦截器中需要使用
@Autowired注入Service,不要直接在拦截器上使用new关键字,应该通过构造器注入或使用@Component注解拦截器类。@Component // 方式1 public class LoginInterceptor implements HandlerInterceptor { @Autowired private UserService userService; // ... } // 配置时 registry.addInterceptor(loginInterceptor) // 注入,而非new .addPathPatterns("/**");
通过以上配置,你可以在Spring Boot项目中灵活地使用拦截器实现权限校验、日志记录、性能监控等功能。