Add ClientRequest attributes

This commit introduces client-side request attributes, similar to those
found on the server-side. The attributes can be used, for instance, for
passing on request-specific information to a globally registered
ExchangeFilterFunction.

The client request builder, as well as WebClient.RequestHeadersSpec and
WebTestClient.RequestHeaderSpec, add methods for adding a single
attribute, as well as manipulating the entire attributes map.

The client request itself adds a accessor for the (immutable) attributes
map.

This commit also introduces a new variant of the basic authentication
filter in ExchangeFilterFunctions. This variant takes the username and
password from well-known attributes.

Issue: SPR-15691
This commit is contained in:
Arjen Poutsma
2017-07-05 14:37:23 +02:00
parent eb928ce456
commit 74b4c02881
9 changed files with 212 additions and 9 deletions

View File

@@ -51,9 +51,11 @@ import org.springframework.web.reactive.function.client.ClientResponse;
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}.
@@ -196,6 +198,19 @@ class DefaultWebTestClient implements WebTestClient {
return this;
}
@Override
public RequestBodySpec attribute(String name, Object value) {
this.bodySpec.attribute(name, value);
return this;
}
@Override
public RequestBodySpec attributes(
Consumer<Map<String, Object>> attributesConsumer) {
this.bodySpec.attributes(attributesConsumer);
return this;
}
@Override
public RequestBodySpec accept(MediaType... acceptableMediaTypes) {
this.bodySpec.accept(acceptableMediaTypes);

View File

@@ -508,6 +508,23 @@ public interface WebTestClient {
*/
S headers(Consumer<HttpHeaders> headersConsumer);
/**
* Set the attribute with the given name to the given value.
* @param name the name of the attribute to add
* @param value the value of the attribute to add
* @return this builder
*/
S attribute(String name, Object value);
/**
* Manipulate the request attributes with the given consumer. The attributes provided to
* the consumer are "live", so that the consumer can be used to inspect attributes,
* remove attributes, or use any of the other map-provided methods.
* @param attributesConsumer a function that consumes the attributes
* @return this builder
*/
S attributes(Consumer<Map<String, Object>> attributesConsumer);
/**
* Perform the exchange without a request body.
* @return spec for decoding the response