Skip to content

Commit 3e1b3c3

Browse files
geminiKimbclozel
authored andcommitted
Avoid duplicate Accept header values in RestTemplate
Prior to this commit, the various `HttpMessageConverter` instances configured for a given `RestTemplate` instance could all contribute `MediaType` values to the "Accept:" request header. This could lead to duplicate media types in that request header, cluttering for the HTTP request for no reason. This commit ensures that only distinct values are added to the request. Issue: SPR-16690 Closes gh-22320 Closes gh-21231
1 parent 9865b0c commit 3e1b3c3

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020
import java.lang.reflect.Type;
2121
import java.net.URI;
2222
import java.util.ArrayList;
23+
import java.util.LinkedHashSet;
2324
import java.util.LinkedList;
2425
import java.util.List;
2526
import java.util.Map;
@@ -767,7 +768,7 @@ public void doWithRequest(ClientHttpRequest request) throws IOException {
767768
if (this.responseType instanceof Class) {
768769
responseClass = (Class<?>) this.responseType;
769770
}
770-
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
771+
Set<MediaType> allSupportedMediaTypes = new LinkedHashSet<MediaType>();
771772
for (HttpMessageConverter<?> converter : getMessageConverters()) {
772773
if (responseClass != null) {
773774
if (converter.canRead(responseClass, null)) {
@@ -782,11 +783,12 @@ else if (converter instanceof GenericHttpMessageConverter) {
782783
}
783784
}
784785
if (!allSupportedMediaTypes.isEmpty()) {
785-
MediaType.sortBySpecificity(allSupportedMediaTypes);
786+
List<MediaType> result = new ArrayList<MediaType>(allSupportedMediaTypes);
787+
MediaType.sortBySpecificity(result);
786788
if (logger.isDebugEnabled()) {
787789
logger.debug("Setting request Accept header to " + allSupportedMediaTypes);
788790
}
789-
request.getHeaders().setAccept(allSupportedMediaTypes);
791+
request.getHeaders().setAccept(result);
790792
}
791793
}
792794
}

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@
1919
import java.io.ByteArrayInputStream;
2020
import java.io.IOException;
2121
import java.net.URI;
22+
import java.nio.charset.StandardCharsets;
23+
import java.util.Arrays;
2224
import java.util.Collections;
2325
import java.util.EnumSet;
2426
import java.util.HashMap;
@@ -43,6 +45,8 @@
4345
import org.springframework.http.client.ClientHttpResponse;
4446
import org.springframework.http.converter.GenericHttpMessageConverter;
4547
import org.springframework.http.converter.HttpMessageConverter;
48+
import org.springframework.http.converter.StringHttpMessageConverter;
49+
import org.springframework.util.StringUtils;
4650
import org.springframework.web.util.DefaultUriTemplateHandler;
4751

4852
import static org.hamcrest.MatcherAssert.assertThat;
@@ -878,4 +882,24 @@ public void requestInterceptorCanAddExistingHeaderValueWithBody() throws Excepti
878882
verify(response).close();
879883
}
880884

885+
@Test
886+
public void acceptHeaderValueShouldBeNotDuplicated() throws Exception {
887+
final StringHttpMessageConverter utf8HttpMessageConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
888+
final StringHttpMessageConverter iso88591HttpMessageConverter = new StringHttpMessageConverter(StandardCharsets.ISO_8859_1);
889+
890+
final RestTemplate multipleEncodingTemplate = new RestTemplate(Arrays.asList(utf8HttpMessageConverter, iso88591HttpMessageConverter));
891+
multipleEncodingTemplate.setRequestFactory(requestFactory);
892+
given(requestFactory.createRequest(new URI("http://example.com"), GET)).willReturn(request);
893+
894+
final HttpHeaders requestHeaders = new HttpHeaders();
895+
given(request.getHeaders()).willReturn(requestHeaders);
896+
given(request.execute()).willReturn(response);
897+
898+
final HttpHeaders responseHeaders = new HttpHeaders();
899+
given(response.getHeaders()).willReturn(responseHeaders);
900+
901+
multipleEncodingTemplate.getForObject("http://example.com", String.class);
902+
assertEquals("text/plain, */*", StringUtils.collectionToDelimitedString(request.getHeaders().get("accept"), ","));
903+
}
904+
881905
}

0 commit comments

Comments
 (0)