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
相关产品推荐
相关产品推荐

