拦截器
在 Spring Boot 中,拦截器(Interceptor)用于在请求到达 Controller 之前或响应返回客户端之前,对请求和响应进行预处理或后处理。
HandlerInterceptor
Spring MVC 提供了 HandlerInterceptor 接口,主要有三个方法:
java
public interface HandlerInterceptor {
// 在 Controller 方法执行前调用
default boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
return true;
}
// Controller 方法执行后,但视图渲染前调用
default void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
}
// 请求处理完成后调用(即使出现异常也会调用)
default void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
}
}preHandle 返回
true表示继续处理请求,返回false则会中断请求(常用于权限校验、日志、限流等)。postHandle 用于修改返回的
ModelAndView,适合在渲染视图前处理数据。afterCompletion 用于清理资源、记录日志或异常处理。
自定义拦截器
假设你要做一个简单的登录检查:
java
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("user");
if (user == null) {
response.sendRedirect("/login");
return false;
}
return true;
}
@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 {
// 清理资源
}
}注册拦截器
Spring Boot 中可以通过实现 WebMvcConfigurer 来注册拦截器:
java
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 MyWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns("/login", "/css/**", "/js/**"); // 排除登录页和静态资源
}
}addPathPatterns用于指定拦截路径。excludePathPatterns用于排除路径,比如登录页或静态资源。
多个拦截器
多个拦截器按顺序执行
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 登录检查
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login", "/css/**");
// 日志拦截
registry.addInterceptor(new LogInterceptor())
.addPathPatterns("/**");
// 权限拦截(例如接口权限)
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**");
}
}preHandle:Login → Log → Auth- Controller 执行
postHandle:Auth → Log → LoginafterCompletion:Auth → Log → Login
如果 LoginInterceptor
preHandle返回 false,Log 和 Auth 的preHandle不会执行,但 Login 的afterCompletion仍然会被调用。
