From 4ff4d5a181aca7f73da01edbc6716468a9da3234 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 16 May 2018 10:41:50 -0400 Subject: [PATCH] Allow client-side use of BodyExtractors#toFormData Issue: SPR-16804 --- .../web/reactive/function/BodyExtractors.java | 19 ++++++++------- .../function/BodyExtractorsTests.java | 24 +++++++++---------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyExtractors.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyExtractors.java index 7d40b99ab6c..84b406949f2 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyExtractors.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyExtractors.java @@ -165,19 +165,22 @@ public abstract class BodyExtractors { /** * Return a {@code BodyExtractor} that reads form data into a {@link MultiValueMap}. + *

As of 5.1 this method can also be used on the client side to read form + * data from a server response (e.g. OAuth). * @return a {@code BodyExtractor} that reads form data */ - // Note that the returned BodyExtractor is parameterized to ServerHttpRequest, not - // ReactiveHttpInputMessage like other methods, since reading form data only typically happens on - // the server-side - public static BodyExtractor>, ServerHttpRequest> toFormData() { - return (request, context) -> { + public static BodyExtractor>, ReactiveHttpInputMessage> toFormData() { + return (message, context) -> { ResolvableType type = FORM_MAP_TYPE; HttpMessageReader> reader = messageReader(type, MediaType.APPLICATION_FORM_URLENCODED, context); - return context.serverResponse() - .map(response -> reader.readMono(type, type, request, response, context.hints())) - .orElseGet(() -> reader.readMono(type, request, context.hints())); + Optional response = context.serverResponse(); + if (response.isPresent() && message instanceof ServerHttpRequest) { + return reader.readMono(type, type, (ServerHttpRequest) message, response.get(), context.hints()); + } + else { + return reader.readMono(type, message, context.hints()); + } }; } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyExtractorsTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyExtractorsTests.java index cc04abfb5d0..fd7d005581d 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyExtractorsTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyExtractorsTests.java @@ -107,7 +107,7 @@ public class BodyExtractorsTests { @Test - public void toMono() throws Exception { + public void toMono() { BodyExtractor, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(String.class); DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); @@ -125,7 +125,7 @@ public class BodyExtractorsTests { } @Test - public void toMonoParameterizedTypeReference() throws Exception { + public void toMonoParameterizedTypeReference() { BodyExtractor>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(new ParameterizedTypeReference>() {}); @@ -147,7 +147,7 @@ public class BodyExtractorsTests { } @Test - public void toMonoWithHints() throws Exception { + public void toMonoWithHints() { BodyExtractor, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(User.class); this.hints.put(JSON_VIEW_HINT, SafeToDeserialize.class); @@ -172,7 +172,7 @@ public class BodyExtractorsTests { } @Test // SPR-15758 - public void toMonoWithEmptyBodyAndNoContentType() throws Exception { + public void toMonoWithEmptyBodyAndNoContentType() { BodyExtractor>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(new ParameterizedTypeReference>() {}); @@ -183,7 +183,7 @@ public class BodyExtractorsTests { } @Test - public void toFlux() throws Exception { + public void toFlux() { BodyExtractor, ReactiveHttpInputMessage> extractor = BodyExtractors.toFlux(String.class); DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); @@ -201,7 +201,7 @@ public class BodyExtractorsTests { } @Test - public void toFluxWithHints() throws Exception { + public void toFluxWithHints() { BodyExtractor, ReactiveHttpInputMessage> extractor = BodyExtractors.toFlux(User.class); this.hints.put(JSON_VIEW_HINT, SafeToDeserialize.class); @@ -230,7 +230,7 @@ public class BodyExtractorsTests { } @Test - public void toFluxUnacceptable() throws Exception { + public void toFluxUnacceptable() { BodyExtractor, ReactiveHttpInputMessage> extractor = BodyExtractors.toFlux(String.class); DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); @@ -266,9 +266,7 @@ public class BodyExtractorsTests { } @Test - public void toFormData() throws Exception { - BodyExtractor>, ServerHttpRequest> extractor = BodyExtractors.toFormData(); - + public void toFormData() { DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); String text = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3"; DefaultDataBuffer dataBuffer = factory.wrap(ByteBuffer.wrap(text.getBytes(StandardCharsets.UTF_8))); @@ -278,7 +276,7 @@ public class BodyExtractorsTests { .contentType(MediaType.APPLICATION_FORM_URLENCODED) .body(body); - Mono> result = extractor.extract(request, this.context); + Mono> result = BodyExtractors.toFormData().extract(request, this.context); StepVerifier.create(result) .consumeNextWith(form -> { @@ -295,7 +293,7 @@ public class BodyExtractorsTests { } @Test - public void toParts() throws Exception { + public void toParts() { BodyExtractor, ServerHttpRequest> extractor = BodyExtractors.toParts(); String bodyContents = "-----------------------------9051914041544843365972754266\r\n" + @@ -353,7 +351,7 @@ public class BodyExtractorsTests { } @Test - public void toDataBuffers() throws Exception { + public void toDataBuffers() { BodyExtractor, ReactiveHttpInputMessage> extractor = BodyExtractors.toDataBuffers(); DefaultDataBufferFactory factory = new DefaultDataBufferFactory();