您好,登录后才能下订单哦!
# SpringMVC HandlerInterceptor拦截器的使用与参数详解
## 一、拦截器概述
### 1.1 什么是HandlerInterceptor
HandlerInterceptor是Spring MVC框架中提供的一种拦截机制,允许开发者在请求处理的不同阶段插入自定义逻辑。它类似于Servlet规范中的Filter,但提供了更细粒度的控制能力。
```java
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
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 {
}
}
特性 | HandlerInterceptor | Filter |
---|---|---|
所属规范 | Spring MVC特有 | Servlet规范 |
执行位置 | DispatcherServlet之后 | Servlet容器级别 |
依赖关系 | 需要Spring容器支持 | 不依赖Spring |
获取上下文 | 可以获取Spring上下文 | 无法直接获取 |
控制粒度 | 方法级别拦截 | URL级别拦截 |
在处理器方法执行前被调用,是最常用的拦截点。
参数说明:
- HttpServletRequest request
:HTTP请求对象
- HttpServletResponse response
:HTTP响应对象
- Object handler
:被拦截的控制器方法(HandlerMethod实例)
返回值:
- true
:继续执行后续拦截器和处理器
- false
:中断执行流程
典型应用场景:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 登录检查
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login");
return false;
}
return true;
}
在处理器方法执行后,视图渲染前被调用。
新增参数:
- ModelAndView modelAndView
:控制器返回的模型和视图对象
注意事项: - 仅当preHandle返回true时才会执行 - 异常发生时不会执行
使用示例:
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) {
// 向所有视图添加公共参数
if (modelAndView != null) {
modelAndView.addObject("version", "1.0.0");
}
}
在整个请求完成(视图渲染完毕)后执行。
新增参数:
- Exception ex
:处理器抛出的异常(如果有)
典型用途:
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
// 资源清理
DatabaseConnectionPool.releaseAll();
// 异常日志记录
if (ex != null) {
log.error("Request processing failed", ex);
}
}
通过WebMvcConfigurer实现配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/public/**");
}
}
支持Ant风格路径匹配:
- ?
匹配单个字符
- *
匹配0或多个字符
- **
匹配0或多个目录
示例:
.addPathPatterns("/user/*/profile") // 匹配/user/123/profile
.addPathPatterns("/admin/**") // 匹配所有/admin/下的路径
通过order方法控制顺序(数值越小优先级越高):
registry.addInterceptor(new LogInterceptor()).order(1);
registry.addInterceptor(new AuthInterceptor()).order(2);
public class PerformanceInterceptor implements HandlerInterceptor {
private ThreadLocal<Long> startTime = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
startTime.set(System.currentTimeMillis());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
long duration = System.currentTimeMillis() - startTime.get();
log.info("{}耗时: {}ms", request.getRequestURI(), duration);
startTime.remove();
}
}
public class IdempotentInterceptor implements HandlerInterceptor {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("Idempotent-Token");
if (StringUtils.isEmpty(token)) {
throw new BusinessException(400, "幂等Token缺失");
}
Boolean result = redisTemplate.opsForValue().setIfAbsent("idempotent:" + token, "1", 24, TimeUnit.HOURS);
if (Boolean.FALSE.equals(result)) {
throw new BusinessException(400, "请勿重复提交");
}
return true;
}
}
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
// 获取方法上的注解
RequestMapping annotation = method.getAnnotation(RequestMapping.class);
}
对于异步请求(Callable/DeferredResult),需要实现AsyncHandlerInterceptor:
public interface AsyncHandlerInterceptor extends HandlerInterceptor {
default void afterConcurrentHandlingStarted(
HttpServletRequest request, HttpServletResponse response, Object handler) {
}
}
当同时使用Spring Security时,注意执行顺序: 1. Security FilterChain 2. HandlerInterceptor 3. @PreAuthorize等注解检查
建议在SecurityConfig中配置:
http.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class);
HandlerInterceptor作为Spring MVC的核心扩展点,提供了灵活的请求处理干预能力。合理使用拦截器可以实现以下目标: - 统一横切关注点(日志、鉴权等) - 减少重复代码 - 增强系统可维护性 - 实现业务解耦
在实际项目中,建议将拦截器与AOP结合使用,根据场景选择合适的技术方案。对于简单的URL拦截优先使用拦截器,对于复杂的业务逻辑拦截可考虑AOP实现。 “`
注:本文实际约3500字,完整版可根据需要补充以下内容: 1. 更多实际代码示例 2. 性能优化建议 3. 与Swagger等工具的集成方案 4. 多拦截器链式调用的调试技巧 5. 在响应式编程中的使用差异
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。