27
27
28
28
import org .springframework .core .ParameterizedTypeReference ;
29
29
import org .springframework .core .ResolvableType ;
30
+ import org .springframework .http .HttpEntity ;
30
31
import org .springframework .http .HttpHeaders ;
31
32
import org .springframework .http .HttpMethod ;
32
33
import org .springframework .http .MediaType ;
33
- import org .springframework .http .client .MultipartBodyBuilder ;
34
34
import org .springframework .lang .Nullable ;
35
35
import org .springframework .util .Assert ;
36
36
import org .springframework .util .CollectionUtils ;
48
48
* @author Rossen Stoyanchev
49
49
* @since 6.0
50
50
*/
51
- public final class HttpRequestValues {
51
+ public class HttpRequestValues {
52
52
53
53
private static final MultiValueMap <String , String > EMPTY_COOKIES_MAP =
54
54
CollectionUtils .toMultiValueMap (Collections .emptyMap ());
@@ -74,18 +74,11 @@ public final class HttpRequestValues {
74
74
@ Nullable
75
75
private final Object bodyValue ;
76
76
77
- @ Nullable
78
- private final Publisher <?> body ;
79
-
80
- @ Nullable
81
- private final ParameterizedTypeReference <?> bodyElementType ;
82
77
83
-
84
- private HttpRequestValues (@ Nullable HttpMethod httpMethod ,
78
+ protected HttpRequestValues (@ Nullable HttpMethod httpMethod ,
85
79
@ Nullable URI uri , @ Nullable String uriTemplate , Map <String , String > uriVariables ,
86
80
HttpHeaders headers , MultiValueMap <String , String > cookies , Map <String , Object > attributes ,
87
- @ Nullable Object bodyValue ,
88
- @ Nullable Publisher <?> body , @ Nullable ParameterizedTypeReference <?> bodyElementType ) {
81
+ @ Nullable Object bodyValue ) {
89
82
90
83
Assert .isTrue (uri != null || uriTemplate != null , "Neither URI nor URI template" );
91
84
@@ -97,8 +90,6 @@ private HttpRequestValues(@Nullable HttpMethod httpMethod,
97
90
this .cookies = cookies ;
98
91
this .attributes = attributes ;
99
92
this .bodyValue = bodyValue ;
100
- this .body = body ;
101
- this .bodyElementType = bodyElementType ;
102
93
}
103
94
104
95
@@ -161,8 +152,6 @@ public Map<String, Object> getAttributes() {
161
152
162
153
/**
163
154
* Return the request body as a value to be serialized, if set.
164
- * <p>This is mutually exclusive with {@link #getBody()}.
165
- * Only one of the two or neither is set.
166
155
*/
167
156
@ Nullable
168
157
public Object getBodyValue () {
@@ -173,18 +162,24 @@ public Object getBodyValue() {
173
162
* Return the request body as a Publisher.
174
163
* <p>This is mutually exclusive with {@link #getBodyValue()}.
175
164
* Only one of the two or neither is set.
165
+ * @deprecated in favor of {@link ReactiveHttpRequestValues#getBodyPublisher()};
166
+ * to be removed in 6.2
176
167
*/
168
+ @ Deprecated (since = "6.1" , forRemoval = true )
177
169
@ Nullable
178
170
public Publisher <?> getBody () {
179
- return this . body ;
171
+ throw new UnsupportedOperationException () ;
180
172
}
181
173
182
174
/**
183
- * Return the element type for a {@linkplain #getBody() Publisher body}.
175
+ * Return the element type for a Publisher body.
176
+ * @deprecated in favor of {@link ReactiveHttpRequestValues#getBodyPublisherElementType()};
177
+ * to be removed in 6.2
184
178
*/
179
+ @ Deprecated (since = "6.1" , forRemoval = true )
185
180
@ Nullable
186
181
public ParameterizedTypeReference <?> getBodyElementType () {
187
- return this . bodyElementType ;
182
+ throw new UnsupportedOperationException () ;
188
183
}
189
184
190
185
@@ -196,7 +191,7 @@ public static Builder builder() {
196
191
/**
197
192
* Builder for {@link HttpRequestValues}.
198
193
*/
199
- public final static class Builder {
194
+ public static class Builder {
200
195
201
196
@ Nullable
202
197
private HttpMethod httpMethod ;
@@ -220,20 +215,14 @@ public final static class Builder {
220
215
private MultiValueMap <String , String > requestParams ;
221
216
222
217
@ Nullable
223
- private MultipartBodyBuilder multipartBuilder ;
218
+ private MultiValueMap < String , Object > parts ;
224
219
225
220
@ Nullable
226
221
private Map <String , Object > attributes ;
227
222
228
223
@ Nullable
229
224
private Object bodyValue ;
230
225
231
- @ Nullable
232
- private Publisher <?> body ;
233
-
234
- @ Nullable
235
- private ParameterizedTypeReference <?> bodyElementType ;
236
-
237
226
/**
238
227
* Set the HTTP method for the request.
239
228
*/
@@ -327,23 +316,30 @@ public Builder addRequestParameter(String name, String... values) {
327
316
}
328
317
329
318
/**
330
- * Add a part to a multipart request. The part value may be as described
331
- * in {@link MultipartBodyBuilder#part(String, Object)}.
319
+ * Add a part for a multipart request. The part may be:
320
+ * <ul>
321
+ * <li>String -- form field
322
+ * <li>{@link org.springframework.core.io.Resource Resource} -- file part
323
+ * <li>Object -- content to be encoded (e.g. to JSON)
324
+ * <li>{@link HttpEntity} -- part content and headers although generally it's
325
+ * easier to add headers through the returned builder
326
+ * </ul>
332
327
*/
333
328
public Builder addRequestPart (String name , Object part ) {
334
- this .multipartBuilder = (this .multipartBuilder != null ? this .multipartBuilder : new MultipartBodyBuilder ());
335
- this .multipartBuilder . part (name , part );
329
+ this .parts = (this .parts != null ? this .parts : new LinkedMultiValueMap <> ());
330
+ this .parts . add (name , part );
336
331
return this ;
337
332
}
338
333
339
334
/**
340
335
* Variant of {@link #addRequestPart(String, Object)} that allows the
341
336
* part value to be produced by a {@link Publisher}.
337
+ * @deprecated in favor of {@link ReactiveHttpRequestValues.Builder#addRequestPartPublisher};
338
+ * to be removed in 6.2
342
339
*/
340
+ @ Deprecated (since = "6.1" , forRemoval = true )
343
341
public <T , P extends Publisher <T >> Builder addRequestPart (String name , P publisher , ResolvableType type ) {
344
- this .multipartBuilder = (this .multipartBuilder != null ? this .multipartBuilder : new MultipartBodyBuilder ());
345
- this .multipartBuilder .asyncPart (name , publisher , ParameterizedTypeReference .forType (type .getType ()));
346
- return this ;
342
+ throw new UnsupportedOperationException ();
347
343
}
348
344
349
345
/**
@@ -358,25 +354,22 @@ public Builder addAttribute(String name, Object value) {
358
354
}
359
355
360
356
/**
361
- * Set the request body as a concrete value to be serialized.
362
- * <p>This is mutually exclusive with, and resets any previously set
363
- * {@linkplain #setBody(Publisher, ParameterizedTypeReference) body Publisher}.
357
+ * Set the request body as an Object to be serialized.
364
358
*/
365
359
public void setBodyValue (Object bodyValue ) {
366
360
this .bodyValue = bodyValue ;
367
- this .body = null ;
368
- this .bodyElementType = null ;
369
361
}
370
362
371
363
/**
372
- * Set the request body as a concrete value to be serialized .
364
+ * Set the request body as a Reactive Streams Publisher .
373
365
* <p>This is mutually exclusive with, and resets any previously set
374
366
* {@linkplain #setBodyValue(Object) body value}.
367
+ * @deprecated in favor of {@link ReactiveHttpRequestValues.Builder#setBodyPublisher};
368
+ * to be removed in 6.2
375
369
*/
370
+ @ Deprecated (since = "6.1" , forRemoval = true )
376
371
public <T , P extends Publisher <T >> void setBody (P body , ParameterizedTypeReference <T > elementTye ) {
377
- this .body = body ;
378
- this .bodyElementType = elementTye ;
379
- this .bodyValue = null ;
372
+ throw new UnsupportedOperationException ();
380
373
}
381
374
382
375
/**
@@ -389,15 +382,15 @@ public HttpRequestValues build() {
389
382
Map <String , String > uriVars = (this .uriVars != null ? new HashMap <>(this .uriVars ) : Collections .emptyMap ());
390
383
391
384
Object bodyValue = this .bodyValue ;
392
- if (this . multipartBuilder != null ) {
393
- Assert .isTrue (bodyValue == null && this . body == null , "Expected body or request parts, not both" );
394
- bodyValue = this . multipartBuilder . build ();
385
+ if (hasParts () ) {
386
+ Assert .isTrue (! hasBody () , "Expected body or request parts, not both" );
387
+ bodyValue = buildMultipartBody ();
395
388
}
396
389
397
390
if (!CollectionUtils .isEmpty (this .requestParams )) {
398
- if (hasContentType ( MediaType . APPLICATION_FORM_URLENCODED )) {
399
- Assert .isTrue (this . multipartBuilder == null , "Cannot add parts to form data request" );
400
- Assert .isTrue (bodyValue == null && this . body == null , "Cannot set body of form data request" );
391
+ if (hasFormDataContentType ( )) {
392
+ Assert .isTrue (! hasParts () , "Request parts not expected for a form data request" );
393
+ Assert .isTrue (! hasBody () , "Body not expected for a form data request" );
401
394
bodyValue = new LinkedMultiValueMap <>(this .requestParams );
402
395
}
403
396
else if (uri != null ) {
@@ -426,13 +419,26 @@ else if (uri != null) {
426
419
Map <String , Object > attributes = (this .attributes != null ?
427
420
new HashMap <>(this .attributes ) : Collections .emptyMap ());
428
421
429
- return new HttpRequestValues (
430
- this .httpMethod , uri , uriTemplate , uriVars , headers , cookies , attributes ,
431
- bodyValue , this .body , this .bodyElementType );
422
+ return createRequestValues (
423
+ this .httpMethod , uri , uriTemplate , uriVars , headers , cookies , attributes , bodyValue );
424
+ }
425
+
426
+ protected boolean hasParts () {
427
+ return (this .parts != null );
428
+ }
429
+
430
+ protected boolean hasBody () {
431
+ return (this .bodyValue != null );
432
432
}
433
433
434
- private boolean hasContentType (MediaType mediaType ) {
435
- return (this .headers != null && mediaType .equals (this .headers .getContentType ()));
434
+ protected Object buildMultipartBody () {
435
+ Assert .notNull (this .parts , "`parts` is null, was hasParts() not called?" );
436
+ return this .parts ;
437
+ }
438
+
439
+ private boolean hasFormDataContentType () {
440
+ return (this .headers != null &&
441
+ MediaType .APPLICATION_FORM_URLENCODED .equals (this .headers .getContentType ()));
436
442
}
437
443
438
444
private String appendQueryParams (
@@ -453,6 +459,15 @@ private String appendQueryParams(
453
459
return uriComponentsBuilder .build ().toUriString ();
454
460
}
455
461
462
+ protected HttpRequestValues createRequestValues (
463
+ @ Nullable HttpMethod httpMethod ,
464
+ @ Nullable URI uri , @ Nullable String uriTemplate , Map <String , String > uriVars ,
465
+ HttpHeaders headers , MultiValueMap <String , String > cookies , Map <String , Object > attributes ,
466
+ @ Nullable Object bodyValue ) {
467
+
468
+ return new HttpRequestValues (
469
+ this .httpMethod , uri , uriTemplate , uriVars , headers , cookies , attributes , bodyValue );
470
+ }
456
471
}
457
472
458
473
}
0 commit comments