千家信息网

spring boot中ErrorWebFluxAutoConfiguration的作用是什么

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,spring boot中ErrorWebFluxAutoConfiguration的作用是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问
千家信息网最后更新 2026年11月01日spring boot中ErrorWebFluxAutoConfiguration的作用是什么

spring boot中ErrorWebFluxAutoConfiguration的作用是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

ErrorWebFluxAutoConfiguration

spring-boot-autoconfigure-2.1.5.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/web/reactive/error/ErrorWebFluxAutoConfiguration.java

@Configuration@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)@ConditionalOnClass(WebFluxConfigurer.class)@AutoConfigureBefore(WebFluxAutoConfiguration.class)@EnableConfigurationProperties({ ServerProperties.class, ResourceProperties.class })public class ErrorWebFluxAutoConfiguration {        private final ServerProperties serverProperties;        private final ApplicationContext applicationContext;        private final ResourceProperties resourceProperties;        private final List viewResolvers;        private final ServerCodecConfigurer serverCodecConfigurer;        public ErrorWebFluxAutoConfiguration(ServerProperties serverProperties,                        ResourceProperties resourceProperties,                        ObjectProvider viewResolversProvider,                        ServerCodecConfigurer serverCodecConfigurer,                        ApplicationContext applicationContext) {                this.serverProperties = serverProperties;                this.applicationContext = applicationContext;                this.resourceProperties = resourceProperties;                this.viewResolvers = viewResolversProvider.orderedStream()                                .collect(Collectors.toList());                this.serverCodecConfigurer = serverCodecConfigurer;        }        @Bean        @ConditionalOnMissingBean(value = ErrorWebExceptionHandler.class,                        search = SearchStrategy.CURRENT)        @Order(-1)        public ErrorWebExceptionHandler errorWebExceptionHandler(                        ErrorAttributes errorAttributes) {                DefaultErrorWebExceptionHandler exceptionHandler = new DefaultErrorWebExceptionHandler(                                errorAttributes, this.resourceProperties,                                this.serverProperties.getError(), this.applicationContext);                exceptionHandler.setViewResolvers(this.viewResolvers);                exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());                exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());                return exceptionHandler;        }        @Bean        @ConditionalOnMissingBean(value = ErrorAttributes.class,                        search = SearchStrategy.CURRENT)        public DefaultErrorAttributes errorAttributes() {                return new DefaultErrorAttributes(                                this.serverProperties.getError().isIncludeException());        }}
  • ErrorWebFluxAutoConfiguration注册了DefaultErrorAttributes、ErrorWebExceptionHandler

ErrorAttributes

spring-boot-2.1.5.RELEASE-sources.jar!/org/springframework/boot/web/reactive/error/ErrorAttributes.java

public interface ErrorAttributes {        /**         * Return a {@link Map} of the error attributes. The map can be used as the model of         * an error page, or returned as a {@link ServerResponse} body.         * @param request the source request         * @param includeStackTrace if stack trace elements should be included         * @return a map of error attributes         */        Map getErrorAttributes(ServerRequest request,                        boolean includeStackTrace);        /**         * Return the underlying cause of the error or {@code null} if the error cannot be         * extracted.         * @param request the source ServerRequest         * @return the {@link Exception} that caused the error or {@code null}         */        Throwable getError(ServerRequest request);        /**         * Store the given error information in the current {@link ServerWebExchange}.         * @param error the {@link Exception} that caused the error         * @param exchange the source exchange         */        void storeErrorInformation(Throwable error, ServerWebExchange exchange);}
  • ErrorAttributes接口定义了getErrorAttributes、getError、storeErrorInformation三个方法

DefaultErrorAttributes

spring-boot-2.1.5.RELEASE-sources.jar!/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java

