How to HTTP POST a Flux<String> as a JSON array using Spring's WebClient?

Viewed 4465

How do I use Spring's reactive WebClient to POST a Flux<String> as a JSON array?

Flux<String> stringFlux = Flux.fromIterable(objects).map(MyObject::getSomeString);

WebClient.create(baseUrl)
  .post()
  .uri(myUrl)
  .contentType(MediaType.APPLICATION_JSON)
  .body(stringFlux, String.class)
  .exchange()
  .flatMap(response -> {
     if (response.statusCode().is2xxSuccessful()) {
       // Do something
     }
     return response.bodyToMono(Void.class);
   })
   .block();

This sends the request, but it's not sending it as a JSON array of strings.

I saw that there's another body() signature that accepts a ParameterizedTypeReference, so I tried this:

.body(stringFlux.collectList(), new ParameterizedTypeReference<>() {})

but this results in a compile error actually (I'm on Java 11):

Error:java: com.sun.tools.javac.code.Types$FunctionDescriptorLookupError.

Any ideas?

4 Answers

Well I'll be darned. I got it working using ParameterizedTypeReference. As is usually the case, the compile error sums it up. I omitted the type parameter when declaring a new ParameterizedTypeReference<>() {}. Providing the type did the trick and posted my Flux<String> as a JSON array:

.body(stringFlux.collectList(), new ParameterizedTypeReference<List<String>>() {})

IntelliJ was telling me this type was inferred, but apparently it is not.

You can do it without ParametrizedTypeRefrence using List.class is enough for Strings.

.body(stringFlux.collectList(), List.class)

The voted solution doesn't seem to produce the mentioned result. This seems to stream a list of JSON objects (which is what Webclient is intended for) rather than sending a JSON Array structure. the result I get with that technic is :

{}{}{}{}

A JSON Array output would be:

[{}, {}, {}, {}]

Unless I'm missing something.

.body(BodyInserters.fromFormData(stringFlux))

Not sure if this is the right answer. It works for me to send List<> as body

Related