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

Webflux中DefaultErrorWebExceptionHandler与@ControllerAdvice的冲突解决

解决GlobalErrorWebExceptionHandler与ExceptionHandling的冲突问题

在Spring WebFlux中,实现了ProblemHandling的@ControllerAdvice类会优先拦截控制器抛出的异常,而你的GlobalErrorWebExceptionHandler作为全局错误处理器在下游生效,所以引入前者后,原本该由后者处理的输入无效请求被前者接管了。下面是几种可行的解决办法:

方案1:限定ExceptionHandling的处理范围

让ExceptionHandling只处理你需要的特定异常,把输入验证类异常(比如MethodArgumentNotValidException、BindException)排除,让这类异常交给GlobalErrorWebExceptionHandler处理。

修改后的ExceptionHandling代码示例:

@ControllerAdvice
public class ExceptionHandling implements ProblemHandling {

    // 仅处理自定义业务异常
    @ExceptionHandler(CustomBusinessException.class)
    public ResponseEntity<Problem> handleCustomBusinessException(CustomBusinessException ex) {
        return create(ex, Status.INTERNAL_SERVER_ERROR);
    }

    // 覆盖默认方法,跳过输入验证异常的处理,让异常继续向下传递
    @Override
    public ResponseEntity<Problem> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, NativeWebRequest request) {
        return null;
    }

    @Override
    public ResponseEntity<Problem> handleBindException(BindException ex, NativeWebRequest request) {
        return null;
    }
}

方案2:调整两者的优先级顺序

给ExceptionHandling添加@Order注解,让它的优先级低于GlobalErrorWebExceptionHandler(你已经给后者加了@Order(-2),所以给前者设一个更大的数值即可):

@ControllerAdvice
@Order(1) // 数值越大优先级越低,确保比-2大
public class ExceptionHandling implements ProblemHandling {
    // 你的handler方法
}

同时修改GlobalErrorWebExceptionHandler,遇到需要交给ExceptionHandling处理的异常时重新抛出:

@Override
protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
    Throwable error = getError(request);
    // 如果是业务异常,抛出给ExceptionHandling处理
    if (error instanceof CustomBusinessException) {
        return Mono.error(error);
    }
    // 其他异常按原逻辑返回
    Map<String, Object> errorPropertiesMap = getErrorAttributes(request, ErrorAttributeOptions.defaults());
    return ServerResponse.status(HttpStatus.BAD_REQUEST)
            .contentType(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromValue(errorPropertiesMap));
}

方案3:自定义ProblemHandling的异常筛选逻辑

重写ProblemHandling的supports方法,指定只处理特定类型的异常:

@ControllerAdvice
public class ExceptionHandling implements ProblemHandling {

    @Override
    public boolean supports(Class<? extends Throwable> type) {
        // 仅处理自定义业务异常,排除输入验证相关异常
        return CustomBusinessException.class.isAssignableFrom(type)
                && !MethodArgumentNotValidException.class.isAssignableFrom(type)
                && !BindException.class.isAssignableFrom(type);
    }

    // 你的handler方法
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 12:41:15