public class DefaultErrorAttributes implements ErrorAttributes {        private static final String ERROR_ATTRIBUTE = DefaultErrorAttributes.class.getName()                        + ".ERROR";        private final boolean includeException;        /**         * Create a new {@link DefaultErrorAttributes} instance that does not include the         * "exception" attribute.         */        public DefaultErrorAttributes() {                this(false);        }        /**         * Create a new {@link DefaultErrorAttributes} instance.         * @param includeException whether to include the "exception" attribute         */        public DefaultErrorAttributes(boolean includeException) {                this.includeException = includeException;        }        @Override        public Map getErrorAttributes(ServerRequest request,                        boolean includeStackTrace) {                Map errorAttributes = new LinkedHashMap<>();                errorAttributes.put("timestamp", new Date());                errorAttributes.put("path", request.path());                Throwable error = getError(request);                HttpStatus errorStatus = determineHttpStatus(error);                errorAttributes.put("status", errorStatus.value());                errorAttributes.put("error", errorStatus.getReasonPhrase());                errorAttributes.put("message", determineMessage(error));                handleException(errorAttributes, determineException(error), includeStackTrace);                return errorAttributes;        }        private HttpStatus determineHttpStatus(Throwable error) {                if (error instanceof ResponseStatusException) {                        return ((ResponseStatusException) error).getStatus();                }                ResponseStatus responseStatus = AnnotatedElementUtils                                .findMergedAnnotation(error.getClass(), ResponseStatus.class);                if (responseStatus != null) {                        return responseStatus.code();                }                return HttpStatus.INTERNAL_SERVER_ERROR;        }        private String determineMessage(Throwable error) {                if (error instanceof WebExchangeBindException) {                        return error.getMessage();                }                if (error instanceof ResponseStatusException) {                        return ((ResponseStatusException) error).getReason();                }                ResponseStatus responseStatus = AnnotatedElementUtils                                .findMergedAnnotation(error.getClass(), ResponseStatus.class);                if (responseStatus != null) {                        return responseStatus.reason();                }                return error.getMessage();        }        private Throwable determineException(Throwable error) {                if (error instanceof ResponseStatusException) {                        return (error.getCause() != null) ? error.getCause() : error;                }                return error;        }        private void addStackTrace(Map errorAttributes, Throwable error) {                StringWriter stackTrace = new StringWriter();                error.printStackTrace(new PrintWriter(stackTrace));                stackTrace.flush();                errorAttributes.put("trace", stackTrace.toString());        }        private void handleException(Map errorAttributes, Throwable error,                        boolean includeStackTrace) {                if (this.includeException) {                        errorAttributes.put("exception", error.getClass().getName());                }                if (includeStackTrace) {                        addStackTrace(errorAttributes, error);                }                if (error instanceof BindingResult) {                        BindingResult result = (BindingResult) error;                        if (result.hasErrors()) {                                errorAttributes.put("errors", result.getAllErrors());                        }                }        }        @Override        public Throwable getError(ServerRequest request) {                return (Throwable) request.attribute(ERROR_ATTRIBUTE)                                .orElseThrow(() -> new IllegalStateException(                                                "Missing exception attribute in ServerWebExchange"));        }        @Override        public void storeErrorInformation(Throwable error, ServerWebExchange exchange) {                exchange.getAttributes().putIfAbsent(ERROR_ATTRIBUTE, error);        }}
  • DefaultErrorAttributes实现了ErrorAttributes接口,它的getErrorAttributes方法会返回timestamp、path、status、error、message、exception(includeException)、trace(includeStackTrace)等信息;getError方法会从ServerRequest的ERROR_ATTRIBUTE中获取Throwable;storeErrorInformation则是把Throwable存放到ServerWebExchange的attributes中

WebExceptionHandler

spring-web-5.1.7.RELEASE-sources.jar!/org/springframework/web/server/WebExceptionHandler.java

public interface WebExceptionHandler {        /**         * Handle the given exception. A completion signal through the return value         * indicates error handling is complete while an error signal indicates the         * exception is still not handled.         * @param exchange the current exchange         * @param ex the exception to handle         * @return {@code Mono} to indicate when exception handling is complete         */        Mono handle(ServerWebExchange exchange, Throwable ex);}
  • WebExceptionHandler定义了handle方法

ErrorWebExceptionHandler

spring-boot-2.1.5.RELEASE-sources.jar!/org/springframework/boot/web/reactive/error/ErrorWebExceptionHandler.java

@FunctionalInterfacepublic interface ErrorWebExceptionHandler extends WebExceptionHandler {}
  • ErrorWebExceptionHandler继承了WebExceptionHandler接口,仅仅是通过类名来标识它用来render errors

AbstractErrorWebExceptionHandler

