001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.autoconfigure.web.reactive.error; 018 019import java.util.List; 020import java.util.stream.Collectors; 021 022import org.springframework.beans.factory.ObjectProvider; 023import org.springframework.boot.autoconfigure.AutoConfigureBefore; 024import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 025import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 026import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 027import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 028import org.springframework.boot.autoconfigure.condition.SearchStrategy; 029import org.springframework.boot.autoconfigure.web.ResourceProperties; 030import org.springframework.boot.autoconfigure.web.ServerProperties; 031import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; 032import org.springframework.boot.context.properties.EnableConfigurationProperties; 033import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; 034import org.springframework.boot.web.reactive.error.ErrorAttributes; 035import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; 036import org.springframework.context.ApplicationContext; 037import org.springframework.context.annotation.Bean; 038import org.springframework.context.annotation.Configuration; 039import org.springframework.core.annotation.Order; 040import org.springframework.http.codec.ServerCodecConfigurer; 041import org.springframework.web.reactive.config.WebFluxConfigurer; 042import org.springframework.web.reactive.result.view.ViewResolver; 043 044/** 045 * {@link EnableAutoConfiguration Auto-configuration} to render errors via a WebFlux 046 * {@link org.springframework.web.server.WebExceptionHandler}. 047 * 048 * @author Brian Clozel 049 * @since 2.0.0 050 */ 051@Configuration 052@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) 053@ConditionalOnClass(WebFluxConfigurer.class) 054@AutoConfigureBefore(WebFluxAutoConfiguration.class) 055@EnableConfigurationProperties({ ServerProperties.class, ResourceProperties.class }) 056public class ErrorWebFluxAutoConfiguration { 057 058 private final ServerProperties serverProperties; 059 060 private final ApplicationContext applicationContext; 061 062 private final ResourceProperties resourceProperties; 063 064 private final List<ViewResolver> viewResolvers; 065 066 private final ServerCodecConfigurer serverCodecConfigurer; 067 068 public ErrorWebFluxAutoConfiguration(ServerProperties serverProperties, 069 ResourceProperties resourceProperties, 070 ObjectProvider<ViewResolver> viewResolversProvider, 071 ServerCodecConfigurer serverCodecConfigurer, 072 ApplicationContext applicationContext) { 073 this.serverProperties = serverProperties; 074 this.applicationContext = applicationContext; 075 this.resourceProperties = resourceProperties; 076 this.viewResolvers = viewResolversProvider.orderedStream() 077 .collect(Collectors.toList()); 078 this.serverCodecConfigurer = serverCodecConfigurer; 079 } 080 081 @Bean 082 @ConditionalOnMissingBean(value = ErrorWebExceptionHandler.class, search = SearchStrategy.CURRENT) 083 @Order(-1) 084 public ErrorWebExceptionHandler errorWebExceptionHandler( 085 ErrorAttributes errorAttributes) { 086 DefaultErrorWebExceptionHandler exceptionHandler = new DefaultErrorWebExceptionHandler( 087 errorAttributes, this.resourceProperties, 088 this.serverProperties.getError(), this.applicationContext); 089 exceptionHandler.setViewResolvers(this.viewResolvers); 090 exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters()); 091 exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders()); 092 return exceptionHandler; 093 } 094 095 @Bean 096 @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT) 097 public DefaultErrorAttributes errorAttributes() { 098 return new DefaultErrorAttributes( 099 this.serverProperties.getError().isIncludeException()); 100 } 101 102}