Add defaultRequest option to WebClient.Builder
Issue: SPR-16873
This commit is contained in:
@@ -79,17 +79,21 @@ class DefaultWebClient implements WebClient {
|
||||
@Nullable
|
||||
private final MultiValueMap<String, String> defaultCookies;
|
||||
|
||||
@Nullable
|
||||
private final Consumer<RequestHeadersSpec<?>> defaultRequest;
|
||||
|
||||
private final DefaultWebClientBuilder builder;
|
||||
|
||||
|
||||
DefaultWebClient(ExchangeFunction exchangeFunction, @Nullable UriBuilderFactory factory,
|
||||
@Nullable HttpHeaders defaultHeaders, @Nullable MultiValueMap<String, String> defaultCookies,
|
||||
DefaultWebClientBuilder builder) {
|
||||
@Nullable Consumer<RequestHeadersSpec<?>> defaultRequest, DefaultWebClientBuilder builder) {
|
||||
|
||||
this.exchangeFunction = exchangeFunction;
|
||||
this.uriBuilderFactory = (factory != null ? factory : new DefaultUriBuilderFactory());
|
||||
this.defaultHeaders = defaultHeaders;
|
||||
this.defaultCookies = defaultCookies;
|
||||
this.defaultRequest = defaultRequest;
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
@@ -317,6 +321,9 @@ class DefaultWebClient implements WebClient {
|
||||
}
|
||||
|
||||
private ClientRequest.Builder initRequestBuilder() {
|
||||
if (defaultRequest != null) {
|
||||
defaultRequest.accept(this);
|
||||
}
|
||||
URI uri = (this.uri != null ? this.uri : uriBuilderFactory.expand(""));
|
||||
return ClientRequest.create(this.httpMethod, uri)
|
||||
.headers(headers -> headers.addAll(initHeaders()))
|
||||
|
||||
@@ -57,6 +57,9 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
|
||||
@Nullable
|
||||
private MultiValueMap<String, String> defaultCookies;
|
||||
|
||||
@Nullable
|
||||
private Consumer<WebClient.RequestHeadersSpec<?>> defaultRequest;
|
||||
|
||||
@Nullable
|
||||
private List<ExchangeFilterFunction> filters;
|
||||
|
||||
@@ -89,6 +92,7 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
|
||||
}
|
||||
this.defaultCookies =
|
||||
other.defaultCookies != null ? new LinkedMultiValueMap<>(other.defaultCookies) : null;
|
||||
this.defaultRequest = other.defaultRequest;
|
||||
this.filters = other.filters != null ? new ArrayList<>(other.filters) : null;
|
||||
this.connector = other.connector;
|
||||
this.exchangeFunction = other.exchangeFunction;
|
||||
@@ -152,6 +156,13 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
|
||||
return this.defaultCookies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebClient.Builder defaultRequest(Consumer<WebClient.RequestHeadersSpec<?>> defaultRequest) {
|
||||
this.defaultRequest = this.defaultRequest != null ?
|
||||
this.defaultRequest.andThen(defaultRequest) : defaultRequest;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebClient.Builder clientConnector(ClientHttpConnector connector) {
|
||||
this.connector = connector;
|
||||
@@ -201,7 +212,7 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
|
||||
return new DefaultWebClient(filteredExchange, initUriBuilderFactory(),
|
||||
this.defaultHeaders != null ? unmodifiableCopy(this.defaultHeaders) : null,
|
||||
this.defaultCookies != null ? unmodifiableCopy(this.defaultCookies) : null,
|
||||
new DefaultWebClientBuilder(this));
|
||||
this.defaultRequest, new DefaultWebClientBuilder(this));
|
||||
}
|
||||
|
||||
private ExchangeFunction initExchangeFunction() {
|
||||
|
||||
@@ -226,7 +226,7 @@ public interface WebClient {
|
||||
Builder uriBuilderFactory(UriBuilderFactory uriBuilderFactory);
|
||||
|
||||
/**
|
||||
* A global option to specify a header to be added to every request,
|
||||
* Global option to specify a header to be added to every request,
|
||||
* if the request does not already contain such a header.
|
||||
* @param header the header name
|
||||
* @param values the header values
|
||||
@@ -241,7 +241,7 @@ public interface WebClient {
|
||||
Builder defaultHeaders(Consumer<HttpHeaders> headersConsumer);
|
||||
|
||||
/**
|
||||
* A global option to specify a cookie to be added to every request,
|
||||
* Global option to specify a cookie to be added to every request,
|
||||
* if the request does not already contain such a cookie.
|
||||
* @param cookie the cookie name
|
||||
* @param values the cookie values
|
||||
@@ -255,6 +255,14 @@ public interface WebClient {
|
||||
*/
|
||||
Builder defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer);
|
||||
|
||||
/**
|
||||
* Provide a consumer to modify every request being built just before the
|
||||
* call to {@link RequestHeadersSpec#exchange() exchange()}.
|
||||
* @param defaultRequest the consumer to use for modifying requests
|
||||
* @since 5.1
|
||||
*/
|
||||
Builder defaultRequest(Consumer<RequestHeadersSpec<?>> defaultRequest);
|
||||
|
||||
/**
|
||||
* Add the given filter to the filter chain.
|
||||
* @param filter the filter to be added to the chain
|
||||
|
||||
@@ -30,6 +30,8 @@ import org.mockito.MockitoAnnotations;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.NamedInheritableThreadLocal;
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
@@ -138,6 +140,33 @@ public class DefaultWebClientTests {
|
||||
verifyNoMoreInteractions(this.exchangeFunction);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultRequest() {
|
||||
|
||||
ThreadLocal<String> context = new NamedThreadLocal<>("foo");
|
||||
|
||||
Map<String, Object> actual = new HashMap<>();
|
||||
ExchangeFilterFunction filter = (request, next) -> {
|
||||
actual.putAll(request.attributes());
|
||||
return next.exchange(request);
|
||||
};
|
||||
|
||||
WebClient client = this.builder
|
||||
.defaultRequest(spec -> spec.attribute("foo", context.get()))
|
||||
.filter(filter)
|
||||
.build();
|
||||
|
||||
try {
|
||||
context.set("bar");
|
||||
client.get().uri("/path").attribute("foo", "bar").exchange();
|
||||
}
|
||||
finally {
|
||||
context.remove();
|
||||
}
|
||||
|
||||
assertEquals("bar", actual.get("foo"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void bodyObjectPublisher() {
|
||||
Mono<Void> mono = Mono.empty();
|
||||
|
||||
Reference in New Issue
Block a user