Spring-Boot-Interceptor-Usage
在构建企业级Web应用时,我们经常需要在请求处理的不同阶段执行一些通用逻辑,如权限验证、日志记录、性能监控等。
Spring MVC的拦截器(Interceptor)机制提供了一种优雅的方式来实现这些横切关注点,而不必在每个控制器中重复编写相同的代码。
本文将介绍SpringBoot中6种常见的拦截器使用场景及其实现方式。
拦截器基础
什么是拦截器?
拦截器是Spring MVC框架提供的一种机制,用于在控制器(Controller)处理请求前后执行特定的逻辑。
拦截器与过滤器的区别
- 归属不同 :过滤器(Filter)属于Servlet规范,拦截器属于Spring框架。
- 拦截范围 :过滤器能拦截所有请求,拦截器只能拦截Spring MVC的请求。
- 执行顺序 :请求首先经过过滤器,然后才会被拦截器处理。
拦截器的生命周期
方法拦截器通过实现HandlerInterceptor接口来定义,该接口包含三个核心方法:
- preHandle() :在控制器方法执行前调用,返回true表示继续执行,返回false表示中断请求。
- postHandle() :在控制器方法执行后、视图渲染前调用。
- afterCompletion() :在整个请求完成后调用,无论是否有异常发生。
场景一:用户认证拦截器
使用场景
用户认证拦截器主要用于:
- 验证用户是否已登录
- 检查用户是否有权限访问特定资源
- 实现无状态API的JWT token验证
实现代码
@Component
public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 跳过非控制器方法的处理
if (!(handler instanceof HandlerMethod)) {
returntrue;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 检查是否有@PermitAll注解,有则跳过认证
PermitAll permitAll = handlerMethod.getMethodAnnotation(PermitAll.class);
if (permitAll != null) {
returntrue;
}
// 从请求头中获取token
String token = request.getHeader("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("{"error": "未授权,请先登录"}");
returnfalse;
}
token = token.substring(7); // 去掉"Bearer "前缀