You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot过滤器中HandlerExceptionResolver处理异常无响应问题

问题分析与解决方案

问题现象

使用Spring Boot 3.4.0,在JwtAuthenticationFilter过滤器中捕获ValidationException后调用HandlerExceptionResolver处理,断点和日志显示异常已进入GlobalExceptionHandler的处理方法,但最终响应体为空,仅返回400状态码。

核心原因

  1. 过滤器链未终止:调用resolver.resolveException()后,未中断过滤器链,后续的Spring Security过滤器可能重置或覆盖了响应内容。
  2. HandlerExceptionResolver注入不准确:默认的handlerExceptionResolver是Composite组合类型,可能未正确关联到@RestControllerAdvice对应的ExceptionHandlerExceptionResolver处理器。

解决方案

方案1:终止过滤器链处理

在调用异常解析方法后直接返回,不再执行后续过滤器逻辑:

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;

    @Override
    protected void doFilterInternal(
            HttpServletRequest request, 
            HttpServletResponse response, 
            FilterChain filterChain) throws ServletException, IOException {
        
        String token = request.getHeader("Authorization");
        
        try {
            if (token.startsWith("Basic ")) {
                String codeId = request.getParameter("codeId");
                String text = request.getParameter("text");
                CaptchaCode captchaCode = new CaptchaCode(codeId, text, null);
                captchaCodeApplicationService.isCoptchaCodeValid(captchaCode);
            }
            // 其他业务逻辑...
            
            // 无异常时继续执行过滤器链
            filterChain.doFilter(request, response);
        } catch (ValidationException e) {
            resolver.resolveException(request, response, null, e);
            // 终止过滤器链,避免后续逻辑覆盖响应
            return;
        }
    }
}

方案2:注入正确的ExceptionHandlerExceptionResolver

直接注入对应@RestControllerAdvice的处理器,确保异常处理逻辑匹配:

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    // 直接注入@RestControllerAdvice对应的异常处理器
    @Autowired
    private ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver;

    @Override
    protected void doFilterInternal(
            HttpServletRequest request, 
            HttpServletResponse response, 
            FilterChain filterChain) throws ServletException, IOException {
        
        String token = request.getHeader("Authorization");
        
        try {
            if (token.startsWith("Basic ")) {
                String codeId = request.getParameter("codeId");
                String text = request.getParameter("text");
                CaptchaCode captchaCode = new CaptchaCode(codeId, text, null);
                captchaCodeApplicationService.isCoptchaCodeValid(captchaCode);
            }
            // 其他业务逻辑...
            
            filterChain.doFilter(request, response);
        } catch (ValidationException e) {
            exceptionHandlerExceptionResolver.resolveException(request, response, null, e);
            return;
        }
    }
}

方案3:强制提交响应(可选)

如果前两种方案仍不生效,可手动强制提交响应内容:

catch (ValidationException e) {
    resolver.resolveException(request, response, null, e);
    // 强制刷新响应缓冲区,确保内容输出
    response.flushBuffer();
    return;
}

额外验证点

  • 确认ExceptionDetails类存在完整的getter方法,保证JSON序列化正常。
  • 检查Spring Security过滤器顺序,确保JwtAuthenticationFilter的执行时机不会被后续过滤器干扰响应。

内容的提问来源于stack exchange,提问作者Albert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 10:08:18