Spring Boot过滤器中HandlerExceptionResolver处理异常无响应问题
问题分析与解决方案
问题现象
使用Spring Boot 3.4.0,在JwtAuthenticationFilter过滤器中捕获ValidationException后调用HandlerExceptionResolver处理,断点和日志显示异常已进入GlobalExceptionHandler的处理方法,但最终响应体为空,仅返回400状态码。
核心原因
- 过滤器链未终止:调用
resolver.resolveException()后,未中断过滤器链,后续的Spring Security过滤器可能重置或覆盖了响应内容。 - 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
相关产品推荐
相关产品推荐

