Polish ResponseBodyArgumentResolver
This commit is contained in:
parent
5c236e1edf
commit
0a88d5983a
|
|
@ -25,7 +25,6 @@ import reactor.core.publisher.Mono;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.core.io.buffer.DataBuffer;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
|
|
@ -35,8 +34,13 @@ import org.springframework.web.reactive.result.method.HandlerMethodArgumentResol
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Resolves method arguments annotated with {@code @RequestBody} by reading and
|
||||||
|
* decoding the body of the request through a compatible
|
||||||
|
* {@code HttpMessageConverter}.
|
||||||
|
*
|
||||||
* @author Sebastien Deleuze
|
* @author Sebastien Deleuze
|
||||||
* @author Stephane Maldini
|
* @author Stephane Maldini
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
*/
|
*/
|
||||||
public class RequestBodyArgumentResolver implements HandlerMethodArgumentResolver {
|
public class RequestBodyArgumentResolver implements HandlerMethodArgumentResolver {
|
||||||
|
|
||||||
|
|
@ -44,15 +48,30 @@ public class RequestBodyArgumentResolver implements HandlerMethodArgumentResolve
|
||||||
|
|
||||||
private final ConversionService conversionService;
|
private final ConversionService conversionService;
|
||||||
|
|
||||||
public RequestBodyArgumentResolver(List<HttpMessageConverter<?>> messageConverters,
|
|
||||||
|
/**
|
||||||
|
* Constructor with message converters and a ConversionService.
|
||||||
|
* @param converters converters for reading the request body with
|
||||||
|
* @param service for converting to other reactive types from Flux and Mono
|
||||||
|
*/
|
||||||
|
public RequestBodyArgumentResolver(List<HttpMessageConverter<?>> converters,
|
||||||
ConversionService service) {
|
ConversionService service) {
|
||||||
Assert.notEmpty(messageConverters, "At least one message converter is required.");
|
|
||||||
|
Assert.notEmpty(converters, "At least one message converter is required.");
|
||||||
Assert.notNull(service, "'conversionService' is required.");
|
Assert.notNull(service, "'conversionService' is required.");
|
||||||
this.messageConverters = messageConverters;
|
this.messageConverters = converters;
|
||||||
this.conversionService = service;
|
this.conversionService = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the configured message converters.
|
||||||
|
*/
|
||||||
|
public List<HttpMessageConverter<?>> getMessageConverters() {
|
||||||
|
return this.messageConverters;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsParameter(MethodParameter parameter) {
|
public boolean supportsParameter(MethodParameter parameter) {
|
||||||
return parameter.hasParameterAnnotation(RequestBody.class);
|
return parameter.hasParameterAnnotation(RequestBody.class);
|
||||||
|
|
@ -70,35 +89,29 @@ public class RequestBodyArgumentResolver implements HandlerMethodArgumentResolve
|
||||||
mediaType = MediaType.APPLICATION_OCTET_STREAM;
|
mediaType = MediaType.APPLICATION_OCTET_STREAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
Flux<DataBuffer> body = exchange.getRequest().getBody();
|
Flux<?> elementFlux = exchange.getRequest().getBody();
|
||||||
Flux<?> elementFlux;
|
|
||||||
|
|
||||||
HttpMessageConverter<?> messageConverter =
|
HttpMessageConverter<?> converter = getMessageConverter(elementType, mediaType);
|
||||||
resolveMessageConverter(elementType, mediaType);
|
if (converter != null) {
|
||||||
if (messageConverter != null) {
|
elementFlux = converter.read(elementType, exchange.getRequest());
|
||||||
elementFlux = messageConverter.read(elementType, exchange.getRequest());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
elementFlux = body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.conversionService.canConvert(Publisher.class, type.getRawClass())) {
|
if (type.getRawClass() == Flux.class) {
|
||||||
return Mono.just(this.conversionService
|
|
||||||
.convert(elementFlux, type.getRawClass()));
|
|
||||||
}
|
|
||||||
else if (type.getRawClass() == Flux.class) {
|
|
||||||
return Mono.just(elementFlux);
|
return Mono.just(elementFlux);
|
||||||
}
|
}
|
||||||
else if (type.getRawClass() == Mono.class) {
|
else if (type.getRawClass() == Mono.class) {
|
||||||
return Mono.just(Mono.from(elementFlux));
|
return Mono.just(Mono.from(elementFlux));
|
||||||
}
|
}
|
||||||
|
else if (this.conversionService.canConvert(Publisher.class, type.getRawClass())) {
|
||||||
|
Object target = this.conversionService.convert(elementFlux, type.getRawClass());
|
||||||
|
return Mono.just(target);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Currently manage only "Foo" parameter, not "List<Foo>" parameters, Stéphane is going to add toIterable/toIterator to Flux to support that use case
|
// TODO Currently manage only "Foo" parameter, not "List<Foo>" parameters, Stéphane is going to add toIterable/toIterator to Flux to support that use case
|
||||||
return elementFlux.next().map(o -> o);
|
return elementFlux.next().map(o -> o);
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpMessageConverter<?> resolveMessageConverter(ResolvableType type,
|
private HttpMessageConverter<?> getMessageConverter(ResolvableType type, MediaType mediaType) {
|
||||||
MediaType mediaType) {
|
|
||||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
||||||
if (messageConverter.canRead(type, mediaType)) {
|
if (messageConverter.canRead(type, mediaType)) {
|
||||||
return messageConverter;
|
return messageConverter;
|
||||||
|
|
|
||||||
|
|
@ -78,14 +78,6 @@ public class ResponseBodyResultHandler extends ContentNegotiatingResultHandlerSu
|
||||||
this(converters, conversionService, new HeaderContentTypeResolver());
|
this(converters, conversionService, new HeaderContentTypeResolver());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the configured message converters.
|
|
||||||
*/
|
|
||||||
public List<HttpMessageConverter<?>> getMessageConverters() {
|
|
||||||
return this.messageConverters;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor with message converters, a {@code ConversionService}, and a
|
* Constructor with message converters, a {@code ConversionService}, and a
|
||||||
* {@code RequestedContentTypeResolver}.
|
* {@code RequestedContentTypeResolver}.
|
||||||
|
|
@ -105,6 +97,13 @@ public class ResponseBodyResultHandler extends ContentNegotiatingResultHandlerSu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the configured message converters.
|
||||||
|
*/
|
||||||
|
public List<HttpMessageConverter<?>> getMessageConverters() {
|
||||||
|
return this.messageConverters;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(HandlerResult result) {
|
public boolean supports(HandlerResult result) {
|
||||||
Object handler = result.getHandler();
|
Object handler = result.getHandler();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue