Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public class RestTemplateBuilder {

private final BasicAuthentication basicAuthentication;

private final Map<String, String> defaultHeaders;
private final Map<String, List<String>> defaultHeaders;

private final Set<RestTemplateCustomizer> customizers;

Expand Down Expand Up @@ -122,7 +122,7 @@ private RestTemplateBuilder(RequestFactoryCustomizer requestFactoryCustomizer, b
String rootUri, Set<HttpMessageConverter<?>> messageConverters,
Set<ClientHttpRequestInterceptor> interceptors, Supplier<ClientHttpRequestFactory> requestFactorySupplier,
UriTemplateHandler uriTemplateHandler, ResponseErrorHandler errorHandler,
BasicAuthentication basicAuthentication, Map<String, String> defaultHeaders,
BasicAuthentication basicAuthentication, Map<String, List<String>> defaultHeaders,
Set<RestTemplateCustomizer> customizers, Set<RestTemplateRequestCustomizer<?>> requestCustomizers) {
this.requestFactoryCustomizer = requestFactoryCustomizer;
this.detectRequestFactory = detectRequestFactory;
Expand Down Expand Up @@ -395,15 +395,17 @@ this.errorHandler, new BasicAuthentication(username, password, charset), this.de
* Add a default header that will be set if not already present on the outgoing
* {@link HttpClientRequest}.
* @param name the name of the header
* @param value the header value
* @param values the header values
* @return a new builder instance
* @since 2.2.0
*/
public RestTemplateBuilder defaultHeader(String name, String value) {
public RestTemplateBuilder defaultHeader(String name, String... values) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(values, "Values must not be null");
return new RestTemplateBuilder(this.requestFactoryCustomizer, this.detectRequestFactory, this.rootUri,
this.messageConverters, this.interceptors, this.requestFactory, this.uriTemplateHandler,
this.errorHandler, this.basicAuthentication, append(this.defaultHeaders, name, value), this.customizers,
this.requestCustomizers);
this.errorHandler, this.basicAuthentication, append(this.defaultHeaders, name, values),
this.customizers, this.requestCustomizers);
}

/**
Expand Down Expand Up @@ -683,6 +685,10 @@ private <T> Set<T> setOf(Collection<? extends T> collection) {
return Collections.unmodifiableSet(new LinkedHashSet<>(collection));
}

private static <T> List<T> listOf(T[] items) {
return Collections.unmodifiableList(new ArrayList<>(Arrays.asList(items)));
}

private static <T> Set<T> append(Collection<? extends T> collection, Collection<? extends T> additions) {
Set<T> result = new LinkedHashSet<>((collection != null) ? collection : Collections.emptySet());
if (additions != null) {
Expand All @@ -691,9 +697,11 @@ private static <T> Set<T> append(Collection<? extends T> collection, Collection<
return Collections.unmodifiableSet(result);
}

private static <K, V> Map<K, V> append(Map<K, V> map, K key, V value) {
Map<K, V> result = new LinkedHashMap<>((map != null) ? map : Collections.emptyMap());
result.put(key, value);
private static <K, V> Map<K, List<V>> append(Map<K, List<V>> map, K key, V[] values) {
Map<K, List<V>> result = new LinkedHashMap<>((map != null) ? map : Collections.emptyMap());
if (values != null) {
result.put(key, listOf(values));
}
return Collections.unmodifiableMap(result);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Set;

Expand All @@ -39,12 +40,12 @@ class RestTemplateBuilderClientHttpRequestFactoryWrapper extends AbstractClientH

private final BasicAuthentication basicAuthentication;

private final Map<String, String> defaultHeaders;
private final Map<String, List<String>> defaultHeaders;

private final Set<RestTemplateRequestCustomizer<?>> requestCustomizers;

RestTemplateBuilderClientHttpRequestFactoryWrapper(ClientHttpRequestFactory requestFactory,
BasicAuthentication basicAuthentication, Map<String, String> defaultHeaders,
BasicAuthentication basicAuthentication, Map<String, List<String>> defaultHeaders,
Set<RestTemplateRequestCustomizer<?>> requestCustomizers) {
super(requestFactory);
this.basicAuthentication = basicAuthentication;
Expand All @@ -61,7 +62,7 @@ protected ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod, Client
if (this.basicAuthentication != null) {
this.basicAuthentication.applyTo(headers);
}
this.defaultHeaders.forEach(headers::addIfAbsent);
this.defaultHeaders.forEach(headers::putIfAbsent);
LambdaSafe.callbacks(RestTemplateRequestCustomizer.class, this.requestCustomizers, request)
.invoke((customizer) -> customizer.customize(request));
return request;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

Expand Down Expand Up @@ -80,16 +82,16 @@ void createRequestWhenHasBasicAuthAndExistingAuthHeaderDoesNotAddHeader() throws
@Test
void createRequestWhenHasDefaultHeadersAddsMissing() throws IOException {
this.headers.add("one", "existing");
Map<String, String> defaultHeaders = new LinkedHashMap<>();
defaultHeaders.put("one", "1");
defaultHeaders.put("two", "2");
defaultHeaders.put("three", "3");
Map<String, List<String>> defaultHeaders = new LinkedHashMap<>();
defaultHeaders.put("one", Collections.singletonList("1"));
defaultHeaders.put("two", Arrays.asList("2", "3"));
defaultHeaders.put("three", Collections.singletonList("4"));
this.requestFactory = new RestTemplateBuilderClientHttpRequestFactoryWrapper(this.requestFactory, null,
defaultHeaders, Collections.emptySet());
ClientHttpRequest request = createRequest();
assertThat(request.getHeaders().get("one")).containsExactly("existing");
assertThat(request.getHeaders().get("two")).containsExactly("2");
assertThat(request.getHeaders().get("three")).containsExactly("3");
assertThat(request.getHeaders().get("two")).containsExactly("2", "3");
assertThat(request.getHeaders().get("three")).containsExactly("4");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.function.Supplier;
Expand All @@ -33,6 +34,7 @@

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
Expand Down Expand Up @@ -321,6 +323,16 @@ void defaultHeaderAddsHeader() throws IOException {
assertThat(request.getHeaders()).contains(entry("spring", Collections.singletonList("boot")));
}

@Test
void defaultHeaderAddsHeaderValues() throws IOException {
String name = HttpHeaders.ACCEPT;
String[] values = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE };
RestTemplate template = this.builder.defaultHeader(name, values).build();
ClientHttpRequestFactory requestFactory = template.getRequestFactory();
ClientHttpRequest request = requestFactory.createRequest(URI.create("http://localhost"), HttpMethod.GET);
assertThat(request.getHeaders()).contains(entry(name, Arrays.asList(values)));
}

@Test
void requestCustomizersAddsCustomizers() throws IOException {
RestTemplate template = this.builder
Expand Down