Replace WebClient.filter with Builder.filter
This commit replaces the WebClient.filter method with WebClient.Builder.filter. The reason for this change is that filters added via WebClient.filter would be applied in the opposite order of their declaration, due to the compositional nature of the method, combined with the immutable nature of the WebClient. WebClient.Builder.filter does keep the order of the filters, as registered. Furthermore, this commit introduces a WebClient.mutate() method, returning a WebClient.Builder. This method allow to add/remove filters and other defaults from a given WebClient. Issue: SPR-15657 Add WebClient.Builder.addFilter Add Consumer-based headers and cookies methods to builders. Add WebClient.mutate
This commit is contained in:
@@ -48,13 +48,14 @@ import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.reactive.function.BodyExtractor;
|
||||
import org.springframework.web.reactive.function.BodyInserter;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.util.UriBuilder;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
import static org.springframework.test.util.AssertionErrors.*;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.*;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.springframework.test.util.AssertionErrors.assertEquals;
|
||||
import static org.springframework.test.util.AssertionErrors.assertTrue;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toFlux;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link WebTestClient}.
|
||||
@@ -80,12 +81,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||
this.timeout = (timeout != null ? timeout : Duration.ofSeconds(5));
|
||||
}
|
||||
|
||||
private DefaultWebTestClient(DefaultWebTestClient webTestClient, ExchangeFilterFunction filter) {
|
||||
this.webClient = webTestClient.webClient.filter(filter);
|
||||
this.wiretapConnector = webTestClient.wiretapConnector;
|
||||
this.timeout = webTestClient.timeout;
|
||||
}
|
||||
|
||||
|
||||
private Duration getTimeout() {
|
||||
return this.timeout;
|
||||
@@ -134,12 +129,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public WebTestClient filter(ExchangeFilterFunction filter) {
|
||||
return new DefaultWebTestClient(this, filter);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private class DefaultUriSpec<S extends RequestHeadersSpec<?>> implements UriSpec<S> {
|
||||
|
||||
@@ -193,8 +182,8 @@ class DefaultWebTestClient implements WebTestClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec headers(HttpHeaders headers) {
|
||||
this.bodySpec.headers(headers);
|
||||
public RequestBodySpec headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.bodySpec.headers(headersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -229,8 +218,9 @@ class DefaultWebTestClient implements WebTestClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBodySpec cookies(MultiValueMap<String, String> cookies) {
|
||||
this.bodySpec.cookies(cookies);
|
||||
public RequestBodySpec cookies(
|
||||
Consumer<MultiValueMap<String, String>> cookiesConsumer) {
|
||||
this.bodySpec.cookies(cookiesConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,15 @@
|
||||
package org.springframework.test.web.reactive.server;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.client.reactive.ClientHttpConnector;
|
||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.util.UriBuilderFactory;
|
||||
@@ -71,12 +76,37 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebTestClient.Builder defaultHeaders(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.webClientBuilder.defaultHeaders(headersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebTestClient.Builder defaultCookie(String cookieName, String... cookieValues) {
|
||||
this.webClientBuilder.defaultCookie(cookieName, cookieValues);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebTestClient.Builder defaultCookies(
|
||||
Consumer<MultiValueMap<String, String>> cookiesConsumer) {
|
||||
this.webClientBuilder.defaultCookies(cookiesConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebTestClient.Builder filter(ExchangeFilterFunction filter) {
|
||||
this.webClientBuilder.filter(filter);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebTestClient.Builder filters(Consumer<List<ExchangeFilterFunction>> filtersConsumer) {
|
||||
this.webClientBuilder.filters(filtersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebTestClient.Builder exchangeStrategies(ExchangeStrategies strategies) {
|
||||
this.webClientBuilder.exchangeStrategies(strategies);
|
||||
|
||||
@@ -43,7 +43,6 @@ import org.springframework.web.reactive.config.ViewResolverRegistry;
|
||||
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
||||
import org.springframework.web.reactive.function.BodyInserter;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFunction;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.reactive.function.server.HandlerStrategies;
|
||||
@@ -128,15 +127,6 @@ public interface WebTestClient {
|
||||
UriSpec<RequestHeadersSpec<?>> options();
|
||||
|
||||
|
||||
/**
|
||||
* Filter the client with the given {@code ExchangeFilterFunction}.
|
||||
* @param filterFunction the filter to apply to this client
|
||||
* @return the filtered client
|
||||
* @see ExchangeFilterFunction#apply(ExchangeFunction)
|
||||
*/
|
||||
WebTestClient filter(ExchangeFilterFunction filterFunction);
|
||||
|
||||
|
||||
// Static, factory methods
|
||||
|
||||
/**
|
||||
@@ -321,6 +311,17 @@ public interface WebTestClient {
|
||||
*/
|
||||
Builder defaultHeader(String headerName, String... headerValues);
|
||||
|
||||
/**
|
||||
* Manipulate the default headers with the given consumer. The
|
||||
* headers provided to the consumer are "live", so that the consumer can be used to
|
||||
* {@linkplain HttpHeaders#set(String, String) overwrite} existing header values,
|
||||
* {@linkplain HttpHeaders#remove(Object) remove} values, or use any of the other
|
||||
* {@link HttpHeaders} methods.
|
||||
* @param headersConsumer a function that consumes the {@code HttpHeaders}
|
||||
* @return this builder
|
||||
*/
|
||||
Builder defaultHeaders(Consumer<HttpHeaders> headersConsumer);
|
||||
|
||||
/**
|
||||
* Add the given header to all requests that haven't added it.
|
||||
* @param cookieName the cookie name
|
||||
@@ -328,6 +329,32 @@ public interface WebTestClient {
|
||||
*/
|
||||
Builder defaultCookie(String cookieName, String... cookieValues);
|
||||
|
||||
/**
|
||||
* Manipulate the default cookies with the given consumer. The
|
||||
* map provided to the consumer is "live", so that the consumer can be used to
|
||||
* {@linkplain MultiValueMap#set(Object, Object) overwrite} existing header values,
|
||||
* {@linkplain MultiValueMap#remove(Object) remove} values, or use any of the other
|
||||
* {@link MultiValueMap} methods.
|
||||
* @param cookiesConsumer a function that consumes the cookies map
|
||||
* @return this builder
|
||||
*/
|
||||
Builder defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer);
|
||||
|
||||
/**
|
||||
* Add the given filter to the filter chain.
|
||||
* @param filter the filter to be added to the chain
|
||||
*/
|
||||
Builder filter(ExchangeFilterFunction filter);
|
||||
|
||||
/**
|
||||
* Manipulate the filters with the given consumer. The
|
||||
* list provided to the consumer is "live", so that the consumer can be used to remove
|
||||
* filters, change ordering, etc.
|
||||
* @param filtersConsumer a function that consumes the filter list
|
||||
* @return this builder
|
||||
*/
|
||||
Builder filters(Consumer<List<ExchangeFilterFunction>> filtersConsumer);
|
||||
|
||||
/**
|
||||
* Configure the {@link ExchangeStrategies} to use.
|
||||
* <p>By default {@link ExchangeStrategies#withDefaults()} is used.
|
||||
@@ -417,12 +444,15 @@ public interface WebTestClient {
|
||||
S cookie(String name, String value);
|
||||
|
||||
/**
|
||||
* Copy the given cookies into the entity's cookies map.
|
||||
*
|
||||
* @param cookies the existing cookies to copy from
|
||||
* @return the same instance
|
||||
* Manipulate this request's cookies with the given consumer. The
|
||||
* map provided to the consumer is "live", so that the consumer can be used to
|
||||
* {@linkplain MultiValueMap#set(Object, Object) overwrite} existing header values,
|
||||
* {@linkplain MultiValueMap#remove(Object) remove} values, or use any of the other
|
||||
* {@link MultiValueMap} methods.
|
||||
* @param cookiesConsumer a function that consumes the cookies map
|
||||
* @return this builder
|
||||
*/
|
||||
S cookies(MultiValueMap<String, String> cookies);
|
||||
S cookies(Consumer<MultiValueMap<String, String>> cookiesConsumer);
|
||||
|
||||
/**
|
||||
* Set the value of the {@code If-Modified-Since} header.
|
||||
@@ -449,11 +479,15 @@ public interface WebTestClient {
|
||||
S header(String headerName, String... headerValues);
|
||||
|
||||
/**
|
||||
* Copy the given headers into the entity's headers map.
|
||||
* @param headers the existing headers to copy from
|
||||
* @return the same instance
|
||||
* Manipulate the request's headers with the given consumer. The
|
||||
* headers provided to the consumer are "live", so that the consumer can be used to
|
||||
* {@linkplain HttpHeaders#set(String, String) overwrite} existing header values,
|
||||
* {@linkplain HttpHeaders#remove(Object) remove} values, or use any of the other
|
||||
* {@link HttpHeaders} methods.
|
||||
* @param headersConsumer a function that consumes the {@code HttpHeaders}
|
||||
* @return this builder
|
||||
*/
|
||||
S headers(HttpHeaders headers);
|
||||
S headers(Consumer<HttpHeaders> headersConsumer);
|
||||
|
||||
/**
|
||||
* Perform the exchange without a request body.
|
||||
|
||||
Reference in New Issue
Block a user