Affects: 6.0.5 (perhaps down to 5.0, the since
value on BodyInserters
)
Currently in BodyInserters
, FormInserter
only supports a blocking supply of values, and MultipartInserter
extends that interface with support for values from a Publisher
. Each interface's Default[...]
implementation then provides the relevant MediaType
when insert
ing the content. The async support is therefore coupled with using MediaType.MULTIPART_FORM_DATA
.
It would be nice if the async support were available in FormInserter
/DefaultFormInserter
, such that a client could provide the form values reactively while still using MediaType.APPLICATION_FORM_URLENCODED
/ FORM_DATA_TYPE
.
Comment From: poutsma
As it turns out, you can use the FormPartEvent
API to accomplish what you want, and then use the resulting Flux<FormPartEvent>
as body. I have added a tests that shows how to do this here: https://github.com/spring-projects/spring-framework/blob/faaf3a61f2944d80b8919c8900325db097944f24/spring-web/src/test/java/org/springframework/http/codec/multipart/PartEventHttpMessageWriterTests.java#L99
Comment From: nmck257
Thanks for that.
I wasn't actually able to accomplish my goal with FluxFormPartEvent
. This sample:
WebClient.create().post().uri("http://localhost:%s".formatted(mockWebServer.getPort()))
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(Flux.concat(Mono.just(FormPartEvent.create("key", "value"))), PartEvent.class)
.retrieve()
.toBodilessEntity()
.block();
...yields an exception like this:
org.springframework.web.reactive.function.client.WebClientRequestException: Content type 'application/x-www-form-urlencoded' not supported for bodyType=org.springframework.http.codec.multipart.PartEvent
Looks like the default PartEventHttpMessageWriter
is only configured for MediaType.MULTIPART_FORM_DATA
.
But after trying that, I did have success with something more like:
WebClient.create().post().uri("http://localhost:%s".formatted(mockWebServer.getPort()))
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(Mono.just(new LinkedMultiValueMap()), MultiValueMap.class)
.retrieve()
.toBodilessEntity()
.block();
...reliant on MultipartHttpMessageWriter
. Maybe there's value in updating the javadocs for BodyInserters::fromFormData
to call out alternatives like this?
(tested using spring-framework 6.0.12)