Spring MVC 拦截器
Spring MVC 拦截器(Interceptor)是 Spring 框架提供的一种用于在请求处理之前和之后对 HTTP 请求进行处理的机制。拦截器常用于处理日志、权限验证、性能监控等功能。
1. 定义拦截器
拦截器需要实现 HandlerInterceptor
接口,主要有三个方法:
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
:在请求处理之前执行,返回true
表示继续执行下一个拦截器或者目标方法,返回false
则会停止后续拦截器链的执行。postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
:请求处理之后执行,但在视图渲染之前调用。afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
:请求处理完毕后执行,主要用于清理资源。
2. 创建拦截器
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
// 请求处理之前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle: 请求处理前");
// 返回true表示继续处理请求,返回false表示请求被拦截,后续处理不会执行
return true;
}
// 请求处理之后执行,但视图渲染之前
@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: 请求处理后,视图渲染后");
}
}
3. 注册拦截器
在 Spring MVC 配置中,你需要将拦截器注册到 HandlerInterceptor
接口中。通常有两种方式来进行配置:
3.1 使用 Java 配置(基于 WebMvcConfigurer
)
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**") // 配置拦截路径,所有路径都会被拦截
.excludePathPatterns("/login", "/signup"); // 排除不需要拦截的路径
}
}
3.2 使用 XML 配置
如果你使用的是基于 XML 配置的 Spring MVC,你可以在 servlet-context.xml
文件中注册拦截器:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.example.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
4.多个拦截器指定顺序
4.1 通过 InterceptorRegistry
顺序控制
在 WebMvcConfigurer
中,拦截器的执行顺序是按照它们注册的顺序来的。注册的顺序决定了拦截器的执行顺序。第一个注册的拦截器会先执行,依此类推。
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 第一个拦截器
registry.addInterceptor(new FirstInterceptor())
.addPathPatterns("/**");
// 第二个拦截器
registry.addInterceptor(new SecondInterceptor())
.addPathPatterns("/**");
}
}
在这个例子中,FirstInterceptor
会先执行,然后是 SecondInterceptor
4.2 使用 @Order
注解显式指定顺序,配合 Spring Bean 自动装配
你也可以通过 @Order
注解显式指定每个拦截器的执行顺序。@Order
的值越小,拦截器的执行顺序越靠前。
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(1) // 顺序靠前
public class FirstInterceptor implements HandlerInterceptor {
// 实现方法
}
@Component
@Order(2) // 顺序靠后
public class SecondInterceptor implements HandlerInterceptor {
// 实现方法
}
@Component
@Order(3) // 最后执行
public class ThirdInterceptor implements HandlerInterceptor {
// 实现方法
}
在这个例子中,FirstInterceptor
会先执行,然后是 SecondInterceptor
,因为 FirstInterceptor
的 @Order
注解值为 1
,而 SecondInterceptor
的值为 2
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private FirstInterceptor firstInterceptor;
@Autowired
private SecondInterceptor secondInterceptor;
@Autowired
private ThirdInterceptor thirdInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(firstInterceptor).addPathPatterns("/**");
registry.addInterceptor(secondInterceptor).addPathPatterns("/**");
registry.addInterceptor(thirdInterceptor).addPathPatterns("/**");
}
}
5.执行顺序
当有多个拦截器时,并且各个方法都未发生异常,执行顺序为
- 先顺序执行各个拦截器的 preHandle 方法
- 然后执行 目标方法
- 然后倒序执行所有拦截器的 postHandle 方法
- 最后再倒序执行所有拦截器的 afterCompletion 方法
当 preHandle 发生异常时,postHandle 不会执行,但是 afterCompletion 会执行
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具