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

WebFlux如何处理404等全局错误?@RestControllerAdvice无法捕获404/500

嘿,我来帮你搞定WebFlux里全局错误处理的问题~

首先得搞清楚为啥你现有的@RestControllerAdvice + @ExceptionHandler处理不了404、500这类错误:它们只能捕获控制器方法执行过程中抛出的异常,而像路由匹配失败(404)、服务器底层错误(500)这类问题,很多是在请求还没到达控制器的时候就触发了,所以不在它的处理范围内。

下面是WebFlux专门处理这类全局错误的方案:

WebFlux全局错误处理实现

1. 自定义ErrorWebExceptionHandler

这是WebFlux处理全局错误的核心接口,实现它就能接管所有错误的处理逻辑,包括那些控制器层面捕获不到的底层错误:

import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.server.NoHandlerFoundException;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class GlobalErrorWebExceptionHandler implements ErrorWebExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalErrorWebExceptionHandler.class);

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        // 记录错误日志
        logger.error("全局错误捕获: ", ex);

        // 初始化错误码和HTTP状态
        String errorCode = Global.ERR_UNKNOWN;
        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;

        // 根据异常类型匹配处理逻辑
        if (ex instanceof ResponseStatusException) {
            ResponseStatusException rspEx = (ResponseStatusException) ex;
            status = rspEx.getStatus();
            switch (status) {
                case NOT_FOUND:
                    errorCode = Global.ERR_NOT_FOUND; // 自定义404错误码
                    break;
                case METHOD_NOT_ALLOWED:
                    errorCode = Global.ERR_HTTP_METHOD;
                    break;
                default:
                    break;
            }
        } else if (ex instanceof NoHandlerFoundException) {
            // 路由未匹配的404场景
            status = HttpStatus.NOT_FOUND;
            errorCode = Global.ERR_NOT_FOUND;
        }

        // 设置响应头和状态码
        exchange.getResponse().setStatusCode(status);
        exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);

        // 构建自定义响应体(这里用JSON字符串示例,你可以改成业务需要的DTO)
        String responseBody = String.format("{\"code\":\"%s\",\"message\":\"%s\"}", errorCode, ex.getMessage());
        return exchange.getResponse()
                .writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(responseBody.getBytes())));
    }
}

2. 禁用默认白标错误页面(可选)

如果不想用Spring Boot默认的白标错误页面,可以在配置文件里关闭:

spring:
  webflux:
    error:
      whitelabel:
        enabled: false

3. 额外说明

  • 这个自定义处理器会捕获所有WebFlux流程中的错误,完全覆盖你之前处理不了的404、500等场景。
  • 它和你现有的@RestControllerAdvice可以共存:控制器方法内抛出的异常会优先被@ExceptionHandler捕获,没被捕获的才会走到这个全局错误处理器。
  • 你可以根据业务需求,把响应体改成更规范的DTO对象,比如定义一个ErrorResponse类,序列化成JSON返回。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:17:35