Skip to content

Commit 4ff4d5a

Browse files
committed
Allow client-side use of BodyExtractors#toFormData
Issue: SPR-16804
1 parent 020c6c0 commit 4ff4d5a

File tree

2 files changed

+22
-21
lines changed

2 files changed

+22
-21
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyExtractors.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,19 +165,22 @@ private static <T> Flux<T> permitEmptyOrFail(ReactiveHttpInputMessage message, U
165165

166166
/**
167167
* Return a {@code BodyExtractor} that reads form data into a {@link MultiValueMap}.
168+
* <p>As of 5.1 this method can also be used on the client side to read form
169+
* data from a server response (e.g. OAuth).
168170
* @return a {@code BodyExtractor} that reads form data
169171
*/
170-
// Note that the returned BodyExtractor is parameterized to ServerHttpRequest, not
171-
// ReactiveHttpInputMessage like other methods, since reading form data only typically happens on
172-
// the server-side
173-
public static BodyExtractor<Mono<MultiValueMap<String, String>>, ServerHttpRequest> toFormData() {
174-
return (request, context) -> {
172+
public static BodyExtractor<Mono<MultiValueMap<String, String>>, ReactiveHttpInputMessage> toFormData() {
173+
return (message, context) -> {
175174
ResolvableType type = FORM_MAP_TYPE;
176175
HttpMessageReader<MultiValueMap<String, String>> reader =
177176
messageReader(type, MediaType.APPLICATION_FORM_URLENCODED, context);
178-
return context.serverResponse()
179-
.map(response -> reader.readMono(type, type, request, response, context.hints()))
180-
.orElseGet(() -> reader.readMono(type, request, context.hints()));
177+
Optional<ServerHttpResponse> response = context.serverResponse();
178+
if (response.isPresent() && message instanceof ServerHttpRequest) {
179+
return reader.readMono(type, type, (ServerHttpRequest) message, response.get(), context.hints());
180+
}
181+
else {
182+
return reader.readMono(type, message, context.hints());
183+
}
181184
};
182185
}
183186

spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyExtractorsTests.java

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public Map<String, Object> hints() {
107107

108108

109109
@Test
110-
public void toMono() throws Exception {
110+
public void toMono() {
111111
BodyExtractor<Mono<String>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(String.class);
112112

113113
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
@@ -125,7 +125,7 @@ public void toMono() throws Exception {
125125
}
126126

127127
@Test
128-
public void toMonoParameterizedTypeReference() throws Exception {
128+
public void toMonoParameterizedTypeReference() {
129129
BodyExtractor<Mono<Map<String, String>>, ReactiveHttpInputMessage> extractor =
130130
BodyExtractors.toMono(new ParameterizedTypeReference<Map<String, String>>() {});
131131

@@ -147,7 +147,7 @@ public void toMonoParameterizedTypeReference() throws Exception {
147147
}
148148

149149
@Test
150-
public void toMonoWithHints() throws Exception {
150+
public void toMonoWithHints() {
151151
BodyExtractor<Mono<User>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(User.class);
152152
this.hints.put(JSON_VIEW_HINT, SafeToDeserialize.class);
153153

@@ -172,7 +172,7 @@ public void toMonoWithHints() throws Exception {
172172
}
173173

174174
@Test // SPR-15758
175-
public void toMonoWithEmptyBodyAndNoContentType() throws Exception {
175+
public void toMonoWithEmptyBodyAndNoContentType() {
176176
BodyExtractor<Mono<Map<String, String>>, ReactiveHttpInputMessage> extractor =
177177
BodyExtractors.toMono(new ParameterizedTypeReference<Map<String, String>>() {});
178178

@@ -183,7 +183,7 @@ public void toMonoWithEmptyBodyAndNoContentType() throws Exception {
183183
}
184184

185185
@Test
186-
public void toFlux() throws Exception {
186+
public void toFlux() {
187187
BodyExtractor<Flux<String>, ReactiveHttpInputMessage> extractor = BodyExtractors.toFlux(String.class);
188188

189189
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
@@ -201,7 +201,7 @@ public void toFlux() throws Exception {
201201
}
202202

203203
@Test
204-
public void toFluxWithHints() throws Exception {
204+
public void toFluxWithHints() {
205205
BodyExtractor<Flux<User>, ReactiveHttpInputMessage> extractor = BodyExtractors.toFlux(User.class);
206206
this.hints.put(JSON_VIEW_HINT, SafeToDeserialize.class);
207207

@@ -230,7 +230,7 @@ public void toFluxWithHints() throws Exception {
230230
}
231231

232232
@Test
233-
public void toFluxUnacceptable() throws Exception {
233+
public void toFluxUnacceptable() {
234234
BodyExtractor<Flux<String>, ReactiveHttpInputMessage> extractor = BodyExtractors.toFlux(String.class);
235235

236236
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
@@ -266,9 +266,7 @@ public Map<String, Object> hints() {
266266
}
267267

268268
@Test
269-
public void toFormData() throws Exception {
270-
BodyExtractor<Mono<MultiValueMap<String, String>>, ServerHttpRequest> extractor = BodyExtractors.toFormData();
271-
269+
public void toFormData() {
272270
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
273271
String text = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3";
274272
DefaultDataBuffer dataBuffer = factory.wrap(ByteBuffer.wrap(text.getBytes(StandardCharsets.UTF_8)));
@@ -278,7 +276,7 @@ public void toFormData() throws Exception {
278276
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
279277
.body(body);
280278

281-
Mono<MultiValueMap<String, String>> result = extractor.extract(request, this.context);
279+
Mono<MultiValueMap<String, String>> result = BodyExtractors.toFormData().extract(request, this.context);
282280

283281
StepVerifier.create(result)
284282
.consumeNextWith(form -> {
@@ -295,7 +293,7 @@ public void toFormData() throws Exception {
295293
}
296294

297295
@Test
298-
public void toParts() throws Exception {
296+
public void toParts() {
299297
BodyExtractor<Flux<Part>, ServerHttpRequest> extractor = BodyExtractors.toParts();
300298

301299
String bodyContents = "-----------------------------9051914041544843365972754266\r\n" +
@@ -353,7 +351,7 @@ public void toParts() throws Exception {
353351
}
354352

355353
@Test
356-
public void toDataBuffers() throws Exception {
354+
public void toDataBuffers() {
357355
BodyExtractor<Flux<DataBuffer>, ReactiveHttpInputMessage> extractor = BodyExtractors.toDataBuffers();
358356

359357
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();

0 commit comments

Comments
 (0)