diff --git a/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java b/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java index f9429225d9..1835f288e3 100644 --- a/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java @@ -91,6 +91,12 @@ public final class MultipartBodyBuilder { "publisher(String, Publisher, ParameterizedTypeReference) for adding Publisher parts"); } + if (part instanceof PublisherEntity) { + PublisherPartBuilder builder = new PublisherPartBuilder<>((PublisherEntity) part); + this.parts.add(name, builder); + return builder; + } + Object partBody; HttpHeaders partHeaders = new HttpHeaders(); @@ -154,7 +160,7 @@ public final class MultipartBodyBuilder { Assert.notNull(elementType1, "'typeReference' must not be null"); HttpHeaders headers = new HttpHeaders(); - PublisherPartBuilder builder = new PublisherPartBuilder<>(publisher, typeReference, headers); + PublisherPartBuilder builder = new PublisherPartBuilder<>(headers, publisher, typeReference); this.parts.add(name, builder); return builder; } @@ -239,11 +245,17 @@ public final class MultipartBodyBuilder { this.resolvableType = ResolvableType.forClass(elementClass); } - public PublisherPartBuilder(P body, ParameterizedTypeReference typeReference, HttpHeaders headers) { + public PublisherPartBuilder(HttpHeaders headers, P body, ParameterizedTypeReference typeReference) { super(headers, body); this.resolvableType = ResolvableType.forType(typeReference); } + public PublisherPartBuilder(PublisherEntity other) { + super(other.getHeaders(), other.getBody()); + this.resolvableType = other.getResolvableType(); + } + + @Override @SuppressWarnings("unchecked") public HttpEntity build() { diff --git a/spring-web/src/test/java/org/springframework/http/client/MultipartBodyBuilderTests.java b/spring-web/src/test/java/org/springframework/http/client/MultipartBodyBuilderTests.java index d948cd6fd2..e7f63a4365 100644 --- a/spring-web/src/test/java/org/springframework/http/client/MultipartBodyBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/http/client/MultipartBodyBuilderTests.java @@ -26,6 +26,7 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; +import org.springframework.http.client.MultipartBodyBuilder.PublisherEntity; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -80,15 +81,36 @@ public class MultipartBodyBuilderTests { assertNotNull(resultEntity); assertEquals(publisher, resultEntity.getBody()); assertEquals(ResolvableType.forClass(String.class), - ((MultipartBodyBuilder.PublisherEntity) resultEntity).getResolvableType()); + ((PublisherEntity) resultEntity).getResolvableType()); assertEquals("qux", resultEntity.getHeaders().getFirst("baz")); resultEntity = result.getFirst("publisherPtr"); assertNotNull(resultEntity); assertEquals(publisher, resultEntity.getBody()); assertEquals(ResolvableType.forClass(String.class), - ((MultipartBodyBuilder.PublisherEntity) resultEntity).getResolvableType()); + ((PublisherEntity) resultEntity).getResolvableType()); assertEquals("qux", resultEntity.getHeaders().getFirst("baz")); } + @Test // SPR-16601 + public void publisherEntityAcceptedAsInput() { + + Publisher publisher = Flux.just("foo", "bar", "baz"); + MultipartBodyBuilder builder = new MultipartBodyBuilder(); + builder.asyncPart("publisherClass", publisher, String.class).header("baz", "qux"); + HttpEntity entity = builder.build().getFirst("publisherClass"); + + assertNotNull(entity); + assertEquals(PublisherEntity.class, entity.getClass()); + + // Now build a new MultipartBodyBuilder, as BodyInserters.fromMultipartData would do... + + builder = new MultipartBodyBuilder(); + builder.part("publisherClass", entity); + entity = builder.build().getFirst("publisherClass"); + + assertNotNull(entity); + assertEquals(PublisherEntity.class, entity.getClass()); + } + } \ No newline at end of file