public abstract class AbstractErrorWebExceptionHandler                implements ErrorWebExceptionHandler, InitializingBean {        /**         * Currently duplicated from Spring WebFlux HttpWebHandlerAdapter.         */        private static final Set DISCONNECTED_CLIENT_EXCEPTIONS;        static {                Set exceptions = new HashSet<>();                exceptions.add("AbortedException");                exceptions.add("ClientAbortException");                exceptions.add("EOFException");                exceptions.add("EofException");                DISCONNECTED_CLIENT_EXCEPTIONS = Collections.unmodifiableSet(exceptions);        }        private static final Log logger = HttpLogging                        .forLogName(AbstractErrorWebExceptionHandler.class);        private final ApplicationContext applicationContext;        private final ErrorAttributes errorAttributes;        private final ResourceProperties resourceProperties;        private final TemplateAvailabilityProviders templateAvailabilityProviders;        private List> messageReaders = Collections.emptyList();        private List> messageWriters = Collections.emptyList();        private List viewResolvers = Collections.emptyList();        public AbstractErrorWebExceptionHandler(ErrorAttributes errorAttributes,                        ResourceProperties resourceProperties,                        ApplicationContext applicationContext) {                Assert.notNull(errorAttributes, "ErrorAttributes must not be null");                Assert.notNull(resourceProperties, "ResourceProperties must not be null");                Assert.notNull(applicationContext, "ApplicationContext must not be null");                this.errorAttributes = errorAttributes;                this.resourceProperties = resourceProperties;                this.applicationContext = applicationContext;                this.templateAvailabilityProviders = new TemplateAvailabilityProviders(                                applicationContext);        }        //......        @Override        public void afterPropertiesSet() throws Exception {                if (CollectionUtils.isEmpty(this.messageWriters)) {                        throw new IllegalArgumentException("Property 'messageWriters' is required");                }        }        /**         * Create a {@link RouterFunction} that can route and handle errors as JSON responses         * or HTML views.         * 

* If the returned {@link RouterFunction} doesn't route to a {@code HandlerFunction}, * the original exception is propagated in the pipeline and can be processed by other * {@link org.springframework.web.server.WebExceptionHandler}s. * @param errorAttributes the {@code ErrorAttributes} instance to use to extract error * information * @return a {@link RouterFunction} that routes and handles errors */ protected abstract RouterFunction getRoutingFunction( ErrorAttributes errorAttributes); @Override public Mono handle(ServerWebExchange exchange, Throwable throwable) { if (exchange.getResponse().isCommitted() || isDisconnectedClientError(throwable)) { return Mono.error(throwable); } this.errorAttributes.storeErrorInformation(throwable, exchange); ServerRequest request = ServerRequest.create(exchange, this.messageReaders); return getRoutingFunction(this.errorAttributes).route(request) .switchIfEmpty(Mono.error(throwable)) .flatMap((handler) -> handler.handle(request)) .doOnNext((response) -> logError(request, response, throwable)) .flatMap((response) -> write(exchange, response)); } //......}

