From b77e03b1e0af83ddbd5eee3ee2bcd0f6b3b26cfe Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Thu, 19 Jan 2017 11:12:24 +0100 Subject: [PATCH] Map to UnsupportedMediaTypeStatusException This commit maps the UnsupportedMediaTypeException, used by both client and server, to a server-side UnsupportedMediaTypeStatusException in the functional web framework. --- .../function/server/DefaultServerRequest.java | 15 ++++++++++-- .../server/DefaultServerRequestTests.java | 23 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java index b5de5881a80..e42e5648d68 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.OptionalLong; +import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; @@ -39,7 +40,9 @@ import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.util.Assert; import org.springframework.web.reactive.function.BodyExtractor; import org.springframework.web.reactive.function.BodyExtractors; +import org.springframework.web.reactive.function.UnsupportedMediaTypeException; import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.UnsupportedMediaTypeStatusException; import org.springframework.web.server.WebSession; /** @@ -48,6 +51,12 @@ import org.springframework.web.server.WebSession; */ class DefaultServerRequest implements ServerRequest { + private static final Function ERROR_MAPPER = + ex -> ex.getContentType() + .map(contentType -> new UnsupportedMediaTypeStatusException(contentType, + ex.getSupportedMediaTypes())) + .orElseGet(() -> new UnsupportedMediaTypeStatusException(ex.getMessage())); + private final ServerWebExchange exchange; private final Headers headers; @@ -100,12 +109,14 @@ class DefaultServerRequest implements ServerRequest { @Override public Mono bodyToMono(Class elementClass) { - return body(BodyExtractors.toMono(elementClass)); + Mono mono = body(BodyExtractors.toMono(elementClass)); + return mono.mapError(UnsupportedMediaTypeException.class, ERROR_MAPPER); } @Override public Flux bodyToFlux(Class elementClass) { - return body(BodyExtractors.toFlux(elementClass)); + Flux flux = body(BodyExtractors.toFlux(elementClass)); + return flux.mapError(UnsupportedMediaTypeException.class, ERROR_MAPPER); } @Override diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/server/DefaultServerRequestTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/server/DefaultServerRequestTests.java index d76ec3e1c96..ea9a32bfb8d 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/server/DefaultServerRequestTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/server/DefaultServerRequestTests.java @@ -32,6 +32,7 @@ import org.junit.Before; import org.junit.Test; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; import org.springframework.core.codec.StringDecoder; import org.springframework.core.io.buffer.DataBuffer; @@ -48,6 +49,7 @@ import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.UnsupportedMediaTypeStatusException; import org.springframework.web.server.WebSession; import static org.junit.Assert.assertEquals; @@ -235,4 +237,25 @@ public class DefaultServerRequestTests { assertEquals(Collections.singletonList("foo"), result.block()); } + @Test + public void bodyUnacceptable() throws Exception { + DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); + DefaultDataBuffer dataBuffer = + factory.wrap(ByteBuffer.wrap("foo".getBytes(StandardCharsets.UTF_8))); + Flux body = Flux.just(dataBuffer); + + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.TEXT_PLAIN); + when(mockRequest.getHeaders()).thenReturn(httpHeaders); + when(mockRequest.getBody()).thenReturn(body); + + Set> messageReaders = Collections.emptySet(); + when(mockHandlerStrategies.messageReaders()).thenReturn(messageReaders::stream); + + Flux resultFlux = defaultRequest.bodyToFlux(String.class); + StepVerifier.create(resultFlux) + .expectError(UnsupportedMediaTypeStatusException.class) + .verify(); + } + } \ No newline at end of file