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

Spring 3中ResponseStatusException异常处理器未触发问题排查

ResponseStatusException全局异常处理器不生效的解决方案

核心原因分析

  1. Web与WebFlux依赖冲突
    你的pom同时引入了spring-boot-starter-web(Servlet栈)和spring-boot-starter-webflux(Reactive栈),Spring Boot会自动切换到Reactive环境,而@ControllerAdvice是Servlet栈的异常处理注解,在Reactive环境下无法正常触发。

  2. ResponseEntityExceptionHandler默认处理优先级更高
    你继承的ResponseEntityExceptionHandler本身已经内置了对ResponseStatusException的处理逻辑,其优先级高于自定义的@ExceptionHandler方法,导致自定义代码被覆盖。

针对性解决方案

方案一:移除WebFlux依赖(推荐,若无需Reactive功能)

如果项目不需要响应式编程能力,直接删除pom中的spring-boot-starter-webflux依赖,Spring Boot会自动切换回Servlet栈,自定义的@ControllerAdvice处理器就能正常拦截ResponseStatusException。

方案二:适配Reactive环境异常处理(若必须保留WebFlux)

改用Reactive环境的全局异常处理方式,修改处理器代码如下:

@RestControllerAdvice
public class ErrorHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @ExceptionHandler(ResponseStatusException.class)
    public Mono<ResponseEntity<Object>> handleResponseStatusException(ResponseStatusException e) {
        ObjectNode node = objectMapper.createObjectNode()
                .put("code", e.getStatusCode().value())
                .put("details", e.getMessage());

        return Mono.just(ResponseEntity.status(e.getStatusCode())
                .contentType(MediaType.APPLICATION_JSON)
                .body(node));
    }
}

也可以实现ErrorWebExceptionHandler接口,更灵活地处理Reactive环境下的全局异常。

方案三:覆盖ResponseEntityExceptionHandler的默认处理

如果坚持使用Servlet栈且保留继承关系,重写父类的handleExceptionInternal方法,优先处理ResponseStatusException:

@ControllerAdvice
public class ErrorHandler extends ResponseEntityExceptionHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatusCode statusCode, WebRequest request) {
        if (ex instanceof ResponseStatusException responseEx) {
            ObjectNode node = objectMapper.createObjectNode()
                    .put("code", responseEx.getStatusCode().value())
                    .put("details", responseEx.getMessage());
            return ResponseEntity.status(responseEx.getStatusCode())
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(node);
        }
        return super.handleExceptionInternal(ex, body, headers, statusCode, request);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:46:01