Skip to content

Commit 73e5aa3

Browse files
committed
Polishing contribution
See gh-33697
1 parent a0af708 commit 73e5aa3

File tree

5 files changed

+95
-94
lines changed

5 files changed

+95
-94
lines changed

spring-web/src/main/java/org/springframework/web/client/DefaultRestClient.java

+27-20
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040

4141
import org.springframework.core.ParameterizedTypeReference;
4242
import org.springframework.core.ResolvableType;
43-
import org.springframework.http.HttpCookie;
4443
import org.springframework.http.HttpHeaders;
4544
import org.springframework.http.HttpMethod;
4645
import org.springframework.http.HttpRequest;
@@ -301,8 +300,6 @@ private static <T> Class<T> bodyClass(Type type) {
301300

302301
private class DefaultRequestBodyUriSpec implements RequestBodyUriSpec {
303302

304-
private static final String COOKIE_DELIMITER = "; ";
305-
306303
private final HttpMethod httpMethod;
307304

308305
@Nullable
@@ -557,10 +554,9 @@ private <T> T exchangeInternal(ExchangeFunction<T> exchangeFunction, boolean clo
557554
try {
558555
uri = initUri();
559556
HttpHeaders headers = initHeaders();
560-
561557
MultiValueMap<String, String> cookies = initCookies();
562558
if (!CollectionUtils.isEmpty(cookies)) {
563-
headers.put(HttpHeaders.COOKIE, List.of(cookiesToHeaderValue(cookies)));
559+
headers.set(HttpHeaders.COOKIE, serializeCookies(cookies));
564560
}
565561

566562
ClientHttpRequest clientRequest = createRequest(uri);
@@ -638,25 +634,36 @@ else if (CollectionUtils.isEmpty(defaultHeaders)) {
638634
}
639635

640636
private MultiValueMap<String, String> initCookies() {
641-
MultiValueMap<String, String> mergedCookies = new LinkedMultiValueMap<>();
642-
643-
if(!CollectionUtils.isEmpty(defaultCookies)) {
644-
mergedCookies.putAll(defaultCookies);
637+
MultiValueMap<String, String> defaultCookies = DefaultRestClient.this.defaultCookies;
638+
if (CollectionUtils.isEmpty(this.cookies)) {
639+
return (defaultCookies != null ? defaultCookies : new LinkedMultiValueMap<>());
645640
}
646-
647-
if(!CollectionUtils.isEmpty(this.cookies)) {
648-
mergedCookies.putAll(this.cookies);
641+
else if (CollectionUtils.isEmpty(defaultCookies)) {
642+
return this.cookies;
643+
}
644+
else {
645+
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
646+
map.putAll(DefaultRestClient.this.defaultCookies);
647+
map.putAll(this.cookies);
648+
return map;
649649
}
650-
651-
return mergedCookies;
652650
}
653651

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);
652+
private String serializeCookies(MultiValueMap<String, String> cookies) {
653+
boolean first = true;
654+
StringBuilder sb = new StringBuilder();
655+
for (Map.Entry<String, List<String>> entry : cookies.entrySet()) {
656+
for (String value : entry.getValue()) {
657+
if (!first) {
658+
sb.append("; ");
659+
}
660+
else {
661+
first = false;
662+
}
663+
sb.append(entry.getKey()).append("=").append(value);
664+
}
665+
}
666+
return sb.toString();
660667
}
661668

662669
private ClientHttpRequest createRequest(URI uri) throws IOException {

spring-web/src/main/java/org/springframework/web/client/DefaultRestClientBuilder.java

+19-23
Original file line numberDiff line numberDiff line change
@@ -468,21 +468,21 @@ public RestClient.Builder clone() {
468468
public RestClient build() {
469469
ClientHttpRequestFactory requestFactory = initRequestFactory();
470470
UriBuilderFactory uriBuilderFactory = initUriBuilderFactory();
471+
471472
HttpHeaders defaultHeaders = copyDefaultHeaders();
472473
MultiValueMap<String, String> defaultCookies = copyDefaultCookies();
473-
List<HttpMessageConverter<?>> messageConverters = (this.messageConverters != null ?
474-
this.messageConverters : initMessageConverters());
475-
return new DefaultRestClient(requestFactory,
476-
this.interceptors, this.initializers, uriBuilderFactory,
477-
defaultHeaders,
478-
defaultCookies,
474+
475+
List<HttpMessageConverter<?>> converters =
476+
(this.messageConverters != null ? this.messageConverters : initMessageConverters());
477+
478+
return new DefaultRestClient(
479+
requestFactory, this.interceptors, this.initializers,
480+
uriBuilderFactory, defaultHeaders, defaultCookies,
479481
this.defaultRequest,
480482
this.statusHandlers,
481-
messageConverters,
482-
this.observationRegistry,
483-
this.observationConvention,
484-
new DefaultRestClientBuilder(this)
485-
);
483+
converters,
484+
this.observationRegistry, this.observationConvention,
485+
new DefaultRestClientBuilder(this));
486486
}
487487

488488
private ClientHttpRequestFactory initRequestFactory() {
@@ -519,26 +519,22 @@ private UriBuilderFactory initUriBuilderFactory() {
519519

520520
@Nullable
521521
private HttpHeaders copyDefaultHeaders() {
522-
if (this.defaultHeaders != null) {
523-
HttpHeaders copy = new HttpHeaders();
524-
this.defaultHeaders.forEach((key, values) -> copy.put(key, new ArrayList<>(values)));
525-
return HttpHeaders.readOnlyHttpHeaders(copy);
526-
}
527-
else {
522+
if (this.defaultHeaders == null) {
528523
return null;
529524
}
525+
HttpHeaders copy = new HttpHeaders();
526+
this.defaultHeaders.forEach((key, values) -> copy.put(key, new ArrayList<>(values)));
527+
return HttpHeaders.readOnlyHttpHeaders(copy);
530528
}
531529

532530
@Nullable
533531
private MultiValueMap<String, String> copyDefaultCookies() {
534-
if (this.defaultCookies != null) {
535-
MultiValueMap<String, String> copy = new LinkedMultiValueMap<>(this.defaultCookies.size());
536-
this.defaultCookies.forEach((key, values) -> copy.put(key, new ArrayList<>(values)));
537-
return CollectionUtils.unmodifiableMultiValueMap(copy);
538-
}
539-
else {
532+
if (this.defaultCookies == null) {
540533
return null;
541534
}
535+
MultiValueMap<String, String> copy = new LinkedMultiValueMap<>(this.defaultCookies.size());
536+
this.defaultCookies.forEach((key, values) -> copy.put(key, new ArrayList<>(values)));
537+
return CollectionUtils.unmodifiableMultiValueMap(copy);
542538
}
543539

544540
}

spring-web/src/test/java/org/springframework/web/client/RestClientBuilderTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ void defaultCookieAddsCookieToDefaultCookiesMap() {
151151
}
152152

153153
@Test
154-
void defaultCookieWithMultipleValuesAddsCookieToDefaultCookiesMapWithAllValues() {
154+
void defaultCookieWithMultipleValuesAddsCookieToDefaultCookiesMap() {
155155
RestClient.Builder builder = RestClient.builder();
156156

157157
builder.defaultCookie("myCookie", "testValue1", "testValue2");

spring-web/src/test/java/org/springframework/web/client/RestClientIntegrationTests.java

+36-30
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.lang.annotation.Target;
2424
import java.net.URI;
2525
import java.net.URISyntaxException;
26-
import java.nio.charset.StandardCharsets;
2726
import java.util.List;
2827
import java.util.Map;
2928
import java.util.function.Consumer;
@@ -56,6 +55,7 @@
5655
import org.springframework.util.MultiValueMap;
5756
import org.springframework.web.testfixture.xml.Pojo;
5857

58+
import static java.nio.charset.StandardCharsets.UTF_8;
5959
import static org.assertj.core.api.Assertions.assertThat;
6060
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
6161
import static org.junit.jupiter.api.Assumptions.assumeFalse;
@@ -660,8 +660,8 @@ void statusHandlerSuppressedErrorSignalWithEntity(ClientHttpRequestFactory reque
660660
startServer(requestFactory);
661661

662662
String content = "Internal Server error";
663-
prepareResponse(response -> response.setResponseCode(500)
664-
.setHeader("Content-Type", "text/plain").setBody(content));
663+
prepareResponse(response ->
664+
response.setResponseCode(500).setHeader("Content-Type", "text/plain").setBody(content));
665665

666666
ResponseEntity<String> result = this.restClient.get()
667667
.uri("/").accept(MediaType.APPLICATION_JSON)
@@ -689,7 +689,7 @@ void exchangeForPlainText(ClientHttpRequestFactory requestFactory) {
689689
String result = this.restClient.get()
690690
.uri("/greeting")
691691
.header("X-Test-Header", "testvalue")
692-
.exchange((request, response) -> new String(RestClientUtils.getBody(response), StandardCharsets.UTF_8));
692+
.exchange((request, response) -> new String(RestClientUtils.getBody(response), UTF_8));
693693

694694
assertThat(result).isEqualTo("Hello Spring!");
695695

@@ -753,12 +753,12 @@ void exchangeForJsonArray(ClientHttpRequestFactory requestFactory) {
753753
void exchangeFor404(ClientHttpRequestFactory requestFactory) {
754754
startServer(requestFactory);
755755

756-
prepareResponse(response -> response.setResponseCode(404)
757-
.setHeader("Content-Type", "text/plain").setBody("Not Found"));
756+
prepareResponse(response ->
757+
response.setResponseCode(404).setHeader("Content-Type", "text/plain").setBody("Not Found"));
758758

759759
String result = this.restClient.get()
760760
.uri("/greeting")
761-
.exchange((request, response) -> new String(RestClientUtils.getBody(response), StandardCharsets.UTF_8));
761+
.exchange((request, response) -> new String(RestClientUtils.getBody(response), UTF_8));
762762

763763
assertThat(result).isEqualTo("Not Found");
764764

@@ -770,8 +770,8 @@ void exchangeFor404(ClientHttpRequestFactory requestFactory) {
770770
void requestInitializer(ClientHttpRequestFactory requestFactory) {
771771
startServer(requestFactory);
772772

773-
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
774-
.setBody("Hello Spring!"));
773+
prepareResponse(response ->
774+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
775775

776776
RestClient initializedClient = this.restClient.mutate()
777777
.requestInitializer(request -> request.getHeaders().add("foo", "bar"))
@@ -792,9 +792,8 @@ void requestInitializer(ClientHttpRequestFactory requestFactory) {
792792
void requestInterceptor(ClientHttpRequestFactory requestFactory) {
793793
startServer(requestFactory);
794794

795-
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
796-
.setBody("Hello Spring!"));
797-
795+
prepareResponse(response ->
796+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
798797

799798
RestClient interceptedClient = this.restClient.mutate()
800799
.requestInterceptor((request, body, execution) -> {
@@ -819,6 +818,7 @@ void retrieveDefaultCookiesAsCookieHeader(ClientHttpRequestFactory requestFactor
819818
startServer(requestFactory);
820819
prepareResponse(response ->
821820
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
821+
822822
RestClient restClientWithCookies = this.restClient.mutate()
823823
.defaultCookie("testCookie", "firstValue", "secondValue")
824824
.build();
@@ -852,8 +852,8 @@ void filterForErrorHandling(ClientHttpRequestFactory requestFactory) {
852852
RestClient interceptedClient = this.restClient.mutate().requestInterceptor(interceptor).build();
853853

854854
// header not present
855-
prepareResponse(response -> response
856-
.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
855+
prepareResponse(response ->
856+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
857857

858858
assertThatExceptionOfType(MyException.class).isThrownBy(() ->
859859
interceptedClient.get()
@@ -881,8 +881,8 @@ void filterForErrorHandling(ClientHttpRequestFactory requestFactory) {
881881
void defaultHeaders(ClientHttpRequestFactory requestFactory) {
882882
startServer(requestFactory);
883883

884-
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
885-
.setBody("Hello Spring!"));
884+
prepareResponse(response ->
885+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
886886

887887
RestClient headersClient = this.restClient.mutate()
888888
.defaultHeaders(headers -> headers.add("foo", "bar"))
@@ -903,8 +903,8 @@ void defaultHeaders(ClientHttpRequestFactory requestFactory) {
903903
void defaultRequest(ClientHttpRequestFactory requestFactory) {
904904
startServer(requestFactory);
905905

906-
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
907-
.setBody("Hello Spring!"));
906+
prepareResponse(response ->
907+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
908908

909909
RestClient headersClient = this.restClient.mutate()
910910
.defaultRequest(request -> request.header("foo", "bar"))
@@ -925,8 +925,8 @@ void defaultRequest(ClientHttpRequestFactory requestFactory) {
925925
void defaultRequestOverride(ClientHttpRequestFactory requestFactory) {
926926
startServer(requestFactory);
927927

928-
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
929-
.setBody("Hello Spring!"));
928+
prepareResponse(response ->
929+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
930930

931931
RestClient headersClient = this.restClient.mutate()
932932
.defaultRequest(request -> request.accept(MediaType.APPLICATION_JSON))
@@ -948,8 +948,8 @@ void defaultRequestOverride(ClientHttpRequestFactory requestFactory) {
948948
void relativeUri(ClientHttpRequestFactory requestFactory) throws URISyntaxException {
949949
startServer(requestFactory);
950950

951-
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
952-
.setBody("Hello Spring!"));
951+
prepareResponse(response ->
952+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
953953

954954
URI uri = new URI(null, null, "/foo bar", null);
955955

@@ -969,23 +969,28 @@ void relativeUri(ClientHttpRequestFactory requestFactory) throws URISyntaxExcept
969969
@ParameterizedRestClientTest
970970
void cookieAddsCookie(ClientHttpRequestFactory requestFactory) {
971971
startServer(requestFactory);
972-
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
973-
.setBody("Hello Spring!"));
972+
973+
prepareResponse(response ->
974+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
974975

975976
this.restClient.get()
976977
.uri("/greeting")
977-
.cookie("foo", "bar")
978+
.cookie("c1", "v1a")
979+
.cookie("c1", "v1b")
980+
.cookie("c2", "v2a")
978981
.retrieve()
979982
.body(String.class);
980983

981-
expectRequest(request -> assertThat(request.getHeader("Cookie")).isEqualTo("foo=bar"));
984+
expectRequest(request -> assertThat(request.getHeader("Cookie")).isEqualTo("c1=v1a; c1=v1b; c2=v2a"));
982985
}
983986

984987
@ParameterizedRestClientTest
985988
void cookieOverridesDefaultCookie(ClientHttpRequestFactory requestFactory) {
986989
startServer(requestFactory);
987-
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
988-
.setBody("Hello Spring!"));
990+
991+
prepareResponse(response ->
992+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
993+
989994
RestClient restClientWithCookies = this.restClient.mutate()
990995
.defaultCookie("testCookie", "firstValue", "secondValue")
991996
.build();
@@ -1002,8 +1007,9 @@ void cookieOverridesDefaultCookie(ClientHttpRequestFactory requestFactory) {
10021007
@ParameterizedRestClientTest
10031008
void cookiesCanRemoveCookie(ClientHttpRequestFactory requestFactory) {
10041009
startServer(requestFactory);
1005-
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
1006-
.setBody("Hello Spring!"));
1010+
1011+
prepareResponse(response ->
1012+
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
10071013

10081014
this.restClient.get()
10091015
.uri("/greeting")

0 commit comments

Comments
 (0)