千家信息网

spring boot中ErrorWebFluxAutoConfiguration的作用是什么

发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,spring boot中ErrorWebFluxAutoConfiguration的作用是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问
千家信息网最后更新 2025年01月24日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的作用是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

方法 接口 信息 作用 内容 更多 格式 错误 问题 束手无策 为此 三个 原因 子类 对此 小结 技能 标识 篇文章 类名 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 云顶之弈两个不同的服务器 网络安全公需科目考试答案 医院管理数据库模块详细介绍 如何上传文件至PDB数据库 什么是网络技术发展的动力 服务器ecs卡 河源宇辰网络技术服务中心 连接数据库的三个类 维护网络安全 守护家园安全 身边的网络安全作文题目 华为数据库产品技术部 关于增强网络安全意识的对联 后勤综合管理软件开发 广州报修管理软件开发 北京现代软件开发出厂价格 网络安全问题很到位 服务器自动开关机怎么固定时间 上海芈咖互联网科技中心 c软件开发用到的技术 游戏服务器多少电脑 mac连接远程服务器热键问题 服务器上的iis 公安联考职位与网络安全与执法 java 存储图片数据库 点餐系统软件开发计划书 武汉大学国家网络安全学院金明 hmoe11服务器无响应 网络技术在特殊教育的发展 网狐荣耀数据库表 网络安全连环画四格
0