精心整理了最新的面试资料和简历模板,有需要的可以自行获取
一、拦截器概述
拦截器(Interceptor)是Spring MVC框架中用于对请求进行预处理和后处理的组件,主要作用于Controller层。相较于Filter(过滤器)作用于更底层,拦截器可以获取Spring的上下文信息,更适合处理与业务逻辑相关的请求拦截。
拦截器与过滤器的区别:
- 作用层面:Filter属于Servlet规范,Interceptor属于Spring MVC组件
- 依赖关系:Interceptor依赖Spring容器,Filter不依赖
- 控制粒度:Interceptor可获取Controller对象和方法信息
二、拦截器核心方法
拦截器通过实现HandlerInterceptor
接口实现,包含三个核心方法:
java
public interface HandlerInterceptor {
// 请求到达Controller前执行
default boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {}
// 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 {}
}
三、实现自定义拦截器
步骤1:创建拦截器类
java
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String token = request.getHeader("Authorization");
if (!validateToken(token)) {
response.sendError(HttpStatus.UNAUTHORIZED.value());
return false; // 中断请求
}
return true;
}
private boolean validateToken(String token) {
// 实现具体的Token验证逻辑
return true;
}
}
步骤2:注册拦截器
创建配置类实现WebMvcConfigurer
:
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/api/**") // 拦截路径
.excludePathPatterns("/api/public/**"); // 排除路径
}
}
四、典型应用场景
1. 接口权限验证
java
@Override
public boolean preHandle(...) {
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login");
return false;
}
return true;
}
2. 请求日志记录
java
public class LoggingInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
@Override
public boolean preHandle(...) {
logger.info("Request [{}] from {}",
request.getRequestURI(),
request.getRemoteAddr());
return true;
}
@Override
public void afterCompletion(...) {
logger.info("Response status: {}", response.getStatus());
}
}
3. 接口耗时统计
java
@Override
public boolean preHandle(...) {
request.setAttribute("startTime", System.currentTimeMillis());
return true;
}
@Override
public void afterCompletion(...) {
long start = (Long) request.getAttribute("startTime");
logger.info("Request took {} ms", System.currentTimeMillis() - start);
}
五、高级配置技巧
1. 多拦截器执行顺序
java
registry.addInterceptor(authInterceptor).order(1);
registry.addInterceptor(loggingInterceptor).order(2);
// 数值越小优先级越高
2. 路径匹配模式
/*
:匹配单级路径/**
:匹配多级路径/admin/**
:匹配/admin下的所有路径
3. 排除静态资源
java
.excludePathPatterns("/static/**", "/public/**")
六、常见问题解决方案
Q1:拦截器不生效的可能原因
- 未添加@Configuration注解
- 路径匹配模式错误
- 未正确注入拦截器实例
Q2:如何获取Controller方法信息?
java
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
// 获取方法上的注解等信息
}
Q3:异步请求的特殊处理
实现AsyncHandlerInterceptor
接口处理异步请求
七、性能优化建议
- 避免在拦截器中处理复杂业务逻辑
- 合理设置拦截路径,减少不必要的拦截
- 使用ThreadLocal存储请求上下文信息