diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index c88dfce3d8..21d370a7b6 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -47,6 +47,7 @@ import org.springframework.web.reactive.config.PathMatchConfigurer; 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.BodyInserters; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; @@ -60,22 +61,27 @@ import org.springframework.web.util.UriBuilder; import org.springframework.web.util.UriBuilderFactory; /** - * Non-blocking, reactive client for testing web servers. It uses the reactive - * {@link WebClient} internally to perform requests and provides a fluent API - * to verify responses. + * Client for testing web servers that uses {@link WebClient} internally to + * perform requests while also providing a fluent API to verify responses. + * This client can connect to any server over HTTP, or to a WebFlux application + * via mock request and response objects. * - *
{@code WebTestClient} can connect to any server over an HTTP connection. - * It can also bind directly to WebFlux applications using mock request and - * response objects, without the need for an HTTP server. + *
Use one of the bindToXxx methods to create an instance. For example: + *
See the static {@code bindToXxx} entry points for creating an instance. - * - *
Warning: {@code WebTestClient} is not usable yet in Kotlin due to a - * type inference issue which is - * expected to be fixed as of Kotlin 1.3. You can watch - * SPR-16057 for up-to-date information. - * Meanwhile, the proposed alternative is to use directly {@link WebClient} with its Reactor - * and Spring Kotlin extensions to perform integration tests on an embedded WebFlux server. + *
Warning: {@code WebTestClient} is not usable yet in + * Kotlin due to a type inference issue + * which is expected to be fixed as of Kotlin 1.3. You can watch + * gh-20606 + * for up-to-date information. Meanwhile, the proposed alternative is to use + * directly {@link WebClient} with its Reactor and Spring Kotlin extensions to + * perform integration tests on an embedded WebFlux server. * * @author Rossen Stoyanchev * @since 5.0 @@ -626,93 +632,81 @@ public interface WebTestClient { RequestBodySpec contentType(MediaType contentType); /** - * Set the body of the request to the given {@code Object} and perform the request. - *
This method is a convenient shortcut for: - *
- * .body(BodyInserters.fromObject(object)) - *- *
The body can be a
- * {@link org.springframework.util.MultiValueMap MultiValueMap} to create
- * a multipart request. The values in the {@code MultiValueMap} can be
- * any Object representing the body of the part, or an
- * {@link org.springframework.http.HttpEntity HttpEntity} representing a
- * part with body and headers. The {@code MultiValueMap} can be built
- * conveniently using
- * @param body the {@code Object} to write to the request
- * @return spec for decoding the response
+ * Set the body to the given {@code Object} value. This method invokes the
+ * {@link WebClient.RequestBodySpec#bodyValue(Object) bodyValue} method
+ * on the underlying {@code WebClient}.
+ * @param body the value to write to the request body
+ * @return spec for further declaration of the request
* @since 5.2
*/
RequestHeadersSpec> bodyValue(Object body);
/**
- * Set the body of the request to the given asynchronous {@code Publisher}.
+ * Set the body from the given {@code Publisher}. Shortcut for
+ * {@link #body(BodyInserter)} with a
+ * {@linkplain BodyInserters#fromPublisher Publisher inserter}.
* @param publisher the request body data
* @param elementClass the class of elements contained in the publisher
* @param This method is a convenient shortcut for:
- * The body can be a
- * {@link org.springframework.util.MultiValueMap MultiValueMap} to create
- * a multipart request. The values in the {@code MultiValueMap} can be
- * any Object representing the body of the part, or an
- * {@link org.springframework.http.HttpEntity HttpEntity} representing a
- * part with body and headers. The {@code MultiValueMap} can be built
- * conveniently using
- * @param body the {@code Object} to write to the request
- * @return spec for decoding the response
- * @throws IllegalArgumentException if {@code body} is a {@link Publisher} or an
- * instance of a type supported by {@link ReactiveAdapterRegistry#getSharedInstance()},
- * for which {@link #body(Publisher, Class)} or {@link #body(Object, Class)} should be used.
+ * Shortcut for {@link #body(BodyInserter)} with an
+ * {@linkplain BodyInserters#fromObject Object inserter}.
+ * As of 5.2 this method delegates to {@link #bodyValue(Object)}.
* @deprecated as of Spring Framework 5.2 in favor of {@link #bodyValue(Object)}
*/
@Deprecated
diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java
index 6b64ab84c7..0401b4be81 100644
--- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java
+++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java
@@ -61,8 +61,6 @@ import org.springframework.web.util.UriBuilderFactory;
* For multipart requests, provide a
- * {@link org.springframework.util.MultiValueMap MultiValueMap}. The
- * values in the {@code MultiValueMap} can be any Object representing
- * the body of the part, or an
- * {@link org.springframework.http.HttpEntity HttpEntity} representing
- * a part with body and headers. The {@code MultiValueMap} can be built
+ * For multipart requests consider providing
+ * {@link org.springframework.util.MultiValueMap MultiValueMap} prepared
* with {@link org.springframework.http.client.MultipartBodyBuilder
* MultipartBodyBuilder}.
- * @param body the {@code Object} to write to the request
+ * @param body the value to write to the request body
* @return this builder
- * @throws IllegalArgumentException if {@code body} is a {@link Publisher} or an
- * instance of a type supported by {@link ReactiveAdapterRegistry#getSharedInstance()},
- * for which {@link #body(Publisher, Class)} or {@link #body(Object, Class)} should be used.
+ * @throws IllegalArgumentException if {@code body} is a
+ * {@link Publisher} or producer known to {@link ReactiveAdapterRegistry}
* @since 5.2
*/
RequestHeadersSpec> bodyValue(Object body);
/**
- * A shortcut for {@link #body(BodyInserter)} with a
+ * Shortcut for {@link #body(BodyInserter)} with a
* {@linkplain BodyInserters#fromPublisher Publisher inserter}.
* For example:
* the type of the {@code Publisher}
* @return this builder
@@ -572,11 +565,10 @@ public interface WebClient {
the type of the {@code Publisher}
* @return this builder
@@ -585,36 +577,22 @@ public interface WebClient {
ParameterizedTypeReference For multipart requests, provide a
- * {@link org.springframework.util.MultiValueMap MultiValueMap}. The
- * values in the {@code MultiValueMap} can be any Object representing
- * the body of the part, or an
- * {@link org.springframework.http.HttpEntity HttpEntity} representing
- * a part with body and headers. The {@code MultiValueMap} can be built
- * with {@link org.springframework.http.client.MultipartBodyBuilder
- * MultipartBodyBuilder}.
- * @param body the {@code Object} to write to the request
- * @return this builder
- * @throws IllegalArgumentException if {@code body} is a {@link Publisher} or an
- * instance of a type supported by {@link ReactiveAdapterRegistry#getSharedInstance()},
- * for which {@link #body(Publisher, Class)} or {@link #body(Object, Class)} should be used.
+ * As of 5.2 this method delegates to {@link #bodyValue(Object)}.
* @deprecated as of Spring Framework 5.2 in favor of {@link #bodyValue(Object)}
*/
@Deprecated
diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java
index 39f57133cd..fd93bf3137 100644
--- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java
+++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java
@@ -41,6 +41,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
+import org.springframework.http.ReactiveHttpOutputMessage;
import org.springframework.http.ResponseCookie;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.server.reactive.AbstractServerHttpResponse;
@@ -218,63 +219,37 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
public Mono the type of the {@code Publisher}
* @return the built response
@@ -423,11 +422,11 @@ public interface ServerResponse {
the type of the {@code Publisher}
* @return the built response
@@ -436,26 +435,22 @@ public interface ServerResponse {
ParameterizedTypeReference the type of the {@code Publisher}
- * @return spec for decoding the response
+ * @return spec for further declaration of the request
*/
the type of the {@code Publisher}
- * @return spec for decoding the response
+ * @return spec for further declaration of the request
* @since 5.2
*/
-
- * .body(BodyInserters.fromObject(object))
- *
- *
*
*
* @author Rossen Stoyanchev
@@ -519,7 +517,7 @@ public interface WebClient {
RequestBodySpec contentType(MediaType contentType);
/**
- * A shortcut for {@link #body(BodyInserter)} with an
+ * Shortcut for {@link #body(BodyInserter)} with an
* {@linkplain BodyInserters#fromObject Object inserter}.
* For example:
*
@@ -532,25 +530,20 @@ public interface WebClient {
* .retrieve()
* .bodyToMono(Void.class);
*
- *
@@ -564,7 +557,7 @@ public interface WebClient {
* .bodyToMono(Void.class);
*
* @param publisher the {@code Publisher} to write to the request
- * @param elementClass the class of elements contained in the publisher
+ * @param elementClass the type of elements published
* @param
- * Single<Person> personSingle = ... ;
- *
- * Mono<Void> result = client.post()
- * .uri("/persons/{id}", id)
- * .contentType(MediaType.APPLICATION_JSON)
- * .body(personSingle, Person.class)
- * .retrieve()
- * .bodyToMono(Void.class);
- *
- * @param producer the producer to write to the request. This must be a
- * {@link Publisher} or another producer adaptable to a
- * {@code Publisher} via {@link ReactiveAdapterRegistry}
- * @param elementClass the class of elements contained in the producer
+ * Variant of {@link #body(Publisher, Class)} that allows using any
+ * producer that can be resolved to {@link Publisher} via
+ * {@link ReactiveAdapterRegistry}.
+ * @param producer the producer to write to the request
+ * @param elementClass the type of elements produced
* @return this builder
* @since 5.2
*/
RequestHeadersSpec> body(Object producer, Class> elementClass);
/**
- * A variant of {@link #body(Object, Class)} that allows providing
- * element type information that includes generics via a
- * {@link ParameterizedTypeReference}.
- * @param producer the producer to write to the request. This must be a
- * {@link Publisher} or another producer adaptable to a
- * {@code Publisher} via {@link ReactiveAdapterRegistry}
- * @param elementTypeRef the type reference of elements contained in the producer
+ * Variant of {@link #body(Publisher, ParameterizedTypeReference)} that
+ * allows using any producer that can be resolved to {@link Publisher}
+ * via {@link ReactiveAdapterRegistry}.
+ * @param producer the producer to write to the request
+ * @param elementTypeRef the type of elements produced
* @return this builder
* @since 5.2
*/
@@ -622,8 +600,7 @@ public interface WebClient {
/**
* Set the body of the request using the given body inserter.
- * {@link BodyInserters} provides access to built-in implementations of
- * {@link BodyInserter}.
+ * See {@link BodyInserters} for built-in {@link BodyInserter} implementations.
* @param inserter the body inserter to use for the request body
* @return this builder
* @see org.springframework.web.reactive.function.BodyInserters
@@ -631,32 +608,9 @@ public interface WebClient {
RequestHeadersSpec> body(BodyInserter, ? super ClientHttpRequest> inserter);
/**
- * A shortcut for {@link #body(BodyInserter)} with an
+ * Shortcut for {@link #body(BodyInserter)} with an
* {@linkplain BodyInserters#fromObject Object inserter}.
- * For example:
- *
- * Person person = ... ;
- *
- * Mono<Void> result = client.post()
- * .uri("/persons/{id}", id)
- * .contentType(MediaType.APPLICATION_JSON)
- * .syncBody(person)
- * .retrieve()
- * .bodyToMono(Void.class);
- *
- *