Browse Source

Fall back on the value type in BodyInserters if necessary

Closes gh-36078
pull/36125/head
rstoyanchev 3 weeks ago
parent
commit
b69cbad38d
  1. 10
      spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyInserters.java
  2. 32
      spring-webflux/src/test/java/org/springframework/web/reactive/function/client/support/WebClientAdapterTests.java

10
spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyInserters.java

@ -98,7 +98,8 @@ public abstract class BodyInserters { @@ -98,7 +98,8 @@ public abstract class BodyInserters {
public static <T> BodyInserter<T, ReactiveHttpOutputMessage> fromValue(T body) {
Assert.notNull(body, "'body' must not be null");
Assert.isNull(registry.getAdapter(body.getClass()),
"'body' should be an object, for reactive types use a variant specifying a publisher/producer and its related element type");
"'body' should not be a reactive type. " +
"For reactive types use a variant with a publisher/producer and the element type");
return (message, context) ->
writeWithMessageWriters(message, context, Mono.just(body), ResolvableType.forInstance(body), null);
}
@ -124,9 +125,12 @@ public abstract class BodyInserters { @@ -124,9 +125,12 @@ public abstract class BodyInserters {
Assert.notNull(body, "'body' must not be null");
Assert.notNull(bodyType, "'bodyType' must not be null");
Assert.isNull(registry.getAdapter(body.getClass()),
"'body' should be an object, for reactive types use a variant specifying a publisher/producer and its related element type");
"'body' should not be a reactive type. " +
"For reactive types use a variant with a publisher/producer and the element type");
ResolvableType bodyTypeToUse = (bodyType.getType().equals(Object.class) ?
ResolvableType.forInstance(body) : ResolvableType.forType(bodyType));
return (message, context) ->
writeWithMessageWriters(message, context, Mono.just(body), ResolvableType.forType(bodyType), null);
writeWithMessageWriters(message, context, Mono.just(body), bodyTypeToUse, null);
}
/**

32
spring-webflux/src/test/java/org/springframework/web/reactive/function/client/support/WebClientAdapterTests.java

@ -26,6 +26,7 @@ import java.util.Map; @@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import jakarta.xml.bind.annotation.XmlRootElement;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import mockwebserver3.RecordedRequest;
@ -36,6 +37,7 @@ import org.junit.jupiter.api.Test; @@ -36,6 +37,7 @@ import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@ -189,6 +191,24 @@ class WebClientAdapterTests { @@ -189,6 +191,24 @@ class WebClientAdapterTests {
assertThat(request.getBody().utf8()).isEqualTo("[{\"name\":\"John\"},{\"name\":\"Richard\"}]");
}
@Test // gh-36078
void postObject() throws InterruptedException {
prepareResponse(response -> response.code(201));
WebClient webClient = WebClient.builder()
.baseUrl(this.server.url("/").toString())
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)
.build();
initService(webClient).postObject(new Person("John"));
RecordedRequest request = server.takeRequest();
assertThat(request.getMethod()).isEqualTo("POST");
assertThat(request.getTarget()).isEqualTo("/object");
assertThat(request.getBody().utf8()).isEqualTo(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><person><name>John</name></person>");
}
@Test
void uriBuilderFactory() throws Exception {
String ignoredResponseBody = "hello";
@ -304,6 +324,9 @@ class WebClientAdapterTests { @@ -304,6 +324,9 @@ class WebClientAdapterTests {
@PostExchange("/persons")
void postPersonSet(@RequestBody Set<Person> set);
@PostExchange("/object")
void postObject(@RequestBody Object object);
@GetExchange("/greeting")
String getWithUriBuilderFactory(UriBuilderFactory uriBuilderFactory);
@ -316,9 +339,13 @@ class WebClientAdapterTests { @@ -316,9 +339,13 @@ class WebClientAdapterTests {
}
@XmlRootElement
static final class Person {
private final String name;
private String name;
public Person() {
}
Person(String name) {
this.name = name;
@ -328,6 +355,9 @@ class WebClientAdapterTests { @@ -328,6 +355,9 @@ class WebClientAdapterTests {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
}

Loading…
Cancel
Save