40
40
41
41
import org .springframework .core .ParameterizedTypeReference ;
42
42
import org .springframework .core .ResolvableType ;
43
+ import org .springframework .http .HttpCookie ;
43
44
import org .springframework .http .HttpHeaders ;
44
45
import org .springframework .http .HttpMethod ;
45
46
import org .springframework .http .HttpRequest ;
64
65
import org .springframework .lang .Nullable ;
65
66
import org .springframework .util .Assert ;
66
67
import org .springframework .util .CollectionUtils ;
68
+ import org .springframework .util .LinkedMultiValueMap ;
69
+ import org .springframework .util .MultiValueMap ;
67
70
import org .springframework .web .util .UriBuilder ;
68
71
import org .springframework .web .util .UriBuilderFactory ;
69
72
@@ -103,6 +106,9 @@ final class DefaultRestClient implements RestClient {
103
106
@ Nullable
104
107
private final HttpHeaders defaultHeaders ;
105
108
109
+ @ Nullable
110
+ private final MultiValueMap <String , String > defaultCookies ;
111
+
106
112
@ Nullable
107
113
private final Consumer <RequestHeadersSpec <?>> defaultRequest ;
108
114
@@ -123,6 +129,7 @@ final class DefaultRestClient implements RestClient {
123
129
@ Nullable List <ClientHttpRequestInitializer > initializers ,
124
130
UriBuilderFactory uriBuilderFactory ,
125
131
@ Nullable HttpHeaders defaultHeaders ,
132
+ @ Nullable MultiValueMap <String , String > defaultCookies ,
126
133
@ Nullable Consumer <RequestHeadersSpec <?>> defaultRequest ,
127
134
@ Nullable List <StatusHandler > statusHandlers ,
128
135
List <HttpMessageConverter <?>> messageConverters ,
@@ -135,6 +142,7 @@ final class DefaultRestClient implements RestClient {
135
142
this .interceptors = interceptors ;
136
143
this .uriBuilderFactory = uriBuilderFactory ;
137
144
this .defaultHeaders = defaultHeaders ;
145
+ this .defaultCookies = defaultCookies ;
138
146
this .defaultRequest = defaultRequest ;
139
147
this .defaultStatusHandlers = (statusHandlers != null ? new ArrayList <>(statusHandlers ) : new ArrayList <>());
140
148
this .messageConverters = messageConverters ;
@@ -293,6 +301,8 @@ private static <T> Class<T> bodyClass(Type type) {
293
301
294
302
private class DefaultRequestBodyUriSpec implements RequestBodyUriSpec {
295
303
304
+ private static final String COOKIE_DELIMITER = "; " ;
305
+
296
306
private final HttpMethod httpMethod ;
297
307
298
308
@ Nullable
@@ -301,6 +311,9 @@ private class DefaultRequestBodyUriSpec implements RequestBodyUriSpec {
301
311
@ Nullable
302
312
private HttpHeaders headers ;
303
313
314
+ @ Nullable
315
+ private MultiValueMap <String , String > cookies ;
316
+
304
317
@ Nullable
305
318
private InternalBody body ;
306
319
@@ -356,6 +369,13 @@ private HttpHeaders getHeaders() {
356
369
return this .headers ;
357
370
}
358
371
372
+ private MultiValueMap <String , String > getCookies () {
373
+ if (this .cookies == null ) {
374
+ this .cookies = new LinkedMultiValueMap <>(3 );
375
+ }
376
+ return this .cookies ;
377
+ }
378
+
359
379
@ Override
360
380
public DefaultRequestBodyUriSpec header (String headerName , String ... headerValues ) {
361
381
for (String headerValue : headerValues ) {
@@ -382,6 +402,18 @@ public DefaultRequestBodyUriSpec acceptCharset(Charset... acceptableCharsets) {
382
402
return this ;
383
403
}
384
404
405
+ @ Override
406
+ public DefaultRequestBodyUriSpec cookie (String name , String value ) {
407
+ getCookies ().add (name , value );
408
+ return this ;
409
+ }
410
+
411
+ @ Override
412
+ public DefaultRequestBodyUriSpec cookies (Consumer <MultiValueMap <String , String >> cookiesConsumer ) {
413
+ cookiesConsumer .accept (getCookies ());
414
+ return this ;
415
+ }
416
+
385
417
@ Override
386
418
public DefaultRequestBodyUriSpec contentType (MediaType contentType ) {
387
419
getHeaders ().setContentType (contentType );
@@ -525,6 +557,12 @@ private <T> T exchangeInternal(ExchangeFunction<T> exchangeFunction, boolean clo
525
557
try {
526
558
uri = initUri ();
527
559
HttpHeaders headers = initHeaders ();
560
+
561
+ MultiValueMap <String , String > cookies = initCookies ();
562
+ if (!CollectionUtils .isEmpty (cookies )) {
563
+ headers .put (HttpHeaders .COOKIE , List .of (cookiesToHeaderValue (cookies )));
564
+ }
565
+
528
566
ClientHttpRequest clientRequest = createRequest (uri );
529
567
clientRequest .getHeaders ().addAll (headers );
530
568
Map <String , Object > attributes = getAttributes ();
@@ -599,6 +637,28 @@ else if (CollectionUtils.isEmpty(defaultHeaders)) {
599
637
}
600
638
}
601
639
640
+ private MultiValueMap <String , String > initCookies () {
641
+ MultiValueMap <String , String > mergedCookies = new LinkedMultiValueMap <>();
642
+
643
+ if (!CollectionUtils .isEmpty (defaultCookies )) {
644
+ mergedCookies .putAll (defaultCookies );
645
+ }
646
+
647
+ if (!CollectionUtils .isEmpty (this .cookies )) {
648
+ mergedCookies .putAll (this .cookies );
649
+ }
650
+
651
+ return mergedCookies ;
652
+ }
653
+
654
+ private String cookiesToHeaderValue (MultiValueMap <String , String > cookies ) {
655
+ List <String > flatCookies = new ArrayList <>();
656
+ cookies .forEach ((name , cookieValues ) -> cookieValues .forEach (value ->
657
+ flatCookies .add (new HttpCookie (name , value ).toString ())
658
+ ));
659
+ return String .join (COOKIE_DELIMITER , flatCookies );
660
+ }
661
+
602
662
private ClientHttpRequest createRequest (URI uri ) throws IOException {
603
663
ClientHttpRequestFactory factory ;
604
664
if (DefaultRestClient .this .interceptors != null ) {
0 commit comments