Introduce ServerCodecConfigurer
Issue: SPR-15247
This commit is contained in:
@@ -21,8 +21,7 @@ import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
import org.springframework.http.codec.ServerHttpMessageReader;
|
||||
import org.springframework.http.codec.ServerHttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
import org.springframework.validation.Validator;
|
||||
@@ -76,13 +75,8 @@ public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureMessageReaders(List<ServerHttpMessageReader<?>> messageReaders) {
|
||||
this.configurers.configureMessageReaders(messageReaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendMessageReaders(List<ServerHttpMessageReader<?>> messageReaders) {
|
||||
this.configurers.extendMessageReaders(messageReaders);
|
||||
protected void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
|
||||
this.configurers.configureHttpMessageCodecs(configurer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,16 +94,6 @@ public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport
|
||||
return this.configurers.getMessageCodesResolver().orElse(super.getMessageCodesResolver());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureMessageWriters(List<ServerHttpMessageWriter<?>> messageWriters) {
|
||||
this.configurers.configureMessageWriters(messageWriters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendMessageWriters(List<ServerHttpMessageWriter<?>> messageWriters) {
|
||||
this.configurers.extendMessageWriters(messageWriters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureViewResolvers(ViewResolverRegistry registry) {
|
||||
this.configurers.configureViewResolvers(registry);
|
||||
|
||||
@@ -30,32 +30,13 @@ import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.ReactiveAdapterRegistry;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.codec.ByteArrayDecoder;
|
||||
import org.springframework.core.codec.ByteArrayEncoder;
|
||||
import org.springframework.core.codec.ByteBufferDecoder;
|
||||
import org.springframework.core.codec.ByteBufferEncoder;
|
||||
import org.springframework.core.codec.CharSequenceEncoder;
|
||||
import org.springframework.core.codec.DataBufferDecoder;
|
||||
import org.springframework.core.codec.DataBufferEncoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.core.codec.ResourceDecoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerHttpMessageReader;
|
||||
import org.springframework.http.codec.ServerHttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlDecoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
@@ -104,9 +85,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
|
||||
|
||||
private PathMatchConfigurer pathMatchConfigurer;
|
||||
|
||||
private List<ServerHttpMessageReader<?>> messageReaders;
|
||||
|
||||
private List<ServerHttpMessageWriter<?>> messageWriters;
|
||||
private ServerCodecConfigurer messageCodecsConfigurer;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@@ -267,7 +246,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
|
||||
@Bean
|
||||
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
|
||||
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
|
||||
adapter.setMessageReaders(getMessageReaders());
|
||||
adapter.setMessageReaders(getMessageCodecsConfigurer().getReaders());
|
||||
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());
|
||||
adapter.setReactiveAdapterRegistry(webFluxAdapterRegistry());
|
||||
|
||||
@@ -294,58 +273,22 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method to access message readers to use for decoding
|
||||
* controller method arguments with.
|
||||
* <p>Use {@link #configureMessageReaders} to configure the list or
|
||||
* {@link #extendMessageReaders} to add in addition to the default ones.
|
||||
* Main method to access the configurer for HTTP message readers and writers.
|
||||
* <p>Use {@link #configureHttpMessageCodecs(ServerCodecConfigurer)} to
|
||||
* configure the readers and writers.
|
||||
*/
|
||||
protected final List<ServerHttpMessageReader<?>> getMessageReaders() {
|
||||
if (this.messageReaders == null) {
|
||||
this.messageReaders = new ArrayList<>();
|
||||
configureMessageReaders(this.messageReaders);
|
||||
if (this.messageReaders.isEmpty()) {
|
||||
addDefaultHttpMessageReaders(this.messageReaders);
|
||||
}
|
||||
extendMessageReaders(this.messageReaders);
|
||||
protected final ServerCodecConfigurer getMessageCodecsConfigurer() {
|
||||
if (this.messageCodecsConfigurer == null) {
|
||||
this.messageCodecsConfigurer = new ServerCodecConfigurer();
|
||||
configureHttpMessageCodecs(this.getMessageCodecsConfigurer());
|
||||
}
|
||||
return this.messageReaders;
|
||||
return this.messageCodecsConfigurer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to configure the message readers to use for decoding
|
||||
* controller method arguments.
|
||||
* <p>If no message readres are specified, default will be added via
|
||||
* {@link #addDefaultHttpMessageReaders}.
|
||||
* @param messageReaders a list to add message readers to, initially an empty
|
||||
* Override to configure the HTTP message readers and writers to use.
|
||||
*/
|
||||
protected void configureMessageReaders(List<ServerHttpMessageReader<?>> messageReaders) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds default converters that sub-classes can call from
|
||||
* {@link #configureMessageReaders(List)} for {@code byte[]},
|
||||
* {@code ByteBuffer}, {@code String}, {@code Resource}, JAXB2, and Jackson
|
||||
* (if present on the classpath).
|
||||
*/
|
||||
protected final void addDefaultHttpMessageReaders(List<ServerHttpMessageReader<?>> readers) {
|
||||
readers.add(new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(new DataBufferDecoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
|
||||
readers.add(new DecoderHttpMessageReader<>(new ResourceDecoder()));
|
||||
if (jaxb2Present) {
|
||||
readers.add(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder()));
|
||||
}
|
||||
if (jackson2Present) {
|
||||
readers.add(new DecoderHttpMessageReader<>(new Jackson2JsonDecoder()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this to modify the list of message readers after it has been
|
||||
* configured, for example to add some in addition to the default ones.
|
||||
*/
|
||||
protected void extendMessageReaders(List<ServerHttpMessageReader<?>> messageReaders) {
|
||||
protected void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,76 +378,14 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
|
||||
|
||||
@Bean
|
||||
public ResponseEntityResultHandler responseEntityResultHandler() {
|
||||
return new ResponseEntityResultHandler(
|
||||
getMessageWriters(), webFluxContentTypeResolver(), webFluxAdapterRegistry());
|
||||
return new ResponseEntityResultHandler(getMessageCodecsConfigurer().getWriters(),
|
||||
webFluxContentTypeResolver(), webFluxAdapterRegistry());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ResponseBodyResultHandler responseBodyResultHandler() {
|
||||
return new ResponseBodyResultHandler(
|
||||
getMessageWriters(), webFluxContentTypeResolver(), webFluxAdapterRegistry());
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method to access message writers to use for encoding return values.
|
||||
* <p>Use {@link #configureMessageWriters(List)} to configure the list or
|
||||
* {@link #extendMessageWriters(List)} to add in addition to the default ones.
|
||||
*/
|
||||
protected final List<ServerHttpMessageWriter<?>> getMessageWriters() {
|
||||
if (this.messageWriters == null) {
|
||||
this.messageWriters = new ArrayList<>();
|
||||
configureMessageWriters(this.messageWriters);
|
||||
if (this.messageWriters.isEmpty()) {
|
||||
addDefaultHttpMessageWriters(this.messageWriters);
|
||||
}
|
||||
extendMessageWriters(this.messageWriters);
|
||||
}
|
||||
return this.messageWriters;
|
||||
}
|
||||
/**
|
||||
* Override to configure the message writers to use for encoding
|
||||
* return values.
|
||||
* <p>If no message readers are specified, default will be added via
|
||||
* {@link #addDefaultHttpMessageWriters}.
|
||||
* @param messageWriters a list to add message writers to, initially an empty
|
||||
*/
|
||||
protected void configureMessageWriters(List<ServerHttpMessageWriter<?>> messageWriters) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds default converters that sub-classes can call from
|
||||
* {@link #configureMessageWriters(List)}.
|
||||
*/
|
||||
protected final void addDefaultHttpMessageWriters(List<ServerHttpMessageWriter<?>> writers) {
|
||||
writers.add(new EncoderHttpMessageWriter<>(new ByteArrayEncoder()));
|
||||
writers.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
|
||||
writers.add(new EncoderHttpMessageWriter<>(new DataBufferEncoder()));
|
||||
writers.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly()));
|
||||
writers.add(new ResourceHttpMessageWriter());
|
||||
if (jaxb2Present) {
|
||||
writers.add(new EncoderHttpMessageWriter<>(new Jaxb2XmlEncoder()));
|
||||
}
|
||||
if (jackson2Present) {
|
||||
writers.add(new EncoderHttpMessageWriter<>(new Jackson2JsonEncoder()));
|
||||
}
|
||||
writers.add(new ServerSentEventHttpMessageWriter(getSseEncoder()));
|
||||
writers.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes()));
|
||||
}
|
||||
|
||||
private Encoder<?> getSseEncoder() {
|
||||
if (jackson2Present) {
|
||||
return new Jackson2JsonEncoder();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this to modify the list of message writers after it has been
|
||||
* configured, for example to add some in addition to the default ones.
|
||||
*/
|
||||
protected void extendMessageWriters(List<ServerHttpMessageWriter<?>> messageWriters) {
|
||||
return new ResponseBodyResultHandler(getMessageCodecsConfigurer().getWriters(),
|
||||
webFluxContentTypeResolver(), webFluxAdapterRegistry());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -22,8 +22,7 @@ import java.util.Optional;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
import org.springframework.http.codec.ServerHttpMessageReader;
|
||||
import org.springframework.http.codec.ServerHttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.reactive.accept.CompositeContentTypeResolver;
|
||||
@@ -89,22 +88,10 @@ public interface WebFluxConfigurer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the message readers to use for decoding the request body where
|
||||
* {@code @RequestBody} and {@code HttpEntity} controller method arguments
|
||||
* are used. If none are specified, default ones are added based on
|
||||
* {@link WebFluxConfigurationSupport#addDefaultHttpMessageReaders}.
|
||||
* <p>See {@link #extendMessageReaders(List)} for adding readers
|
||||
* in addition to the default ones.
|
||||
* @param readers an empty list to add message readers to
|
||||
* Configure custom HTTP message readers and writers or override built-in ones.
|
||||
* @param configurer the configurer to use
|
||||
*/
|
||||
default void configureMessageReaders(List<ServerHttpMessageReader<?>> readers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* An alternative to {@link #configureMessageReaders(List)} that allows
|
||||
* modifying the message readers to use after default ones have been added.
|
||||
*/
|
||||
default void extendMessageReaders(List<ServerHttpMessageReader<?>> readers) {
|
||||
default void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,25 +119,6 @@ public interface WebFluxConfigurer {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the message writers to use to encode the response body based on
|
||||
* the return values of {@code @ResponseBody}, and {@code ResponseEntity}
|
||||
* controller methods. If none are specified, default ones are added based on
|
||||
* {@link WebFluxConfigurationSupport#addDefaultHttpMessageWriters(List)}.
|
||||
* <p>See {@link #extendMessageWriters(List)} for adding writers
|
||||
* in addition to the default ones.
|
||||
* @param writers a empty list to add message writers to
|
||||
*/
|
||||
default void configureMessageWriters(List<ServerHttpMessageWriter<?>> writers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* An alternative to {@link #configureMessageWriters(List)} that allows
|
||||
* modifying the message writers to use after default ones have been added.
|
||||
*/
|
||||
default void extendMessageWriters(List<ServerHttpMessageWriter<?>> writers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure view resolution for processing the return values of controller
|
||||
* methods that rely on resolving a
|
||||
|
||||
@@ -23,8 +23,7 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
import org.springframework.http.codec.ServerHttpMessageReader;
|
||||
import org.springframework.http.codec.ServerHttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
import org.springframework.validation.Validator;
|
||||
@@ -52,42 +51,37 @@ public class WebFluxConfigurerComposite implements WebFluxConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.configureContentTypeResolver(builder));
|
||||
this.delegates.forEach(delegate -> delegate.configureContentTypeResolver(builder));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.addCorsMappings(registry));
|
||||
this.delegates.forEach(delegate -> delegate.addCorsMappings(registry));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configurePathMatching(PathMatchConfigurer configurer) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.configurePathMatching(configurer));
|
||||
this.delegates.forEach(delegate -> delegate.configurePathMatching(configurer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.addResourceHandlers(registry));
|
||||
this.delegates.forEach(delegate -> delegate.addResourceHandlers(registry));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.addArgumentResolvers(resolvers));
|
||||
this.delegates.forEach(delegate -> delegate.addArgumentResolvers(resolvers));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageReaders(List<ServerHttpMessageReader<?>> readers) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.configureMessageReaders(readers));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extendMessageReaders(List<ServerHttpMessageReader<?>> readers) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.extendMessageReaders(readers));
|
||||
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
|
||||
this.delegates.forEach(delegate -> delegate.configureHttpMessageCodecs(configurer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFormatters(FormatterRegistry registry) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.addFormatters(registry));
|
||||
this.delegates.forEach(delegate -> delegate.addFormatters(registry));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,19 +94,9 @@ public class WebFluxConfigurerComposite implements WebFluxConfigurer {
|
||||
return createSingleBean(WebFluxConfigurer::getMessageCodesResolver, MessageCodesResolver.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageWriters(List<ServerHttpMessageWriter<?>> writers) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.configureMessageWriters(writers));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extendMessageWriters(List<ServerHttpMessageWriter<?>> writers) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.extendMessageWriters(writers));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureViewResolvers(ViewResolverRegistry registry) {
|
||||
this.delegates.stream().forEach(delegate -> delegate.configureViewResolvers(registry));
|
||||
this.delegates.forEach(delegate -> delegate.configureViewResolvers(registry));
|
||||
}
|
||||
|
||||
private <T> Optional<T> createSingleBean(Function<WebFluxConfigurer, Optional<T>> factory,
|
||||
|
||||
@@ -26,26 +26,10 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.codec.ByteArrayDecoder;
|
||||
import org.springframework.core.codec.ByteArrayEncoder;
|
||||
import org.springframework.core.codec.ByteBufferDecoder;
|
||||
import org.springframework.core.codec.ByteBufferEncoder;
|
||||
import org.springframework.core.codec.CharSequenceEncoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.FormHttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlDecoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
|
||||
/**
|
||||
@@ -61,16 +45,6 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder {
|
||||
.map(Locale.LanguageRange::getRange)
|
||||
.map(Locale::forLanguageTag).findFirst();
|
||||
|
||||
private static final boolean jackson2Present =
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
|
||||
DefaultHandlerStrategiesBuilder.class.getClassLoader()) &&
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
|
||||
DefaultHandlerStrategiesBuilder.class.getClassLoader());
|
||||
|
||||
private static final boolean jaxb2Present =
|
||||
ClassUtils.isPresent("javax.xml.bind.Binder",
|
||||
DefaultHandlerStrategiesBuilder.class.getClassLoader());
|
||||
|
||||
|
||||
private final List<HttpMessageReader<?>> messageReaders = new ArrayList<>();
|
||||
|
||||
@@ -82,40 +56,12 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder {
|
||||
|
||||
|
||||
public void defaultConfiguration() {
|
||||
messageReader(new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
|
||||
messageReader(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
|
||||
messageReader(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
|
||||
messageReader(new FormHttpMessageReader());
|
||||
|
||||
messageWriter(new EncoderHttpMessageWriter<>(new ByteArrayEncoder()));
|
||||
messageWriter(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
|
||||
messageWriter(new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly()));
|
||||
messageWriter(new ResourceHttpMessageWriter());
|
||||
|
||||
if (jaxb2Present) {
|
||||
messageReader(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder()));
|
||||
messageWriter(new EncoderHttpMessageWriter<>(new Jaxb2XmlEncoder()));
|
||||
}
|
||||
if (jackson2Present) {
|
||||
messageReader(new DecoderHttpMessageReader<>(new Jackson2JsonDecoder()));
|
||||
messageWriter(new EncoderHttpMessageWriter<>(new Jackson2JsonEncoder()));
|
||||
}
|
||||
|
||||
messageWriter(new ServerSentEventHttpMessageWriter(getSseEncoder()));
|
||||
messageWriter(new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes()));
|
||||
|
||||
ServerCodecConfigurer configurer = new ServerCodecConfigurer();
|
||||
configurer.getReaders().forEach(this::messageReader);
|
||||
configurer.getWriters().forEach(this::messageWriter);
|
||||
localeResolver(DEFAULT_LOCALE_RESOLVER);
|
||||
}
|
||||
|
||||
private Encoder<?> getSseEncoder() {
|
||||
if (jackson2Present) {
|
||||
return new Jackson2JsonEncoder();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void applicationContext(ApplicationContext applicationContext) {
|
||||
applicationContext.getBeansOfType(HttpMessageReader.class).values().forEach(this::messageReader);
|
||||
applicationContext.getBeansOfType(HttpMessageWriter.class).values().forEach(this::messageWriter);
|
||||
|
||||
@@ -42,8 +42,10 @@ import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.codec.ByteArrayDecoder;
|
||||
import org.springframework.core.codec.ByteBufferDecoder;
|
||||
import org.springframework.core.codec.DataBufferDecoder;
|
||||
import org.springframework.core.codec.ResourceDecoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.http.codec.ServerHttpMessageReader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -114,16 +116,20 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, Application
|
||||
|
||||
|
||||
public RequestMappingHandlerAdapter() {
|
||||
// TODO: improve with better (shared) defaults
|
||||
this.messageReaders.add(new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
|
||||
this.messageReaders.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
|
||||
this.messageReaders.add(new DecoderHttpMessageReader<>(new DataBufferDecoder()));
|
||||
this.messageReaders.add(new DecoderHttpMessageReader<>(new ResourceDecoder()));
|
||||
this.messageReaders.add(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure message readers to de-serialize the request body with.
|
||||
* Configure HTTP message readers to de-serialize the request body with.
|
||||
* <p>By default only basic data types such as bytes and text are registered.
|
||||
* Consider using {@link ServerCodecConfigurer} to configure a richer list
|
||||
* including JSON encoding .
|
||||
* @see ServerCodecConfigurer
|
||||
*/
|
||||
public void setMessageReaders(List<ServerHttpMessageReader<?>> messageReaders) {
|
||||
this.messageReaders.clear();
|
||||
@@ -131,7 +137,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, Application
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured message readers.
|
||||
* Return the configured HTTP message readers.
|
||||
*/
|
||||
public List<ServerHttpMessageReader<?>> getMessageReaders() {
|
||||
return this.messageReaders;
|
||||
|
||||
@@ -30,8 +30,8 @@ import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
import org.springframework.http.codec.ServerHttpMessageReader;
|
||||
import org.springframework.http.codec.ServerHttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
|
||||
@@ -58,7 +58,7 @@ public class DelegatingWebFluxConfigurationTests {
|
||||
private WebFluxConfigurer webFluxConfigurer;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<List<ServerHttpMessageReader<?>>> readers;
|
||||
private ArgumentCaptor<ServerCodecConfigurer> codecsConfigurer;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<List<ServerHttpMessageWriter<?>>> writers;
|
||||
@@ -96,15 +96,14 @@ public class DelegatingWebFluxConfigurationTests {
|
||||
ConversionService initializerConversionService = initializer.getConversionService();
|
||||
assertTrue(initializer.getValidator() instanceof LocalValidatorFactoryBean);
|
||||
|
||||
verify(webFluxConfigurer).configureMessageReaders(readers.capture());
|
||||
verify(webFluxConfigurer).extendMessageReaders(readers.capture());
|
||||
verify(webFluxConfigurer).configureHttpMessageCodecs(codecsConfigurer.capture());
|
||||
verify(webFluxConfigurer).getValidator();
|
||||
verify(webFluxConfigurer).getMessageCodesResolver();
|
||||
verify(webFluxConfigurer).addFormatters(formatterRegistry.capture());
|
||||
verify(webFluxConfigurer).addArgumentResolvers(any());
|
||||
|
||||
assertSame(formatterRegistry.getValue(), initializerConversionService);
|
||||
assertEquals(7, readers.getValue().size());
|
||||
assertEquals(8, codecsConfigurer.getValue().getReaders().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,8 +125,7 @@ public class DelegatingWebFluxConfigurationTests {
|
||||
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
|
||||
delegatingConfig.responseBodyResultHandler();
|
||||
|
||||
verify(webFluxConfigurer).configureMessageWriters(writers.capture());
|
||||
verify(webFluxConfigurer).extendMessageWriters(writers.capture());
|
||||
verify(webFluxConfigurer).configureHttpMessageCodecs(codecsConfigurer.capture());
|
||||
verify(webFluxConfigurer).configureContentTypeResolver(any(RequestedContentTypeResolverBuilder.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,10 +34,9 @@ import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerHttpMessageReader;
|
||||
import org.springframework.http.codec.ServerHttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlDecoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
|
||||
@@ -128,7 +127,7 @@ public class WebFluxConfigurationSupportTests {
|
||||
assertNotNull(adapter);
|
||||
|
||||
List<ServerHttpMessageReader<?>> readers = adapter.getMessageReaders();
|
||||
assertEquals(7, readers.size());
|
||||
assertEquals(8, readers.size());
|
||||
|
||||
assertHasMessageReader(readers, byte[].class, APPLICATION_OCTET_STREAM);
|
||||
assertHasMessageReader(readers, ByteBuffer.class, APPLICATION_OCTET_STREAM);
|
||||
@@ -297,23 +296,12 @@ public class WebFluxConfigurationSupportTests {
|
||||
static class CustomMessageConverterConfig extends WebFluxConfigurationSupport {
|
||||
|
||||
@Override
|
||||
protected void configureMessageReaders(List<ServerHttpMessageReader<?>> messageReaders) {
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(StringDecoder.textPlainOnly(true)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureMessageWriters(List<ServerHttpMessageWriter<?>> messageWriters) {
|
||||
messageWriters.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendMessageReaders(List<ServerHttpMessageReader<?>> messageReaders) {
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendMessageWriters(List<ServerHttpMessageWriter<?>> messageWriters) {
|
||||
messageWriters.add(new EncoderHttpMessageWriter<>(new Jaxb2XmlEncoder()));
|
||||
protected void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
|
||||
configurer.registerDefaults(false);
|
||||
configurer.customCodec().decoder(StringDecoder.textPlainOnly(true));
|
||||
configurer.customCodec().decoder(new Jaxb2XmlDecoder());
|
||||
configurer.customCodec().encoder(CharSequenceEncoder.textPlainOnly());
|
||||
configurer.customCodec().encoder(new Jaxb2XmlEncoder());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,16 +120,19 @@ public class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegr
|
||||
@Bean
|
||||
public HandlerMapping handlerMapping(RouterFunction<?> routerFunction,
|
||||
ApplicationContext applicationContext) {
|
||||
|
||||
return RouterFunctions.toHandlerMapping(routerFunction,
|
||||
new HandlerStrategies() {
|
||||
@Override
|
||||
public Supplier<Stream<HttpMessageReader<?>>> messageReaders() {
|
||||
return () -> getMessageReaders().stream().map(reader -> (HttpMessageReader<?>) reader);
|
||||
return () -> getMessageCodecsConfigurer().getReaders().stream()
|
||||
.map(reader -> (HttpMessageReader<?>) reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<Stream<HttpMessageWriter<?>>> messageWriters() {
|
||||
return () -> getMessageWriters().stream().map(writer -> (HttpMessageWriter<?>) writer);
|
||||
return () -> getMessageCodecsConfigurer().getWriters().stream()
|
||||
.map(writer -> (HttpMessageWriter<?>) writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user