/* * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.web.reactive.config; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import reactor.core.converter.DependencyUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.codec.Decoder; import org.springframework.core.codec.Encoder; import org.springframework.core.codec.ByteBufferDecoder; import org.springframework.core.codec.ByteBufferEncoder; import org.springframework.core.convert.support.PublisherToFluxConverter; import org.springframework.http.codec.json.JacksonJsonDecoder; import org.springframework.http.codec.json.JacksonJsonEncoder; import org.springframework.http.codec.xml.Jaxb2Decoder; import org.springframework.http.codec.xml.Jaxb2Encoder; import org.springframework.core.codec.StringDecoder; import org.springframework.core.codec.StringEncoder; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.core.convert.support.MonoToCompletableFutureConverter; import org.springframework.core.convert.support.ReactorToRxJava1Converter; import org.springframework.format.Formatter; import org.springframework.http.MediaType; import org.springframework.http.codec.SseEventEncoder; import org.springframework.http.converter.reactive.CodecHttpMessageConverter; import org.springframework.http.converter.reactive.HttpMessageConverter; import org.springframework.http.converter.reactive.ResourceHttpMessageConverter; import org.springframework.util.ClassUtils; import org.springframework.validation.Errors; import org.springframework.validation.Validator; import org.springframework.web.reactive.accept.RequestedContentTypeResolver; import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder; import org.springframework.web.reactive.result.SimpleHandlerAdapter; import org.springframework.web.reactive.result.SimpleResultHandler; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler; import org.springframework.web.reactive.result.method.annotation.ResponseEntityResultHandler; import org.springframework.web.reactive.result.view.ViewResolutionResultHandler; import org.springframework.web.reactive.result.view.ViewResolver; /** * The main class for Spring Web Reactive configuration. * *
Import directly or extend and override protected methods to customize.
*
* @author Rossen Stoyanchev
*/
@Configuration @SuppressWarnings("unused")
public class WebReactiveConfiguration implements ApplicationContextAware {
private static final ClassLoader classLoader = WebReactiveConfiguration.class.getClassLoader();
private static final boolean jackson2Present =
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
private static final boolean jaxb2Present =
ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
private PathMatchConfigurer pathMatchConfigurer;
private List Use {@link #configureMessageConverters} to configure the list or
* {@link #extendMessageConverters} to add in addition to the default ones.
*/
protected final List If no converters are specified, default will be added via
* {@link #addDefaultHttpMessageConverters}.
* @param converters a list to add converters to, initially an empty
*/
protected void configureMessageConverters(List By default this method method registers:
* Delegates to {@link #getValidator()} first. If that returns {@code null}
* checks the classpath for the presence of a JSR-303 implementations
* before creating a {@code OptionalValidatorFactoryBean}. If a JSR-303
* implementation is not available, a "no-op" {@link Validator} is returned.
*/
@Bean
public Validator mvcValidator() {
Validator validator = getValidator();
if (validator == null) {
if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) {
Class> clazz;
try {
String name = "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean";
clazz = ClassUtils.forName(name, classLoader);
}
catch (ClassNotFoundException ex) {
throw new BeanInitializationException("Could not find default validator class", ex);
}
catch (LinkageError ex) {
throw new BeanInitializationException("Could not load default validator class", ex);
}
validator = (Validator) BeanUtils.instantiate(clazz);
}
else {
validator = new NoOpValidator();
}
}
return validator;
}
/**
* Override this method to provide a custom {@link Validator}.
*/
protected Validator getValidator() {
return null;
}
@Bean
public SimpleHandlerAdapter simpleHandlerAdapter() {
return new SimpleHandlerAdapter();
}
@Bean
public SimpleResultHandler simpleResultHandler() {
return new SimpleResultHandler(mvcConversionService());
}
@Bean
public ResponseEntityResultHandler responseEntityResultHandler() {
return new ResponseEntityResultHandler(getMessageConverters(), mvcConversionService(),
mvcContentTypeResolver());
}
@Bean
public ResponseBodyResultHandler responseBodyResultHandler() {
return new ResponseBodyResultHandler(getMessageConverters(), mvcConversionService(),
mvcContentTypeResolver());
}
@Bean
public ViewResolutionResultHandler viewResolutionResultHandler() {
ViewResolverRegistry registry = new ViewResolverRegistry(this.applicationContext);
configureViewResolvers(registry);
List
*
*/
protected void addFormatters(ConverterRegistry registry) {
registry.addConverter(new MonoToCompletableFutureConverter());
registry.addConverter(new PublisherToFluxConverter());
if (DependencyUtils.hasRxJava1()) {
registry.addConverter(new ReactorToRxJava1Converter());
}
}
/**
* Return a global {@link Validator} instance for example for validating
* {@code @RequestBody} method arguments.
*