Add body methods with Object parameter to WebFlux
The commit deprecates syncBody(Object) in favor of body(Object) which has the same behavior in ServerResponse, WebClient and WebTestClient. It also adds body(Object, Class) and body(Object, ParameterizedTypeReference) methods in order to support any reactive type that can be adapted to a Publisher via ReactiveAdapterRegistry. Related BodyInserters#fromProducer methods are provided as well. Shadowed Kotlin body<T>() extensions are deprecated in favor of bodyWithType<T>() ones, including dedicated Publisher<T> and Flow<T> variants. Coroutines extensions are adapted as well, and body(Object) can now be used with suspending functions. Closes gh-23212
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -261,8 +261,20 @@ class DefaultWebTestClient implements WebTestClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestHeadersSpec<?> body(BodyInserter<?, ? super ClientHttpRequest> inserter) {
|
||||
this.bodySpec.body(inserter);
|
||||
public RequestHeadersSpec<?> body(Object body) {
|
||||
this.bodySpec.body(body);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestHeadersSpec<?> body(Object producer, Class<?> elementClass) {
|
||||
this.bodySpec.body(producer, elementClass);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestHeadersSpec<?> body(Object producer, ParameterizedTypeReference<?> elementType) {
|
||||
this.bodySpec.body(producer, elementType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -273,11 +285,23 @@ class DefaultWebTestClient implements WebTestClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestHeadersSpec<?> syncBody(Object body) {
|
||||
this.bodySpec.syncBody(body);
|
||||
public <T, S extends Publisher<T>> RequestHeadersSpec<?> body(S publisher, ParameterizedTypeReference<T> elementType) {
|
||||
this.bodySpec.body(publisher, elementType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestHeadersSpec<?> body(BodyInserter<?, ? super ClientHttpRequest> inserter) {
|
||||
this.bodySpec.body(inserter);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public RequestHeadersSpec<?> syncBody(Object body) {
|
||||
return body(body);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseSpec exchange() {
|
||||
ClientResponse clientResponse = this.bodySpec.exchange().block(getTimeout());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,6 +30,7 @@ import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.ReactiveAdapterRegistry;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
@@ -625,26 +626,7 @@ public interface WebTestClient {
|
||||
RequestBodySpec contentType(MediaType contentType);
|
||||
|
||||
/**
|
||||
* Set the body of the request to the given {@code BodyInserter}.
|
||||
* @param inserter the inserter
|
||||
* @return spec for decoding the response
|
||||
* @see org.springframework.web.reactive.function.BodyInserters
|
||||
*/
|
||||
RequestHeadersSpec<?> body(BodyInserter<?, ? super ClientHttpRequest> inserter);
|
||||
|
||||
/**
|
||||
* Set the body of the request to the given asynchronous {@code Publisher}.
|
||||
* @param publisher the request body data
|
||||
* @param elementClass the class of elements contained in the publisher
|
||||
* @param <T> the type of the elements contained in the publisher
|
||||
* @param <S> the type of the {@code Publisher}
|
||||
* @return spec for decoding the response
|
||||
*/
|
||||
<T, S extends Publisher<T>> RequestHeadersSpec<?> body(S publisher, Class<T> elementClass);
|
||||
|
||||
/**
|
||||
* Set the body of the request to the given synchronous {@code Object} and
|
||||
* perform the request.
|
||||
* Set the body of the request to the given {@code Object} and perform the request.
|
||||
* <p>This method is a convenient shortcut for:
|
||||
* <pre class="code">
|
||||
* .body(BodyInserters.fromObject(object))
|
||||
@@ -657,8 +639,83 @@ public interface WebTestClient {
|
||||
* part with body and headers. The {@code MultiValueMap} can be built
|
||||
* conveniently using
|
||||
* @param body the {@code Object} to write to the request
|
||||
* @return a {@code Mono} with the response
|
||||
* @return spec for decoding the response
|
||||
* @since 5.2
|
||||
*/
|
||||
RequestHeadersSpec<?> body(Object body);
|
||||
|
||||
/**
|
||||
* Set the body of the request to the given producer.
|
||||
* @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
|
||||
* @return spec for decoding the response
|
||||
* @since 5.2
|
||||
*/
|
||||
RequestHeadersSpec<?> body(Object producer, Class<?> elementClass);
|
||||
|
||||
/**
|
||||
* Set the body of the request to the given producer.
|
||||
* @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 elementType the type reference of elements contained in the producer
|
||||
* @return spec for decoding the response
|
||||
* @since 5.2
|
||||
*/
|
||||
RequestHeadersSpec<?> body(Object producer, ParameterizedTypeReference<?> elementType);
|
||||
|
||||
/**
|
||||
* Set the body of the request to the given asynchronous {@code Publisher}.
|
||||
* @param publisher the request body data
|
||||
* @param elementClass the class of elements contained in the publisher
|
||||
* @param <T> the type of the elements contained in the publisher
|
||||
* @param <S> the type of the {@code Publisher}
|
||||
* @return spec for decoding the response
|
||||
*/
|
||||
<T, S extends Publisher<T>> RequestHeadersSpec<?> body(S publisher, Class<T> elementClass);
|
||||
|
||||
/**
|
||||
* Set the body of the request to the given asynchronous {@code Publisher}.
|
||||
* @param publisher the request body data
|
||||
* @param elementType the type reference of elements contained in the publisher
|
||||
* @param <T> the type of the elements contained in the publisher
|
||||
* @param <S> the type of the {@code Publisher}
|
||||
* @return spec for decoding the response
|
||||
* @since 5.2
|
||||
*/
|
||||
<T, S extends Publisher<T>> RequestHeadersSpec<?> body(S publisher, ParameterizedTypeReference<T> elementType);
|
||||
|
||||
/**
|
||||
* Set the body of the request to the given {@code BodyInserter}.
|
||||
* @param inserter the inserter
|
||||
* @return spec for decoding the response
|
||||
* @see org.springframework.web.reactive.function.BodyInserters
|
||||
*/
|
||||
RequestHeadersSpec<?> body(BodyInserter<?, ? super ClientHttpRequest> inserter);
|
||||
|
||||
/**
|
||||
* Set the body of the request to the given {@code Object} and perform the request.
|
||||
* <p>This method is a convenient shortcut for:
|
||||
* <pre class="code">
|
||||
* .body(BodyInserters.fromObject(object))
|
||||
* </pre>
|
||||
* <p>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.
|
||||
* @deprecated as of Spring Framework 5.2 in favor of {@link #body(Object)}
|
||||
*/
|
||||
@Deprecated
|
||||
RequestHeadersSpec<?> syncBody(Object body);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user