  • AbstractErrorWebExceptionHandler声明实现ErrorWebExceptionHandler以及InitializingBean接口;其handle方法首先把throwable存储到errorAttributes汇总,然后通过getRoutingFunction进行route;afterPropertiesSet主要是确保messageWriters不为空;它定义了getRoutingFunction要子类去实现

DefaultErrorWebExceptionHandler

spring-boot-autoconfigure-2.1.5.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java

public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {        private static final Map SERIES_VIEWS;        static {                Map views = new EnumMap<>(HttpStatus.Series.class);                views.put(HttpStatus.Series.CLIENT_ERROR, "4xx");                views.put(HttpStatus.Series.SERVER_ERROR, "5xx");                SERIES_VIEWS = Collections.unmodifiableMap(views);        }        private final ErrorProperties errorProperties;        /**         * Create a new {@code DefaultErrorWebExceptionHandler} instance.         * @param errorAttributes the error attributes         * @param resourceProperties the resources configuration properties         * @param errorProperties the error configuration properties         * @param applicationContext the current application context         */        public DefaultErrorWebExceptionHandler(ErrorAttributes errorAttributes,                        ResourceProperties resourceProperties, ErrorProperties errorProperties,                        ApplicationContext applicationContext) {                super(errorAttributes, resourceProperties, applicationContext);                this.errorProperties = errorProperties;        }        @Override        protected RouterFunction getRoutingFunction(                        ErrorAttributes errorAttributes) {                return route(acceptsTextHtml(), this::renderErrorView).andRoute(all(),                                this::renderErrorResponse);        }        /**         * Render the error information as an HTML view.         * @param request the current request         * @return a {@code Publisher} of the HTTP response         */        protected Mono renderErrorView(ServerRequest request) {                boolean includeStackTrace = isIncludeStackTrace(request, MediaType.TEXT_HTML);                Map error = getErrorAttributes(request, includeStackTrace);                HttpStatus errorStatus = getHttpStatus(error);                ServerResponse.BodyBuilder responseBody = ServerResponse.status(errorStatus)                                .contentType(MediaType.TEXT_HTML);                return Flux                                .just("error/" + errorStatus.value(),                                                "error/" + SERIES_VIEWS.get(errorStatus.series()), "error/error")                                .flatMap((viewName) -> renderErrorView(viewName, responseBody, error))                                .switchIfEmpty(this.errorProperties.getWhitelabel().isEnabled()                                                ? renderDefaultErrorView(responseBody, error)                                                : Mono.error(getError(request)))                                .next();        }        /**         * Render the error information as a JSON payload.         * @param request the current request         * @return a {@code Publisher} of the HTTP response         */        protected Mono renderErrorResponse(ServerRequest request) {                boolean includeStackTrace = isIncludeStackTrace(request, MediaType.ALL);                Map error = getErrorAttributes(request, includeStackTrace);                return ServerResponse.status(getHttpStatus(error))                                .contentType(MediaType.APPLICATION_JSON_UTF8)                                .body(BodyInserters.fromObject(error));        }        /**         * Determine if the stacktrace attribute should be included.         * @param request the source request         * @param produces the media type produced (or {@code MediaType.ALL})         * @return if the stacktrace attribute should be included         */        protected boolean isIncludeStackTrace(ServerRequest request, MediaType produces) {                ErrorProperties.IncludeStacktrace include = this.errorProperties                                .getIncludeStacktrace();                if (include == ErrorProperties.IncludeStacktrace.ALWAYS) {                        return true;                }                if (include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM) {                        return isTraceEnabled(request);                }                return false;        }        /**         * Get the HTTP error status information from the error map.         * @param errorAttributes the current error information         * @return the error HTTP status         */        protected HttpStatus getHttpStatus(Map errorAttributes) {                int statusCode = (int) errorAttributes.get("status");                return HttpStatus.valueOf(statusCode);        }        /**         * Predicate that checks whether the current request explicitly support         * {@code "text/html"} media type.         * 

* The "match-all" media type is not considered here. * @return the request predicate */ protected RequestPredicate acceptsTextHtml() { return (serverRequest) -> { try { List acceptedMediaTypes = serverRequest.headers().accept(); acceptedMediaTypes.remove(MediaType.ALL); MediaType.sortBySpecificityAndQuality(acceptedMediaTypes); return acceptedMediaTypes.stream() .anyMatch(MediaType.TEXT_HTML::isCompatibleWith); } catch (InvalidMediaTypeException ex) { return false; } }; }}

  • DefaultErrorWebExceptionHandler继承了AbstractErrorWebExceptionHandler;其getRoutingFunction方法会对acceptsTextHtml的renderErrorView,其他的通过renderErrorResponse来返回json格式的错误信息

ExceptionHandlingWebHandler

spring-web-5.1.7.RELEASE-sources.jar!/org/springframework/web/server/handler/ExceptionHandlingWebHandler.java

public class ExceptionHandlingWebHandler extends WebHandlerDecorator {        private final List exceptionHandlers;        public ExceptionHandlingWebHandler(WebHandler delegate, List handlers) {                super(delegate);                this.exceptionHandlers = Collections.unmodifiableList(new ArrayList<>(handlers));        }        /**         * Return a read-only list of the configured exception handlers.         */        public List getExceptionHandlers() {                return this.exceptionHandlers;        }        @Override        public Mono handle(ServerWebExchange exchange) {                Mono completion;                try {                        completion = super.handle(exchange);                }                catch (Throwable ex) {                        completion = Mono.error(ex);                }                for (WebExceptionHandler handler : this.exceptionHandlers) {                        completion = completion.onErrorResume(ex -> handler.handle(exchange, ex));                }                return completion;        }}
  • ExceptionHandlingWebHandler继承了WebHandlerDecorator,它会挨个调用WebExceptionHandler的handle方法

小结

  • ErrorWebFluxAutoConfiguration注册了DefaultErrorAttributes、ErrorWebExceptionHandler

  • DefaultErrorAttributes实现了ErrorAttributes接口,它的getErrorAttributes方法会返回timestamp、path、status、error、message、exception(includeException)、trace(includeStackTrace)等信息;getError方法会从ServerRequest的ERROR_ATTRIBUTE中获取Throwable;storeErrorInformation则是把Throwable存放到ServerWebExchange的attributes中

  • DefaultErrorWebExceptionHandler继承了AbstractErrorWebExceptionHandler;其getRoutingFunction方法会对acceptsTextHtml的renderErrorView,其他的通过renderErrorResponse来返回json格式的错误信息

看完上述内容,你们掌握spring boot中ErrorWebFluxAutoConfiguration的作用是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

0