2
votes

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?

3

3 Answers

4
votes

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.

0
votes

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

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

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.