Split HttpMessageConverter into ~Reader and ~Writer
This commit is contained in:
@@ -25,6 +25,7 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.reactive.result.view.HttpMessageWriterView;
|
||||
import org.springframework.web.reactive.result.view.UrlBasedViewResolver;
|
||||
import org.springframework.web.reactive.result.view.View;
|
||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
@@ -97,9 +98,9 @@ public class ViewResolverRegistry {
|
||||
/**
|
||||
* Set default views associated with any view name and selected based on the
|
||||
* best match for the requested content type.
|
||||
* <p>Use {@link org.springframework.web.reactive.result.view.HttpMessageConverterView
|
||||
* HttpMessageConverterView} to adapt and use any existing
|
||||
* {@code HttpMessageConverter} (e.g. JSON, XML) as a {@code View}.
|
||||
* <p>Use {@link HttpMessageWriterView
|
||||
* HttpMessageWriterView} to adapt and use any existing
|
||||
* {@code HttpMessageWriter} (e.g. JSON, XML) as a {@code View}.
|
||||
*/
|
||||
public void defaultViews(View... defaultViews) {
|
||||
this.defaultViews.addAll(Arrays.asList(defaultViews));
|
||||
|
||||
@@ -28,8 +28,8 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.codec.ByteBufferDecoder;
|
||||
import org.springframework.core.codec.ByteBufferEncoder;
|
||||
import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.core.codec.ResourceDecoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.core.codec.StringEncoder;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
@@ -45,9 +45,11 @@ 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.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.DecoderHttpMessageReader;
|
||||
import org.springframework.http.converter.reactive.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.http.converter.reactive.HttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.ResourceHttpMessageWriter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
@@ -87,7 +89,9 @@ public class WebReactiveConfiguration implements ApplicationContextAware {
|
||||
|
||||
private PathMatchConfigurer pathMatchConfigurer;
|
||||
|
||||
private List<HttpMessageConverter<?>> messageConverters;
|
||||
private List<HttpMessageReader<?>> messageReaders;
|
||||
|
||||
private List<HttpMessageWriter<?>> messageWriters;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@@ -189,7 +193,7 @@ public class WebReactiveConfiguration implements ApplicationContextAware {
|
||||
adapter.setCustomArgumentResolvers(resolvers);
|
||||
}
|
||||
|
||||
adapter.setMessageConverters(getMessageConverters());
|
||||
adapter.setMessageReaders(getMessageReaders());
|
||||
adapter.setConversionService(mvcConversionService());
|
||||
adapter.setValidator(mvcValidator());
|
||||
|
||||
@@ -210,65 +214,54 @@ public class WebReactiveConfiguration implements ApplicationContextAware {
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method to access message converters to use for decoding
|
||||
* controller method arguments and encoding return values.
|
||||
* <p>Use {@link #configureMessageConverters} to configure the list or
|
||||
* {@link #extendMessageConverters} to add in addition to the default ones.
|
||||
* 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.
|
||||
*/
|
||||
protected final List<HttpMessageConverter<?>> getMessageConverters() {
|
||||
if (this.messageConverters == null) {
|
||||
this.messageConverters = new ArrayList<>();
|
||||
configureMessageConverters(this.messageConverters);
|
||||
if (this.messageConverters.isEmpty()) {
|
||||
addDefaultHttpMessageConverters(this.messageConverters);
|
||||
protected final List<HttpMessageReader<?>> getMessageReaders() {
|
||||
if (this.messageReaders == null) {
|
||||
this.messageReaders = new ArrayList<>();
|
||||
configureMessageReaders(this.messageReaders);
|
||||
if (this.messageReaders.isEmpty()) {
|
||||
addDefaultHttpMessageReaders(this.messageReaders);
|
||||
}
|
||||
extendMessageConverters(this.messageConverters);
|
||||
extendMessageReaders(this.messageReaders);
|
||||
}
|
||||
return this.messageConverters;
|
||||
return this.messageReaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to configure the message converters to use for decoding
|
||||
* controller method arguments and encoding return values.
|
||||
* <p>If no converters are specified, default will be added via
|
||||
* {@link #addDefaultHttpMessageConverters}.
|
||||
* @param converters a list to add converters to, initially an empty
|
||||
* 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
|
||||
*/
|
||||
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
protected void configureMessageReaders(List<HttpMessageReader<?>> messageReaders) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds default converters that sub-classes can call from
|
||||
* {@link #configureMessageConverters(List)}.
|
||||
* {@link #configureMessageReaders(List)}.
|
||||
*/
|
||||
protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
List<Encoder<?>> sseDataEncoders = new ArrayList<>();
|
||||
converters.add(converter(new ByteBufferEncoder(), new ByteBufferDecoder()));
|
||||
converters.add(converter(new StringEncoder(), new StringDecoder()));
|
||||
converters.add(new ResourceHttpMessageConverter());
|
||||
protected final void addDefaultHttpMessageReaders(List<HttpMessageReader<?>> readers) {
|
||||
readers.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(new StringDecoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(new ResourceDecoder()));
|
||||
if (jaxb2Present) {
|
||||
converters.add(converter(new Jaxb2Encoder(), new Jaxb2Decoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(new Jaxb2Decoder()));
|
||||
}
|
||||
if (jackson2Present) {
|
||||
JacksonJsonEncoder jacksonEncoder = new JacksonJsonEncoder();
|
||||
JacksonJsonDecoder jacksonDecoder = new JacksonJsonDecoder();
|
||||
converters.add(converter(jacksonEncoder, jacksonDecoder));
|
||||
sseDataEncoders.add(jacksonEncoder);
|
||||
} else {
|
||||
|
||||
readers.add(new DecoderHttpMessageReader<>(new JacksonJsonDecoder()));
|
||||
}
|
||||
converters.add(converter(new SseEventEncoder(sseDataEncoders), null));
|
||||
}
|
||||
|
||||
private static <T> HttpMessageConverter<T> converter(Encoder<T> encoder, Decoder<T> decoder) {
|
||||
return new CodecHttpMessageConverter<>(encoder, decoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this to modify the list of converters after it has been
|
||||
* 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 extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
protected void extendMessageReaders(List<HttpMessageReader<?>> messageReaders) {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -345,16 +338,67 @@ public class WebReactiveConfiguration implements ApplicationContextAware {
|
||||
|
||||
@Bean
|
||||
public ResponseEntityResultHandler responseEntityResultHandler() {
|
||||
return new ResponseEntityResultHandler(getMessageConverters(), mvcConversionService(),
|
||||
return new ResponseEntityResultHandler(getMessageWriters(), mvcConversionService(),
|
||||
mvcContentTypeResolver());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ResponseBodyResultHandler responseBodyResultHandler() {
|
||||
return new ResponseBodyResultHandler(getMessageConverters(), mvcConversionService(),
|
||||
return new ResponseBodyResultHandler(getMessageWriters(), mvcConversionService(),
|
||||
mvcContentTypeResolver());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<HttpMessageWriter<?>> 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<HttpMessageWriter<?>> messageWriters) {
|
||||
}
|
||||
/**
|
||||
* Adds default converters that sub-classes can call from
|
||||
* {@link #configureMessageWriters(List)}.
|
||||
*/
|
||||
protected final void addDefaultHttpMessageWriters(List<HttpMessageWriter<?>> writers) {
|
||||
List<Encoder<?>> sseDataEncoders = new ArrayList<>();
|
||||
writers.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
|
||||
writers.add(new EncoderHttpMessageWriter<>(new StringEncoder()));
|
||||
writers.add(new ResourceHttpMessageWriter());
|
||||
if (jaxb2Present) {
|
||||
writers.add(new EncoderHttpMessageWriter<>(new Jaxb2Encoder()));
|
||||
}
|
||||
if (jackson2Present) {
|
||||
JacksonJsonEncoder jacksonEncoder = new JacksonJsonEncoder();
|
||||
writers.add(new EncoderHttpMessageWriter<>(jacksonEncoder));
|
||||
sseDataEncoders.add(jacksonEncoder);
|
||||
}
|
||||
writers.add(new EncoderHttpMessageWriter<>(new SseEventEncoder(sseDataEncoders)));
|
||||
}
|
||||
/**
|
||||
* 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<HttpMessageWriter<?>> messageWriters) {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ViewResolutionResultHandler viewResolutionResultHandler() {
|
||||
ViewResolverRegistry registry = new ViewResolverRegistry(this.applicationContext);
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -45,7 +45,7 @@ import org.springframework.web.server.UnsupportedMediaTypeStatusException;
|
||||
|
||||
/**
|
||||
* Abstract base class for argument resolvers that resolve method arguments
|
||||
* by reading the request body with an {@link HttpMessageConverter}.
|
||||
* by reading the request body with an {@link HttpMessageReader}.
|
||||
*
|
||||
* <p>Applies validation if the method argument is annotated with
|
||||
* {@code @javax.validation.Valid} or
|
||||
@@ -55,14 +55,14 @@ import org.springframework.web.server.UnsupportedMediaTypeStatusException;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public abstract class AbstractMessageConverterArgumentResolver {
|
||||
public abstract class AbstractMessageReaderArgumentResolver {
|
||||
|
||||
private static final TypeDescriptor MONO_TYPE = TypeDescriptor.valueOf(Mono.class);
|
||||
|
||||
private static final TypeDescriptor FLUX_TYPE = TypeDescriptor.valueOf(Flux.class);
|
||||
|
||||
|
||||
private final List<HttpMessageConverter<?>> messageConverters;
|
||||
private final List<HttpMessageReader<?>> messageReaders;
|
||||
|
||||
private final ConversionService conversionService;
|
||||
|
||||
@@ -73,19 +73,19 @@ public abstract class AbstractMessageConverterArgumentResolver {
|
||||
|
||||
/**
|
||||
* Constructor with message converters and a ConversionService.
|
||||
* @param converters converters for reading the request body with
|
||||
* @param messageReaders readers to convert from the request body
|
||||
* @param service for converting to other reactive types from Flux and Mono
|
||||
* @param validator validator to validate decoded objects with
|
||||
*/
|
||||
protected AbstractMessageConverterArgumentResolver(List<HttpMessageConverter<?>> converters,
|
||||
protected AbstractMessageReaderArgumentResolver(List<HttpMessageReader<?>> messageReaders,
|
||||
ConversionService service, Validator validator) {
|
||||
|
||||
Assert.notEmpty(converters, "At least one message converter is required.");
|
||||
Assert.notEmpty(messageReaders, "At least one message reader is required.");
|
||||
Assert.notNull(service, "'conversionService' is required.");
|
||||
this.messageConverters = converters;
|
||||
this.messageReaders = messageReaders;
|
||||
this.conversionService = service;
|
||||
this.validator = validator;
|
||||
this.supportedMediaTypes = converters.stream()
|
||||
this.supportedMediaTypes = messageReaders.stream()
|
||||
.flatMap(converter -> converter.getReadableMediaTypes().stream())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
@@ -94,8 +94,8 @@ public abstract class AbstractMessageConverterArgumentResolver {
|
||||
/**
|
||||
* Return the configured message converters.
|
||||
*/
|
||||
public List<HttpMessageConverter<?>> getMessageConverters() {
|
||||
return this.messageConverters;
|
||||
public List<HttpMessageReader<?>> getMessageReaders() {
|
||||
return this.messageReaders;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,10 +124,10 @@ public abstract class AbstractMessageConverterArgumentResolver {
|
||||
mediaType = MediaType.APPLICATION_OCTET_STREAM;
|
||||
}
|
||||
|
||||
for (HttpMessageConverter<?> converter : getMessageConverters()) {
|
||||
if (converter.canRead(elementType, mediaType)) {
|
||||
for (HttpMessageReader<?> reader : getMessageReaders()) {
|
||||
if (reader.canRead(elementType, mediaType)) {
|
||||
if (convertFromFlux) {
|
||||
Flux<?> flux = converter.read(elementType, request)
|
||||
Flux<?> flux = reader.read(elementType, request)
|
||||
.onErrorResumeWith(ex -> Flux.error(getReadError(ex, bodyParameter)));
|
||||
if (checkRequired(bodyParameter, isBodyRequired)) {
|
||||
flux = flux.switchIfEmpty(Flux.error(getRequiredBodyError(bodyParameter)));
|
||||
@@ -138,7 +138,7 @@ public abstract class AbstractMessageConverterArgumentResolver {
|
||||
return Mono.just(getConversionService().convert(flux, FLUX_TYPE, typeDescriptor));
|
||||
}
|
||||
else {
|
||||
Mono<?> mono = converter.readMono(elementType, request)
|
||||
Mono<?> mono = reader.readMono(elementType, request)
|
||||
.otherwise(ex -> Mono.error(getReadError(ex, bodyParameter)));
|
||||
if (checkRequired(bodyParameter, isBodyRequired)) {
|
||||
mono = mono.otherwiseIfEmpty(Mono.error(getRequiredBodyError(bodyParameter)));
|
||||
@@ -27,7 +27,7 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageWriter;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
|
||||
@@ -37,43 +37,43 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* Abstract base class for result handlers that handle return values by writing
|
||||
* to the response with {@link HttpMessageConverter}.
|
||||
* to the response with {@link HttpMessageWriter}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public abstract class AbstractMessageConverterResultHandler extends ContentNegotiatingResultHandlerSupport {
|
||||
public abstract class AbstractMessageWriterResultHandler extends ContentNegotiatingResultHandlerSupport {
|
||||
|
||||
protected static final TypeDescriptor MONO_TYPE = TypeDescriptor.valueOf(Mono.class);
|
||||
|
||||
protected static final TypeDescriptor FLUX_TYPE = TypeDescriptor.valueOf(Flux.class);
|
||||
|
||||
|
||||
private final List<HttpMessageConverter<?>> messageConverters;
|
||||
private final List<HttpMessageWriter<?>> messageWriters;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor with message converters, a {@code ConversionService}, and a
|
||||
* {@code RequestedContentTypeResolver}.
|
||||
*
|
||||
* @param converters converters for writing the response body with
|
||||
* @param messageWriters for serializing Objects to the response body stream
|
||||
* @param conversionService for converting other reactive types (e.g.
|
||||
* rx.Observable, rx.Single, etc.) to Flux or Mono
|
||||
* @param contentTypeResolver for resolving the requested content type
|
||||
*/
|
||||
protected AbstractMessageConverterResultHandler(List<HttpMessageConverter<?>> converters,
|
||||
protected AbstractMessageWriterResultHandler(List<HttpMessageWriter<?>> messageWriters,
|
||||
ConversionService conversionService, RequestedContentTypeResolver contentTypeResolver) {
|
||||
|
||||
super(conversionService, contentTypeResolver);
|
||||
Assert.notEmpty(converters, "At least one message converter is required.");
|
||||
this.messageConverters = converters;
|
||||
Assert.notEmpty(messageWriters, "At least one message writer is required.");
|
||||
this.messageWriters = messageWriters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured message converters.
|
||||
*/
|
||||
public List<HttpMessageConverter<?>> getMessageConverters() {
|
||||
return this.messageConverters;
|
||||
public List<HttpMessageWriter<?>> getMessageWriters() {
|
||||
return this.messageWriters;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,10 +118,10 @@ public abstract class AbstractMessageConverterResultHandler extends ContentNegot
|
||||
MediaType bestMediaType = selectMediaType(exchange, producibleTypes);
|
||||
|
||||
if (bestMediaType != null) {
|
||||
for (HttpMessageConverter<?> converter : getMessageConverters()) {
|
||||
if (converter.canWrite(elementType, bestMediaType)) {
|
||||
for (HttpMessageWriter<?> messageWriter : getMessageWriters()) {
|
||||
if (messageWriter.canWrite(elementType, bestMediaType)) {
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
return converter.write((Publisher) publisher, elementType, bestMediaType, response);
|
||||
return messageWriter.write((Publisher) publisher, elementType, bestMediaType, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ public abstract class AbstractMessageConverterResultHandler extends ContentNegot
|
||||
}
|
||||
|
||||
private List<MediaType> getProducibleMediaTypes(ResolvableType elementType) {
|
||||
return getMessageConverters().stream()
|
||||
return getMessageWriters().stream()
|
||||
.filter(converter -> converter.canWrite(elementType, null))
|
||||
.flatMap(converter -> converter.getWritableMediaTypes().stream())
|
||||
.collect(Collectors.toList());
|
||||
@@ -25,7 +25,7 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.Validator;
|
||||
@@ -35,36 +35,36 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
/**
|
||||
* Resolves method arguments of type {@link HttpEntity} or {@link RequestEntity}
|
||||
* by reading the body of the request through a compatible
|
||||
* {@code HttpMessageConverter}.
|
||||
* {@code HttpMessageReader}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public class HttpEntityArgumentResolver extends AbstractMessageConverterArgumentResolver
|
||||
public class HttpEntityArgumentResolver extends AbstractMessageReaderArgumentResolver
|
||||
implements HandlerMethodArgumentResolver {
|
||||
|
||||
|
||||
/**
|
||||
* Constructor with message converters and a ConversionService.
|
||||
* @param converters converters for reading the request body with
|
||||
* @param messageReaders readers for de-serializing the request body with
|
||||
* @param service for converting to other reactive types from Flux and Mono
|
||||
*/
|
||||
public HttpEntityArgumentResolver(List<HttpMessageConverter<?>> converters,
|
||||
public HttpEntityArgumentResolver(List<HttpMessageReader<?>> messageReaders,
|
||||
ConversionService service) {
|
||||
|
||||
this(converters, service, null);
|
||||
this(messageReaders, service, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with message converters and a ConversionService.
|
||||
* @param converters converters for reading the request body with
|
||||
* @param messageReaders readers for de-serializing the request body with
|
||||
* @param service for converting to other reactive types from Flux and Mono
|
||||
* @param validator validator to validate decoded objects with
|
||||
*/
|
||||
public HttpEntityArgumentResolver(List<HttpMessageConverter<?>> converters,
|
||||
public HttpEntityArgumentResolver(List<HttpMessageReader<?>> messageReaders,
|
||||
ConversionService service, Validator validator) {
|
||||
|
||||
super(converters, service, validator);
|
||||
super(messageReaders, service, validator);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@@ -32,7 +32,7 @@ import org.springframework.web.server.ServerWebInputException;
|
||||
|
||||
/**
|
||||
* Resolves method arguments annotated with {@code @RequestBody} by reading the
|
||||
* body of the request through a compatible {@code HttpMessageConverter}.
|
||||
* body of the request through a compatible {@code HttpMessageReader}.
|
||||
*
|
||||
* <p>An {@code @RequestBody} method argument is also validated if it is
|
||||
* annotated with {@code @javax.validation.Valid} or
|
||||
@@ -44,31 +44,31 @@ import org.springframework.web.server.ServerWebInputException;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public class RequestBodyArgumentResolver extends AbstractMessageConverterArgumentResolver
|
||||
public class RequestBodyArgumentResolver extends AbstractMessageReaderArgumentResolver
|
||||
implements HandlerMethodArgumentResolver {
|
||||
|
||||
|
||||
/**
|
||||
* Constructor with message converters and a ConversionService.
|
||||
* @param converters converters for reading the request body with
|
||||
* @param messageReaders readers for de-serializing the request body with
|
||||
* @param service for converting to other reactive types from Flux and Mono
|
||||
*/
|
||||
public RequestBodyArgumentResolver(List<HttpMessageConverter<?>> converters,
|
||||
public RequestBodyArgumentResolver(List<HttpMessageReader<?>> messageReaders,
|
||||
ConversionService service) {
|
||||
|
||||
this(converters, service, null);
|
||||
this(messageReaders, service, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with message converters and a ConversionService.
|
||||
* @param converters converters for reading the request body with
|
||||
* @param messageReaders readers for de-serializing the request body with
|
||||
* @param service for converting to other reactive types from Flux and Mono
|
||||
* @param validator validator to validate decoded objects with
|
||||
*/
|
||||
public RequestBodyArgumentResolver(List<HttpMessageConverter<?>> converters,
|
||||
public RequestBodyArgumentResolver(List<HttpMessageReader<?>> messageReaders,
|
||||
ConversionService service, Validator validator) {
|
||||
|
||||
super(converters, service, validator);
|
||||
super(messageReaders, service, validator);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ import org.springframework.core.codec.ByteBufferDecoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.DecoderHttpMessageReader;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.Validator;
|
||||
@@ -64,7 +64,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
|
||||
|
||||
private List<HandlerMethodArgumentResolver> argumentResolvers;
|
||||
|
||||
private final List<HttpMessageConverter<?>> messageConverters = new ArrayList<>(10);
|
||||
private final List<HttpMessageReader<?>> messageReaders = new ArrayList<>(10);
|
||||
|
||||
private ConversionService conversionService = new DefaultFormattingConversionService();
|
||||
|
||||
@@ -77,8 +77,8 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
|
||||
|
||||
|
||||
public RequestMappingHandlerAdapter() {
|
||||
this.messageConverters.add(new CodecHttpMessageConverter<>(new ByteBufferDecoder()));
|
||||
this.messageConverters.add(new CodecHttpMessageConverter<>(new StringDecoder()));
|
||||
this.messageReaders.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
|
||||
this.messageReaders.add(new DecoderHttpMessageReader<>(new StringDecoder()));
|
||||
}
|
||||
|
||||
|
||||
@@ -112,18 +112,18 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure message converters to read the request body with.
|
||||
* Configure message readers to de-serialize the request body with.
|
||||
*/
|
||||
public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
|
||||
this.messageConverters.clear();
|
||||
this.messageConverters.addAll(messageConverters);
|
||||
public void setMessageReaders(List<HttpMessageReader<?>> messageReaders) {
|
||||
this.messageReaders.clear();
|
||||
this.messageReaders.addAll(messageReaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured message converters.
|
||||
* Return the configured message readers.
|
||||
*/
|
||||
public List<HttpMessageConverter<?>> getMessageConverters() {
|
||||
return this.messageConverters;
|
||||
public List<HttpMessageReader<?>> getMessageReaders() {
|
||||
return this.messageReaders;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,7 +193,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
|
||||
resolvers.add(new RequestParamMapMethodArgumentResolver());
|
||||
resolvers.add(new PathVariableMethodArgumentResolver(cs, getBeanFactory()));
|
||||
resolvers.add(new PathVariableMapMethodArgumentResolver());
|
||||
resolvers.add(new RequestBodyArgumentResolver(getMessageConverters(), cs, getValidator()));
|
||||
resolvers.add(new RequestBodyArgumentResolver(getMessageReaders(), cs, getValidator()));
|
||||
resolvers.add(new RequestHeaderMethodArgumentResolver(cs, getBeanFactory()));
|
||||
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
|
||||
resolvers.add(new CookieValueMethodArgumentResolver(cs, getBeanFactory()));
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageWriter;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
import org.springframework.web.reactive.HandlerResultHandler;
|
||||
@@ -37,7 +37,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
/**
|
||||
* {@code HandlerResultHandler} that handles return values from methods annotated
|
||||
* with {@code @ResponseBody} writing to the body of the request or response with
|
||||
* an {@link HttpMessageConverter}.
|
||||
* an {@link HttpMessageWriter}.
|
||||
*
|
||||
* <p>By default the order for this result handler is set to 100. As it detects
|
||||
* the presence of {@code @ResponseBody} it should be ordered after result
|
||||
@@ -50,7 +50,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
* @author Arjen Poutsma
|
||||
* @since 5.0
|
||||
*/
|
||||
public class ResponseBodyResultHandler extends AbstractMessageConverterResultHandler
|
||||
public class ResponseBodyResultHandler extends AbstractMessageWriterResultHandler
|
||||
implements HandlerResultHandler {
|
||||
|
||||
/**
|
||||
@@ -58,28 +58,28 @@ public class ResponseBodyResultHandler extends AbstractMessageConverterResultHan
|
||||
* and creating a {@link HeaderContentTypeResolver}, i.e. using Accept header
|
||||
* to determine the requested content type.
|
||||
*
|
||||
* @param converters converters for writing the response body with
|
||||
* @param messageWriters writers for serializing to the response body stream
|
||||
* @param conversionService for converting to Flux and Mono from other reactive types
|
||||
*/
|
||||
public ResponseBodyResultHandler(List<HttpMessageConverter<?>> converters,
|
||||
public ResponseBodyResultHandler(List<HttpMessageWriter<?>> messageWriters,
|
||||
ConversionService conversionService) {
|
||||
|
||||
this(converters, conversionService, new HeaderContentTypeResolver());
|
||||
this(messageWriters, conversionService, new HeaderContentTypeResolver());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with message converters, a {@code ConversionService}, and a
|
||||
* {@code RequestedContentTypeResolver}.
|
||||
*
|
||||
* @param converters converters for writing the response body with
|
||||
* @param messageWriters writers for serializing to the response body stream
|
||||
* @param conversionService for converting other reactive types (e.g.
|
||||
* rx.Observable, rx.Single, etc.) to Flux or Mono
|
||||
* @param contentTypeResolver for resolving the requested content type
|
||||
*/
|
||||
public ResponseBodyResultHandler(List<HttpMessageConverter<?>> converters,
|
||||
public ResponseBodyResultHandler(List<HttpMessageWriter<?>> messageWriters,
|
||||
ConversionService conversionService, RequestedContentTypeResolver contentTypeResolver) {
|
||||
|
||||
super(converters, conversionService, contentTypeResolver);
|
||||
super(messageWriters, conversionService, contentTypeResolver);
|
||||
setOrder(100);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageWriter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
import org.springframework.web.reactive.HandlerResultHandler;
|
||||
@@ -44,7 +44,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public class ResponseEntityResultHandler extends AbstractMessageConverterResultHandler
|
||||
public class ResponseEntityResultHandler extends AbstractMessageWriterResultHandler
|
||||
implements HandlerResultHandler {
|
||||
|
||||
/**
|
||||
@@ -52,28 +52,28 @@ public class ResponseEntityResultHandler extends AbstractMessageConverterResultH
|
||||
* and creating a {@link HeaderContentTypeResolver}, i.e. using Accept header
|
||||
* to determine the requested content type.
|
||||
*
|
||||
* @param converters converters for writing the response body with
|
||||
* @param messageWriters writers for serializing to the response body stream
|
||||
* @param conversionService for converting to Flux and Mono from other reactive types
|
||||
*/
|
||||
public ResponseEntityResultHandler(List<HttpMessageConverter<?>> converters,
|
||||
public ResponseEntityResultHandler(List<HttpMessageWriter<?>> messageWriters,
|
||||
ConversionService conversionService) {
|
||||
|
||||
this(converters, conversionService, new HeaderContentTypeResolver());
|
||||
this(messageWriters, conversionService, new HeaderContentTypeResolver());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with message converters, a {@code ConversionService}, and a
|
||||
* {@code RequestedContentTypeResolver}.
|
||||
*
|
||||
* @param converters converters for writing the response body with
|
||||
* @param messageWriters writers for serializing to the response body stream
|
||||
* @param conversionService for converting other reactive types (e.g.
|
||||
* rx.Observable, rx.Single, etc.) to Flux or Mono
|
||||
* @param contentTypeResolver for resolving the requested content type
|
||||
*/
|
||||
public ResponseEntityResultHandler(List<HttpMessageConverter<?>> converters,
|
||||
public ResponseEntityResultHandler(List<HttpMessageWriter<?>> messageWriters,
|
||||
ConversionService conversionService, RequestedContentTypeResolver contentTypeResolver) {
|
||||
|
||||
super(converters, conversionService, contentTypeResolver);
|
||||
super(messageWriters, conversionService, contentTypeResolver);
|
||||
setOrder(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ import reactor.core.publisher.Mono;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageWriter;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -37,14 +37,14 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link View} that delegates to an {@link HttpMessageConverter}.
|
||||
* A {@link View} that delegates to an {@link HttpMessageWriter}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public class HttpMessageConverterView implements View {
|
||||
public class HttpMessageWriterView implements View {
|
||||
|
||||
private final HttpMessageConverter<?> converter;
|
||||
private final HttpMessageWriter<?> messageWriter;
|
||||
|
||||
private final Set<String> modelKeys = new HashSet<>(4);
|
||||
|
||||
@@ -52,35 +52,33 @@ public class HttpMessageConverterView implements View {
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@code View} with the given {@code Encoder}.
|
||||
* Internally this creates
|
||||
* {@link CodecHttpMessageConverter#CodecHttpMessageConverter(Encoder)
|
||||
* CodecHttpMessageConverter(Encoder)}.
|
||||
* Create a {@code View} with the given {@code Encoder} wrapping it as an
|
||||
* {@link EncoderHttpMessageWriter}.
|
||||
*/
|
||||
public HttpMessageConverterView(Encoder<?> encoder) {
|
||||
this(new CodecHttpMessageConverter<>(encoder));
|
||||
public HttpMessageWriterView(Encoder<?> encoder) {
|
||||
this(new EncoderHttpMessageWriter<>(encoder));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a View that delegates to the given message converter.
|
||||
* Create a View that delegates to the given message messageWriter.
|
||||
*/
|
||||
public HttpMessageConverterView(HttpMessageConverter<?> converter) {
|
||||
Assert.notNull(converter, "'converter' is required.");
|
||||
this.converter = converter;
|
||||
this.mediaTypes = converter.getWritableMediaTypes();
|
||||
public HttpMessageWriterView(HttpMessageWriter<?> messageWriter) {
|
||||
Assert.notNull(messageWriter, "'messageWriter' is required.");
|
||||
this.messageWriter = messageWriter;
|
||||
this.mediaTypes = messageWriter.getWritableMediaTypes();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the configured message converter.
|
||||
* Return the configured message messageWriter.
|
||||
*/
|
||||
public HttpMessageConverter<?> getConverter() {
|
||||
return this.converter;
|
||||
public HttpMessageWriter<?> getMessageWriter() {
|
||||
return this.messageWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* By default model attributes are filtered with
|
||||
* {@link HttpMessageConverter#canWrite} to find the ones that can be
|
||||
* {@link HttpMessageWriter#canWrite} to find the ones that can be
|
||||
* rendered. Use this property to further narrow the list and consider only
|
||||
* attribute(s) under specific model key(s).
|
||||
* <p>If more than one matching attribute is found, than a Map is rendered,
|
||||
@@ -109,7 +107,7 @@ public class HttpMessageConverterView implements View {
|
||||
@Override
|
||||
public Mono<Void> render(HandlerResult result, MediaType contentType, ServerWebExchange exchange) {
|
||||
Object value = extractObjectToRender(result);
|
||||
return applyConverter(value, contentType, exchange);
|
||||
return applyMessageWriter(value, contentType, exchange);
|
||||
}
|
||||
|
||||
protected Object extractObjectToRender(HandlerResult result) {
|
||||
@@ -126,13 +124,13 @@ public class HttpMessageConverterView implements View {
|
||||
else if (map.size() == 1) {
|
||||
return map.values().iterator().next();
|
||||
}
|
||||
else if (getConverter().canWrite(ResolvableType.forClass(Map.class), null)) {
|
||||
else if (getMessageWriter().canWrite(ResolvableType.forClass(Map.class), null)) {
|
||||
return map;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"Multiple matching attributes found: " + map + ". " +
|
||||
"However Map rendering is not supported by " + getConverter());
|
||||
"However Map rendering is not supported by " + getMessageWriter());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,28 +143,28 @@ public class HttpMessageConverterView implements View {
|
||||
protected boolean isEligibleAttribute(String attributeName, Object attributeValue) {
|
||||
ResolvableType type = ResolvableType.forClass(attributeValue.getClass());
|
||||
if (getModelKeys().isEmpty()) {
|
||||
return getConverter().canWrite(type, null);
|
||||
return getMessageWriter().canWrite(type, null);
|
||||
}
|
||||
if (getModelKeys().contains(attributeName)) {
|
||||
if (getConverter().canWrite(type, null)) {
|
||||
if (getMessageWriter().canWrite(type, null)) {
|
||||
return true;
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"Model object [" + attributeValue + "] retrieved via key " +
|
||||
"[" + attributeName + "] is not supported by " + getConverter());
|
||||
"[" + attributeName + "] is not supported by " + getMessageWriter());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Mono<Void> applyConverter(Object value, MediaType contentType, ServerWebExchange exchange) {
|
||||
private <T> Mono<Void> applyMessageWriter(Object value, MediaType contentType, ServerWebExchange exchange) {
|
||||
if (value == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
Publisher<? extends T> stream = Mono.just((T) value);
|
||||
ResolvableType type = ResolvableType.forClass(value.getClass());
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
return ((HttpMessageConverter<T>) getConverter()).write(stream, type, contentType, response);
|
||||
return ((HttpMessageWriter<T>) getMessageWriter()).write(stream, type, contentType, response);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,7 +36,7 @@ import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@@ -197,7 +197,7 @@ public class DispatcherHandlerErrorTests {
|
||||
@Bean
|
||||
public ResponseBodyResultHandler resultHandler() {
|
||||
return new ResponseBodyResultHandler(
|
||||
Collections.singletonList(new CodecHttpMessageConverter<>(new StringEncoder())),
|
||||
Collections.singletonList(new EncoderHttpMessageWriter<>(new StringEncoder())),
|
||||
new DefaultConversionService());
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.junit.Test;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.codec.json.JacksonJsonEncoder;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.reactive.result.view.HttpMessageConverterView;
|
||||
import org.springframework.web.reactive.result.view.HttpMessageWriterView;
|
||||
import org.springframework.web.reactive.result.view.UrlBasedViewResolver;
|
||||
import org.springframework.web.reactive.result.view.View;
|
||||
import org.springframework.web.reactive.result.view.freemarker.FreeMarkerConfigurer;
|
||||
@@ -80,7 +80,7 @@ public class ViewResolverRegistryTests {
|
||||
|
||||
@Test
|
||||
public void defaultViews() throws Exception {
|
||||
View view = new HttpMessageConverterView(new JacksonJsonEncoder());
|
||||
View view = new HttpMessageWriterView(new JacksonJsonEncoder());
|
||||
this.registry.defaultViews(view);
|
||||
|
||||
assertEquals(1, this.registry.getDefaultViews().size());
|
||||
|
||||
@@ -43,8 +43,10 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.json.JacksonJsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2Decoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2Encoder;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.DecoderHttpMessageReader;
|
||||
import org.springframework.http.converter.reactive.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.http.converter.reactive.HttpMessageWriter;
|
||||
import org.springframework.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.util.MimeType;
|
||||
@@ -56,7 +58,7 @@ import org.springframework.web.reactive.result.method.annotation.RequestMappingH
|
||||
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.HttpMessageConverterView;
|
||||
import org.springframework.web.reactive.result.view.HttpMessageWriterView;
|
||||
import org.springframework.web.reactive.result.view.View;
|
||||
import org.springframework.web.reactive.result.view.ViewResolutionResultHandler;
|
||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
@@ -142,15 +144,15 @@ public class WebReactiveConfigurationTests {
|
||||
RequestMappingHandlerAdapter adapter = context.getBean(name, RequestMappingHandlerAdapter.class);
|
||||
assertNotNull(adapter);
|
||||
|
||||
List<HttpMessageConverter<?>> converters = adapter.getMessageConverters();
|
||||
assertEquals(6, converters.size());
|
||||
List<HttpMessageReader<?>> readers = adapter.getMessageReaders();
|
||||
assertEquals(5, readers.size());
|
||||
|
||||
assertHasConverter(converters, ByteBuffer.class, APPLICATION_OCTET_STREAM, APPLICATION_OCTET_STREAM);
|
||||
assertHasConverter(converters, String.class, TEXT_PLAIN, TEXT_PLAIN);
|
||||
assertHasConverter(converters, Resource.class, IMAGE_PNG, IMAGE_PNG);
|
||||
assertHasConverter(converters, TestBean.class, APPLICATION_XML, APPLICATION_XML);
|
||||
assertHasConverter(converters, TestBean.class, APPLICATION_JSON, APPLICATION_JSON);
|
||||
assertHasConverter(converters, TestBean.class, null, MediaType.parseMediaType("text/event-stream"));
|
||||
assertHasMessageReader(readers, ByteBuffer.class, APPLICATION_OCTET_STREAM);
|
||||
assertHasMessageReader(readers, String.class, TEXT_PLAIN);
|
||||
assertHasMessageReader(readers, Resource.class, IMAGE_PNG);
|
||||
assertHasMessageReader(readers, TestBean.class, APPLICATION_XML);
|
||||
assertHasMessageReader(readers, TestBean.class, APPLICATION_JSON);
|
||||
assertHasMessageReader(readers, TestBean.class, null);
|
||||
|
||||
name = "mvcConversionService";
|
||||
ConversionService service = context.getBean(name, ConversionService.class);
|
||||
@@ -170,11 +172,11 @@ public class WebReactiveConfigurationTests {
|
||||
RequestMappingHandlerAdapter adapter = context.getBean(name, RequestMappingHandlerAdapter.class);
|
||||
assertNotNull(adapter);
|
||||
|
||||
List<HttpMessageConverter<?>> converters = adapter.getMessageConverters();
|
||||
assertEquals(2, converters.size());
|
||||
List<HttpMessageReader<?>> messageReaders = adapter.getMessageReaders();
|
||||
assertEquals(2, messageReaders.size());
|
||||
|
||||
assertHasConverter(converters, String.class, TEXT_PLAIN, TEXT_PLAIN);
|
||||
assertHasConverter(converters, TestBean.class, APPLICATION_XML, APPLICATION_XML);
|
||||
assertHasMessageReader(messageReaders, String.class, TEXT_PLAIN);
|
||||
assertHasMessageReader(messageReaders, TestBean.class, APPLICATION_XML);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -199,15 +201,15 @@ public class WebReactiveConfigurationTests {
|
||||
|
||||
assertEquals(0, handler.getOrder());
|
||||
|
||||
List<HttpMessageConverter<?>> converters = handler.getMessageConverters();
|
||||
assertEquals(6, converters.size());
|
||||
List<HttpMessageWriter<?>> writers = handler.getMessageWriters();
|
||||
assertEquals(6, writers.size());
|
||||
|
||||
assertHasConverter(converters, ByteBuffer.class, APPLICATION_OCTET_STREAM, APPLICATION_OCTET_STREAM);
|
||||
assertHasConverter(converters, String.class, TEXT_PLAIN, TEXT_PLAIN);
|
||||
assertHasConverter(converters, Resource.class, IMAGE_PNG, IMAGE_PNG);
|
||||
assertHasConverter(converters, TestBean.class, APPLICATION_XML, APPLICATION_XML);
|
||||
assertHasConverter(converters, TestBean.class, APPLICATION_JSON, APPLICATION_JSON);
|
||||
assertHasConverter(converters, TestBean.class, null, MediaType.parseMediaType("text/event-stream"));
|
||||
assertHasMessageWriter(writers, ByteBuffer.class, APPLICATION_OCTET_STREAM);
|
||||
assertHasMessageWriter(writers, String.class, TEXT_PLAIN);
|
||||
assertHasMessageWriter(writers, Resource.class, IMAGE_PNG);
|
||||
assertHasMessageWriter(writers, TestBean.class, APPLICATION_XML);
|
||||
assertHasMessageWriter(writers, TestBean.class, APPLICATION_JSON);
|
||||
assertHasMessageWriter(writers, TestBean.class, MediaType.parseMediaType("text/event-stream"));
|
||||
|
||||
name = "mvcContentTypeResolver";
|
||||
RequestedContentTypeResolver resolver = context.getBean(name, RequestedContentTypeResolver.class);
|
||||
@@ -224,15 +226,15 @@ public class WebReactiveConfigurationTests {
|
||||
|
||||
assertEquals(100, handler.getOrder());
|
||||
|
||||
List<HttpMessageConverter<?>> converters = handler.getMessageConverters();
|
||||
assertEquals(6, converters.size());
|
||||
List<HttpMessageWriter<?>> writers = handler.getMessageWriters();
|
||||
assertEquals(6, writers.size());
|
||||
|
||||
assertHasConverter(converters, ByteBuffer.class, APPLICATION_OCTET_STREAM, APPLICATION_OCTET_STREAM);
|
||||
assertHasConverter(converters, String.class, TEXT_PLAIN, TEXT_PLAIN);
|
||||
assertHasConverter(converters, Resource.class, IMAGE_PNG, IMAGE_PNG);
|
||||
assertHasConverter(converters, TestBean.class, APPLICATION_XML, APPLICATION_XML);
|
||||
assertHasConverter(converters, TestBean.class, APPLICATION_JSON, APPLICATION_JSON);
|
||||
assertHasConverter(converters, TestBean.class, null, MediaType.parseMediaType("text/event-stream"));
|
||||
assertHasMessageWriter(writers, ByteBuffer.class, APPLICATION_OCTET_STREAM);
|
||||
assertHasMessageWriter(writers, String.class, TEXT_PLAIN);
|
||||
assertHasMessageWriter(writers, Resource.class, IMAGE_PNG);
|
||||
assertHasMessageWriter(writers, TestBean.class, APPLICATION_XML);
|
||||
assertHasMessageWriter(writers, TestBean.class, APPLICATION_JSON);
|
||||
assertHasMessageWriter(writers, TestBean.class, null);
|
||||
|
||||
name = "mvcContentTypeResolver";
|
||||
RequestedContentTypeResolver resolver = context.getBean(name, RequestedContentTypeResolver.class);
|
||||
@@ -261,12 +263,18 @@ public class WebReactiveConfigurationTests {
|
||||
}
|
||||
|
||||
|
||||
private void assertHasConverter(List<HttpMessageConverter<?>> converters, Class<?> clazz,
|
||||
MediaType readMediaType, MediaType writeMediaType) {
|
||||
private void assertHasMessageReader(List<HttpMessageReader<?>> readers, Class<?> clazz, MediaType mediaType) {
|
||||
ResolvableType type = ResolvableType.forClass(clazz);
|
||||
assertTrue(converters.stream()
|
||||
.filter(c -> (readMediaType == null || c.canRead(type, readMediaType))
|
||||
&& (writeMediaType == null || c.canWrite(type, writeMediaType)))
|
||||
assertTrue(readers.stream()
|
||||
.filter(c -> mediaType == null || c.canRead(type, mediaType))
|
||||
.findAny()
|
||||
.isPresent());
|
||||
}
|
||||
|
||||
private void assertHasMessageWriter(List<HttpMessageWriter<?>> writers, Class<?> clazz, MediaType mediaType) {
|
||||
ResolvableType type = ResolvableType.forClass(clazz);
|
||||
assertTrue(writers.stream()
|
||||
.filter(c -> mediaType == null || c.canWrite(type, mediaType))
|
||||
.findAny()
|
||||
.isPresent());
|
||||
}
|
||||
@@ -293,13 +301,23 @@ public class WebReactiveConfigurationTests {
|
||||
static class CustomMessageConverterConfig extends WebReactiveConfiguration {
|
||||
|
||||
@Override
|
||||
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
converters.add(new CodecHttpMessageConverter<>(new StringEncoder(), new StringDecoder()));
|
||||
protected void configureMessageReaders(List<HttpMessageReader<?>> messageReaders) {
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(new StringDecoder()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
converters.add(new CodecHttpMessageConverter<>(new Jaxb2Encoder(), new Jaxb2Decoder()));
|
||||
protected void configureMessageWriters(List<HttpMessageWriter<?>> messageWriters) {
|
||||
messageWriters.add(new EncoderHttpMessageWriter<>(new StringEncoder()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendMessageReaders(List<HttpMessageReader<?>> messageReaders) {
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(new Jaxb2Decoder()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendMessageWriters(List<HttpMessageWriter<?>> messageWriters) {
|
||||
messageWriters.add(new EncoderHttpMessageWriter<>(new Jaxb2Encoder()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +327,7 @@ public class WebReactiveConfigurationTests {
|
||||
@Override
|
||||
protected void configureViewResolvers(ViewResolverRegistry registry) {
|
||||
registry.freeMarker();
|
||||
registry.defaultViews(new HttpMessageConverterView(new JacksonJsonEncoder()));
|
||||
registry.defaultViews(new HttpMessageWriterView(new JacksonJsonEncoder()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -45,8 +45,8 @@ import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.DecoderHttpMessageReader;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
@@ -66,7 +66,7 @@ import static org.springframework.core.ResolvableType.forClassWithGenerics;
|
||||
/**
|
||||
* Unit tests for {@link HttpEntityArgumentResolver}.When adding a test also
|
||||
* consider whether the logic under test is in a parent class, then see:
|
||||
* {@link MessageConverterArgumentResolverTests}.
|
||||
* {@link MessageReaderArgumentResolverTests}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
@@ -89,14 +89,14 @@ public class HttpEntityArgumentResolverTests {
|
||||
}
|
||||
|
||||
private HttpEntityArgumentResolver createResolver() {
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
||||
converters.add(new CodecHttpMessageConverter<>(new StringDecoder()));
|
||||
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
||||
readers.add(new DecoderHttpMessageReader<>(new StringDecoder()));
|
||||
|
||||
FormattingConversionService service = new DefaultFormattingConversionService();
|
||||
service.addConverter(new MonoToCompletableFutureConverter());
|
||||
service.addConverter(new ReactorToRxJava1Converter());
|
||||
|
||||
return new HttpEntityArgumentResolver(converters, service);
|
||||
return new HttpEntityArgumentResolver(readers, service);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.json.JacksonJsonDecoder;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.DecoderHttpMessageReader;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.validation.Errors;
|
||||
@@ -72,12 +72,12 @@ import static org.springframework.core.ResolvableType.forClass;
|
||||
import static org.springframework.core.ResolvableType.forClassWithGenerics;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractMessageConverterArgumentResolver}.
|
||||
* Unit tests for {@link AbstractMessageReaderArgumentResolver}.
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class MessageConverterArgumentResolverTests {
|
||||
public class MessageReaderArgumentResolverTests {
|
||||
|
||||
private AbstractMessageConverterArgumentResolver resolver = resolver(new JacksonJsonDecoder());
|
||||
private AbstractMessageReaderArgumentResolver resolver = resolver(new JacksonJsonDecoder());
|
||||
|
||||
private ServerWebExchange exchange;
|
||||
|
||||
@@ -276,16 +276,16 @@ public class MessageConverterArgumentResolverTests {
|
||||
}
|
||||
|
||||
@SuppressWarnings("Convert2MethodRef")
|
||||
private AbstractMessageConverterArgumentResolver resolver(Decoder<?>... decoders) {
|
||||
private AbstractMessageReaderArgumentResolver resolver(Decoder<?>... decoders) {
|
||||
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
||||
Arrays.asList(decoders).forEach(decoder -> converters.add(new CodecHttpMessageConverter<>(decoder)));
|
||||
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
||||
Arrays.asList(decoders).forEach(decoder -> readers.add(new DecoderHttpMessageReader<>(decoder)));
|
||||
|
||||
FormattingConversionService service = new DefaultFormattingConversionService();
|
||||
service.addConverter(new MonoToCompletableFutureConverter());
|
||||
service.addConverter(new ReactorToRxJava1Converter());
|
||||
|
||||
return new AbstractMessageConverterArgumentResolver(converters, service, new TestBeanValidator()) {};
|
||||
return new AbstractMessageReaderArgumentResolver(readers, service, new TestBeanValidator()) {};
|
||||
}
|
||||
|
||||
private DataBuffer dataBuffer(String body) {
|
||||
@@ -49,9 +49,9 @@ import org.springframework.core.io.buffer.support.DataBufferTestUtils;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.codec.json.JacksonJsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2Encoder;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.ResourceHttpMessageWriter;
|
||||
import org.springframework.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
@@ -70,12 +70,12 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
|
||||
import static org.springframework.web.reactive.HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractMessageConverterResultHandler}.
|
||||
* Unit tests for {@link AbstractMessageWriterResultHandler}.
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class MessageConverterResultHandlerTests {
|
||||
public class MessageWriterResultHandlerTests {
|
||||
|
||||
private AbstractMessageConverterResultHandler resultHandler;
|
||||
private AbstractMessageWriterResultHandler resultHandler;
|
||||
|
||||
private MockServerHttpResponse response = new MockServerHttpResponse();
|
||||
|
||||
@@ -131,8 +131,8 @@ public class MessageConverterResultHandlerTests {
|
||||
ByteArrayOutputStream body = new ByteArrayOutputStream();
|
||||
ResolvableType type = ResolvableType.forType(OutputStream.class);
|
||||
|
||||
HttpMessageConverter<?> converter = new CodecHttpMessageConverter<>(new ByteBufferEncoder());
|
||||
Mono<Void> mono = createResultHandler(converter).writeBody(this.exchange, body, type, returnType(type));
|
||||
HttpMessageWriter<?> writer = new EncoderHttpMessageWriter<>(new ByteBufferEncoder());
|
||||
Mono<Void> mono = createResultHandler(writer).writeBody(this.exchange, body, type, returnType(type));
|
||||
|
||||
TestSubscriber.subscribe(mono).assertError(IllegalStateException.class);
|
||||
}
|
||||
@@ -175,18 +175,18 @@ public class MessageConverterResultHandlerTests {
|
||||
return ResolvableMethod.onClass(TestController.class).returning(bodyType).resolveReturnType();
|
||||
}
|
||||
|
||||
private AbstractMessageConverterResultHandler createResultHandler(HttpMessageConverter<?>... converters) {
|
||||
List<HttpMessageConverter<?>> converterList;
|
||||
if (ObjectUtils.isEmpty(converters)) {
|
||||
converterList = new ArrayList<>();
|
||||
converterList.add(new CodecHttpMessageConverter<>(new ByteBufferEncoder()));
|
||||
converterList.add(new CodecHttpMessageConverter<>(new StringEncoder()));
|
||||
converterList.add(new ResourceHttpMessageConverter());
|
||||
converterList.add(new CodecHttpMessageConverter<>(new Jaxb2Encoder()));
|
||||
converterList.add(new CodecHttpMessageConverter<>(new JacksonJsonEncoder()));
|
||||
private AbstractMessageWriterResultHandler createResultHandler(HttpMessageWriter<?>... writers) {
|
||||
List<HttpMessageWriter<?>> writerList;
|
||||
if (ObjectUtils.isEmpty(writers)) {
|
||||
writerList = new ArrayList<>();
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new StringEncoder()));
|
||||
writerList.add(new ResourceHttpMessageWriter());
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new Jaxb2Encoder()));
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new JacksonJsonEncoder()));
|
||||
}
|
||||
else {
|
||||
converterList = Arrays.asList(converters);
|
||||
writerList = Arrays.asList(writers);
|
||||
}
|
||||
|
||||
GenericConversionService service = new GenericConversionService();
|
||||
@@ -195,7 +195,7 @@ public class MessageConverterResultHandlerTests {
|
||||
|
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder().build();
|
||||
|
||||
return new AbstractMessageConverterResultHandler(converterList, service, resolver) {};
|
||||
return new AbstractMessageWriterResultHandler(writerList, service, resolver) {};
|
||||
}
|
||||
|
||||
private void assertResponseBody(String responseBody) {
|
||||
@@ -44,8 +44,8 @@ import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.DecoderHttpMessageReader;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
@@ -67,7 +67,7 @@ import static org.springframework.core.ResolvableType.forClassWithGenerics;
|
||||
/**
|
||||
* Unit tests for {@link RequestBodyArgumentResolver}. When adding a test also
|
||||
* consider whether the logic under test is in a parent class, then see:
|
||||
* {@link MessageConverterArgumentResolverTests}.
|
||||
* {@link MessageReaderArgumentResolverTests}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
@@ -90,14 +90,14 @@ public class RequestBodyArgumentResolverTests {
|
||||
}
|
||||
|
||||
private RequestBodyArgumentResolver resolver() {
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
||||
converters.add(new CodecHttpMessageConverter<>(new StringDecoder()));
|
||||
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
||||
readers.add(new DecoderHttpMessageReader<>(new StringDecoder()));
|
||||
|
||||
FormattingConversionService service = new DefaultFormattingConversionService();
|
||||
service.addConverter(new MonoToCompletableFutureConverter());
|
||||
service.addConverter(new ReactorToRxJava1Converter());
|
||||
|
||||
return new RequestBodyArgumentResolver(converters, service);
|
||||
return new RequestBodyArgumentResolver(readers, service);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,9 +36,9 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.codec.json.JacksonJsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2Encoder;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.ResourceHttpMessageWriter;
|
||||
import org.springframework.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
@@ -62,7 +62,7 @@ import static org.junit.Assert.assertEquals;
|
||||
* Unit tests for {@link ResponseBodyResultHandler}.When adding a test also
|
||||
* consider whether the logic under test is in a parent class, then see:
|
||||
* <ul>
|
||||
* <li>{@code MessageConverterResultHandlerTests},
|
||||
* <li>{@code MessageWriterResultHandlerTests},
|
||||
* <li>{@code ContentNegotiatingResultHandlerSupportTests}
|
||||
* </ul>
|
||||
*
|
||||
@@ -86,25 +86,25 @@ public class ResponseBodyResultHandlerTests {
|
||||
}
|
||||
|
||||
|
||||
private ResponseBodyResultHandler createHandler(HttpMessageConverter<?>... converters) {
|
||||
List<HttpMessageConverter<?>> converterList;
|
||||
if (ObjectUtils.isEmpty(converters)) {
|
||||
converterList = new ArrayList<>();
|
||||
converterList.add(new CodecHttpMessageConverter<>(new ByteBufferEncoder()));
|
||||
converterList.add(new CodecHttpMessageConverter<>(new StringEncoder()));
|
||||
converterList.add(new ResourceHttpMessageConverter());
|
||||
converterList.add(new CodecHttpMessageConverter<>(new Jaxb2Encoder()));
|
||||
converterList.add(new CodecHttpMessageConverter<>(new JacksonJsonEncoder()));
|
||||
private ResponseBodyResultHandler createHandler(HttpMessageWriter<?>... writers) {
|
||||
List<HttpMessageWriter<?>> writerList;
|
||||
if (ObjectUtils.isEmpty(writers)) {
|
||||
writerList = new ArrayList<>();
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new StringEncoder()));
|
||||
writerList.add(new ResourceHttpMessageWriter());
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new Jaxb2Encoder()));
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new JacksonJsonEncoder()));
|
||||
}
|
||||
else {
|
||||
converterList = Arrays.asList(converters);
|
||||
writerList = Arrays.asList(writers);
|
||||
}
|
||||
FormattingConversionService service = new DefaultFormattingConversionService();
|
||||
service.addConverter(new MonoToCompletableFutureConverter());
|
||||
service.addConverter(new ReactorToRxJava1Converter());
|
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder().build();
|
||||
|
||||
return new ResponseBodyResultHandler(converterList, new DefaultConversionService(), resolver);
|
||||
return new ResponseBodyResultHandler(writerList, new DefaultConversionService(), resolver);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -43,9 +43,9 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.codec.json.JacksonJsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2Encoder;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageWriter;
|
||||
import org.springframework.http.converter.reactive.ResourceHttpMessageWriter;
|
||||
import org.springframework.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
@@ -68,7 +68,7 @@ import static org.springframework.core.ResolvableType.forClassWithGenerics;
|
||||
* Unit tests for {@link ResponseEntityResultHandler}. When adding a test also
|
||||
* consider whether the logic under test is in a parent class, then see:
|
||||
* <ul>
|
||||
* <li>{@code MessageConverterResultHandlerTests},
|
||||
* <li>{@code MessageWriterResultHandlerTests},
|
||||
* <li>{@code ContentNegotiatingResultHandlerSupportTests}
|
||||
* </ul>
|
||||
* @author Rossen Stoyanchev
|
||||
@@ -89,18 +89,18 @@ public class ResponseEntityResultHandlerTests {
|
||||
this.exchange = new DefaultServerWebExchange(request, this.response, new MockWebSessionManager());
|
||||
}
|
||||
|
||||
private ResponseEntityResultHandler createHandler(HttpMessageConverter<?>... converters) {
|
||||
List<HttpMessageConverter<?>> converterList;
|
||||
if (ObjectUtils.isEmpty(converters)) {
|
||||
converterList = new ArrayList<>();
|
||||
converterList.add(new CodecHttpMessageConverter<>(new ByteBufferEncoder()));
|
||||
converterList.add(new CodecHttpMessageConverter<>(new StringEncoder()));
|
||||
converterList.add(new ResourceHttpMessageConverter());
|
||||
converterList.add(new CodecHttpMessageConverter<>(new Jaxb2Encoder()));
|
||||
converterList.add(new CodecHttpMessageConverter<>(new JacksonJsonEncoder()));
|
||||
private ResponseEntityResultHandler createHandler(HttpMessageWriter<?>... writers) {
|
||||
List<HttpMessageWriter<?>> writerList;
|
||||
if (ObjectUtils.isEmpty(writers)) {
|
||||
writerList = new ArrayList<>();
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new StringEncoder()));
|
||||
writerList.add(new ResourceHttpMessageWriter());
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new Jaxb2Encoder()));
|
||||
writerList.add(new EncoderHttpMessageWriter<>(new JacksonJsonEncoder()));
|
||||
}
|
||||
else {
|
||||
converterList = Arrays.asList(converters);
|
||||
writerList = Arrays.asList(writers);
|
||||
}
|
||||
FormattingConversionService service = new DefaultFormattingConversionService();
|
||||
service.addConverter(new MonoToCompletableFutureConverter());
|
||||
@@ -109,7 +109,7 @@ public class ResponseEntityResultHandlerTests {
|
||||
|
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder().build();
|
||||
|
||||
return new ResponseEntityResultHandler(converterList, service, resolver);
|
||||
return new ResponseEntityResultHandler(writerList, service, resolver);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,13 +16,8 @@
|
||||
|
||||
package org.springframework.web.reactive.result.method.annotation;
|
||||
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
import static org.springframework.web.client.reactive.ClientWebRequestBuilders.*;
|
||||
import static org.springframework.web.client.reactive.ResponseExtractors.*;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -34,18 +29,13 @@ import reactor.test.TestSubscriber;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.codec.ByteBufferDecoder;
|
||||
import org.springframework.core.codec.ByteBufferEncoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.core.codec.StringEncoder;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
||||
import org.springframework.http.codec.SseEventEncoder;
|
||||
import org.springframework.http.codec.SseEvent;
|
||||
import org.springframework.http.codec.json.JacksonJsonDecoder;
|
||||
import org.springframework.http.codec.json.JacksonJsonEncoder;
|
||||
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.DecoderHttpMessageReader;
|
||||
import org.springframework.http.converter.reactive.HttpMessageReader;
|
||||
import org.springframework.http.server.reactive.AbstractHttpHandlerIntegrationTests;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.http.server.reactive.bootstrap.JettyHttpServer;
|
||||
@@ -54,9 +44,12 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.reactive.WebClient;
|
||||
import org.springframework.web.reactive.DispatcherHandler;
|
||||
import org.springframework.web.reactive.config.WebReactiveConfiguration;
|
||||
import org.springframework.http.codec.SseEvent;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
import static org.springframework.web.client.reactive.ClientWebRequestBuilders.get;
|
||||
import static org.springframework.web.client.reactive.ResponseExtractors.bodyStream;
|
||||
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@@ -74,11 +67,6 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
assumeFalse(server instanceof JettyHttpServer);
|
||||
|
||||
this.webClient = new WebClient(new ReactorClientHttpConnector());
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
||||
converters.add(new CodecHttpMessageConverter<>(new ByteBufferEncoder(), new ByteBufferDecoder()));
|
||||
converters.add(new CodecHttpMessageConverter<>(new StringEncoder(), new StringDecoder(false)));
|
||||
converters.add(new CodecHttpMessageConverter<>(new JacksonJsonEncoder(), new JacksonJsonDecoder()));
|
||||
this.webClient.setMessageConverters(converters);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,16 +98,14 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sseAsPojo() throws Exception {
|
||||
public void sseAsPerson() throws Exception {
|
||||
Mono<String> result = this.webClient
|
||||
.perform(get("http://localhost:" + port + "/sse/person")
|
||||
.accept(new MediaType("text", "event-stream")))
|
||||
.extract(bodyStream(String.class))
|
||||
.filter(s -> !s.equals("\n"))
|
||||
.map(s -> (s.replace("\n", "")))
|
||||
.takeUntil(s -> {
|
||||
return s.endsWith("foo 1\"}");
|
||||
})
|
||||
.map(s -> s.replace("\n", ""))
|
||||
.takeUntil(s -> s.endsWith("foo 1\"}"))
|
||||
.reduce((s1, s2) -> s1 + s2);
|
||||
|
||||
TestSubscriber
|
||||
@@ -135,7 +121,7 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
.accept(new MediaType("text", "event-stream")))
|
||||
.extract(bodyStream(String.class))
|
||||
.filter(s -> !s.equals("\n"))
|
||||
.map(s -> (s.replace("\n", "")))
|
||||
.map(s -> s.replace("\n", ""))
|
||||
.take(2);
|
||||
|
||||
TestSubscriber
|
||||
@@ -182,12 +168,6 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
public SseController sseController() {
|
||||
return new SseController();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
Encoder<Object> sseEncoder = new SseEventEncoder(Arrays.asList(new JacksonJsonEncoder()));
|
||||
converters.add(new CodecHttpMessageConverter<>(sseEncoder));
|
||||
}
|
||||
}
|
||||
|
||||
private static class Person {
|
||||
|
||||
@@ -58,12 +58,12 @@ import static org.junit.Assert.fail;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for {@link HttpMessageConverterView}.
|
||||
* Unit tests for {@link HttpMessageWriterView}.
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class HttpMessageConverterViewTests {
|
||||
public class HttpMessageWriterViewTests {
|
||||
|
||||
private HttpMessageConverterView view = new HttpMessageConverterView(new JacksonJsonEncoder());
|
||||
private HttpMessageWriterView view = new HttpMessageWriterView(new JacksonJsonEncoder());
|
||||
|
||||
private HandlerResult result;
|
||||
|
||||
@@ -123,7 +123,7 @@ public class HttpMessageConverterViewTests {
|
||||
|
||||
@Test
|
||||
public void extractObjectMultipleMatchesNotSupported() throws Exception {
|
||||
HttpMessageConverterView view = new HttpMessageConverterView(new StringEncoder());
|
||||
HttpMessageWriterView view = new HttpMessageWriterView(new StringEncoder());
|
||||
view.setModelKeys(new HashSet<>(Arrays.asList("foo1", "foo2")));
|
||||
this.model.addAttribute("foo1", "bar1");
|
||||
this.model.addAttribute("foo2", "bar2");
|
||||
@@ -140,7 +140,7 @@ public class HttpMessageConverterViewTests {
|
||||
|
||||
@Test
|
||||
public void extractObjectNotSupported() throws Exception {
|
||||
HttpMessageConverterView view = new HttpMessageConverterView(new Jaxb2Encoder());
|
||||
HttpMessageWriterView view = new HttpMessageWriterView(new Jaxb2Encoder());
|
||||
view.setModelKeys(new HashSet<>(Collections.singletonList("foo1")));
|
||||
this.model.addAttribute("foo1", "bar1");
|
||||
|
||||
Reference in New Issue
Block a user