SpringMVC HandlerInterceptor拦截器的使用与参数是什么

发布时间:2022-01-19 09:11:02 作者:柒染
来源:亿速云 阅读:204
# 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 {
    }
}

1.2 拦截器与过滤器的区别

特性 HandlerInterceptor Filter
所属规范 Spring MVC特有 Servlet规范
执行位置 DispatcherServlet之后 Servlet容器级别
依赖关系 需要Spring容器支持 不依赖Spring
获取上下文 可以获取Spring上下文 无法直接获取
控制粒度 方法级别拦截 URL级别拦截

二、核心方法详解

2.1 preHandle方法

在处理器方法执行前被调用,是最常用的拦截点。

参数说明: - 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;
}

2.2 postHandle方法

在处理器方法执行后,视图渲染前被调用。

新增参数: - 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");
    }
}

2.3 afterCompletion方法

在整个请求完成(视图渲染完毕)后执行。

新增参数: - 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);
    }
}

三、高级配置技巧

3.1 拦截器注册方式

通过WebMvcConfigurer实现配置:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/public/**");
    }
}

3.2 路径匹配模式

支持Ant风格路径匹配: - ? 匹配单个字符 - * 匹配0或多个字符 - ** 匹配0或多个目录

示例:

.addPathPatterns("/user/*/profile")  // 匹配/user/123/profile
.addPathPatterns("/admin/**")       // 匹配所有/admin/下的路径

3.3 拦截器执行顺序

通过order方法控制顺序(数值越小优先级越高):

registry.addInterceptor(new LogInterceptor()).order(1);
registry.addInterceptor(new AuthInterceptor()).order(2);

四、实战应用案例

4.1 性能监控拦截器

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();
    }
}

4.2 接口幂等性检查

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;
    }
}

五、常见问题排查

5.1 拦截器不生效的可能原因

  1. 配置未加载:检查@Configuration类是否被扫描
  2. 路径不匹配:确认addPathPatterns配置正确
  3. 顺序问题:其他拦截器中断了执行链
  4. Spring版本差异:注意Spring Boot 2.x与3.x的配置差异

5.2 获取控制器方法信息

if (handler instanceof HandlerMethod) {
    HandlerMethod handlerMethod = (HandlerMethod) handler;
    Method method = handlerMethod.getMethod();
    // 获取方法上的注解
    RequestMapping annotation = method.getAnnotation(RequestMapping.class);
}

六、扩展进阶

6.1 异步请求处理

对于异步请求(Callable/DeferredResult),需要实现AsyncHandlerInterceptor:

public interface AsyncHandlerInterceptor extends HandlerInterceptor {
    default void afterConcurrentHandlingStarted(
            HttpServletRequest request, HttpServletResponse response, Object handler) {
    }
}

6.2 与Spring Security集成

当同时使用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. 在响应式编程中的使用差异

推荐阅读:
  1. SpringCloud使用HandlerInterceptor拦截器
  2. springmvc怎样使用POJO作为参数

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springmvc handlerinterceptor

上一篇:k8s中kubeconfig怎么配置使用

下一篇:html5中有哪些常用框架

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》