Spring MVC 拦截器概念与作用
拦截器是Spring MVC提供的AOP式机制,用于在请求处理前后执行统一逻辑。
拦截器定义
拦截器(Interceptor)是在Controller方法执行前后插入自定义逻辑的组件,通过实现HandlerInterceptor接口实现。
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 | Controller执行前 | boolean | 登录验证、权限检查、预处理 |
| postHandle | Controller执行后,视图渲染前 | void | 修改ModelAndView、添加公共数据 |
| afterCompletion | 视图渲染完成后 | void | 资源清理、日志记录、异常处理 |
执行流程
Java
HTTP请求
↓
DispatcherServlet
↓
preHandle() → 返回true继续,返回false中断
↓
Handler(Controller)
↓
postHandle() → 可修改响应数据
↓
View渲染
↓
afterCompletion() → 资源清理
↓
HTTP响应
拦截器核心作用
1. 登录验证
拦截未登录请求,强制跳转登录页。
Java
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
if (user == null) {
response.sendRedirect("/login");
return false;
}
return true;
}
2. 权限控制
验证用户是否有访问特定资源的权限。
Java
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String uri = request.getRequestURI();
User user = getCurrentUser();
if (!hasPermission(user, uri)) {
response.setStatus(403);
response.getWriter().write("无访问权限");
return false;
}
return true;
}
3. 日志记录
记录请求信息,便于追踪和调试。
Java
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
log.info("请求开始: {} {}", request.getMethod(), request.getRequestURI());
request.setAttribute("startTime", System.currentTimeMillis());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
long duration = System.currentTimeMillis()
- (Long) request.getAttribute("startTime");
log.info("请求完成: {} {}, 耗时: {}ms",
request.getMethod(), request.getRequestURI(), duration);
}
4. 性能监控
统计接口响应时间,监控慢请求。
Java
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
Long startTime = (Long) request.getAttribute("startTime");
long duration = System.currentTimeMillis() - startTime;
if (duration > 1000) { // 超过1秒为慢请求
log.warn("慢请求警告: {} {}, 耗时: {}ms",
request.getMethod(), request.getRequestURI(), duration);
}
}
5. 公共数据注入
为所有视图添加公共数据。
Java
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) {
if (modelAndView != null) {
modelAndView.addObject("siteName", "MyApp");
modelAndView.addObject("currentUser", getCurrentUser());
}
}
6. 资源清理
请求完成后清理ThreadLocal等资源。
text
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
UserContext.clear(); // 清理用户上下文
TraceContext.clear(); // 清理追踪上下文
}
拦截器适用场景
| 场景 | 是否适用 | 说明 |
|---|---|---|
| 登录验证 | ✅ | preHandle检查session或token |
| 权限控制 | ✅ | preHandle验证权限 |
| 日志记录 | ✅ | preHandle记录开始,afterCompletion记录结束 |
| 性能监控 | ✅ | 计算请求耗时 |
| 请求限流 | ✅ | preHandle检查限流规则 |
| 数据预处理 | ✅ | preHandle添加公共参数 |
| 异常统一处理 | ❌ | 建议使用@ControllerAdvice |
| 静态资源处理 | ❌ | 拦截器不处理静态资源 |
拦截器与过滤器对比
| 对比项 | 拦截器 | 过滤器 |
|---|---|---|
| 所属框架 | Spring MVC | Servlet容器 |
| 作用范围 | Controller | 所有请求(包括静态资源) |
| 执行时机 | Controller前后 | Servlet前后 |
| 依赖Spring | 是 | 否 |
| 获取Handler | 可以 | 不可以 |
拦截器只能拦截Controller请求,静态资源不经过拦截器。
要点总结
- 拦截器实现HandlerInterceptor接口
- preHandle在Controller前执行,返回false中断请求
- postHandle在Controller后执行,可修改响应数据
- afterCompletion在渲染后执行,用于清理和日志
- 适用于登录验证、权限控制、日志记录等场景
- 拦截器只作用于Controller,不拦截静态资源
📝 发现内容有误?点击此处直接编辑