HandlerInterceptor
是 Spring MVC 框架中的一个接口,主要用于在处理 HTTP 请求的不同阶段进行拦截和处理。它类似于 Servlet 过滤器,但作用范围更加精细,可以在请求到达控制器之前、请求处理之后以及视图渲染之前进行拦截。
HandlerInterceptor
主要有三个方法:
-
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- 在请求被处理之前调用。通常用于做一些前置的处理逻辑,比如身份验证、权限检查或记录日志等。
- 如果返回
true
,则请求继续向下执行。如果返回false
,则中止请求的后续处理。
-
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
- 在请求处理完后、视图渲染之前调用。可以在这里修改
ModelAndView
,对返回的视图或数据进行进一步的调整。 - 适用于添加一些通用的模型数据或者修改返回的视图等。
- 在请求处理完后、视图渲染之前调用。可以在这里修改
-
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- 在视图渲染完成之后调用。通常用于进行资源清理、日志记录等操作。
- 不管请求是否发生异常,这个方法都会执行,因此特别适合用于做最终的清理工作。
常见使用场景
- 权限验证:可以在
preHandle
中拦截未经授权的请求。 - 性能监控:在
preHandle
中记录请求的开始时间,在afterCompletion
中计算总耗时。 - 日志记录:记录请求的详细信息,如访问的 URL、请求参数、响应状态等。
要使用 HandlerInterceptor
,你需要实现它并在 Spring 配置中注册。通常通过实现 WebMvcConfigurer
接口的 addInterceptors
方法来添加自定义的拦截器。
示例
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 处理前逻辑
System.out.println("preHandle: 拦截请求前的处理逻辑");
return true; // 返回 false 则终止请求处理
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 处理后的逻辑
System.out.println("postHandle: 请求处理后的逻辑");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 资源清理逻辑
System.out.println("afterCompletion: 请求完成后的逻辑");
}
}
然后在 Spring 配置中注册:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor());
}
}
通过这样配置,MyInterceptor
就会在请求处理的各个阶段生效。
preHandle()调用位置
DispatcherServlet
拦截器配置
在 addInterceptor
后面可以使用以下几个方法来配置拦截器的行为:
addPathPatterns(String... patterns)
:指定拦截的 URL 路径。excludePathPatterns(String... patterns)
:指定排除拦截的 URL 路径,即哪些路径不会被拦截。order(int order)
:指定拦截器的执行顺序。数字越小,优先级越高。pathMatcher(PathMatcher pathMatcher)
:自定义路径匹配规则。
下面是一个完整的代码例子,展示如何在 addInterceptor
后使用这些方法:
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
// 指定拦截的路径
.addPathPatterns("/services/**", "/admin/**")
// 指定不拦截的路径
.excludePathPatterns("/services/login", "/services/register")
// 指定拦截器的顺序
.order(1)
// 自定义路径匹配规则(可选)
.pathMatcher(new AntPathMatcher());
// 你还可以注册其他的拦截器
registry.addInterceptor(new AnotherInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/public/**")
.order(2);
}
}
解释:
addPathPatterns("/services/**", "/admin/**")
:指定拦截/services/**
和/admin/**
路径下的请求。excludePathPatterns("/services/login", "/services/register")
:排除对/services/login
和/services/register
这两个路径的拦截。order(1)
:指定authInterceptor
的执行顺序为 1(数字越小优先级越高)。pathMatcher(new AntPathMatcher())
:使用AntPathMatcher
来匹配路径,Spring 默认就是用这个匹配器,所以这行代码可以省略,除非你需要自定义匹配规则。
这个配置允许你灵活地定义哪些请求会被拦截器处理,以及排除哪些路径不被拦截。