1
votes

I'm using org.springframework.web.reactive.function.client.WebClient in a Spring Boot (2.0.0.M1) application to query a REST interface that returns a nested array:

[
    [ "name1", 2331.0, 2323.3 ],
    [ "name2", 2833.3, 3838.2 ]
]

I'm now trying to map this response to a Flux of objects. To do that I did the following call:

WebClient webClient = WebClient.create("http://example.org");

Flux<Result> results = webClient.get().uri("/query").
    accept(MediaType.APPLICATION_JSON_UTF8).
    exchange().
    flatMapMany(response -> response.bodyToFlux(Result.class));

The Result class looks something like this:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import java.math.BigDecimal;

@Data
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
public class Result {

    private final String name;
    private final BigDecimal value1;
    private final BigDecimal value2;

    @JsonCreator
    public Result(
        @JsonProperty String name,
        @JsonProperty BigDecimal value1,
        @JsonProperty BigDecimal value2) {
        this.name = name;
        this.value1 = value1;
        this.value2 = value2;
    }
}

Unfortunately I get the following error:

org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/json;charset=utf-8' not supported

Can anybody tell me what I'm doing wrong or tell me a better way to deserialize this kind of response into a Flux, preferably in a nonblocking way?

1

1 Answers

1
votes

The problem is not connected to Flux.

Jackson simply can't deserialize your json object and probably it's not possible to do so public Result(@JsonProperty String name, @JsonProperty BigDecimal value1, @JsonProperty BigDecimal value2) with an array of different values.

The easiest fix is to use next constructor implementation.

@JsonCreator
public Result(Object[] args) {
     this.name = String.valueOf(args[0]);
     this.value1 = new BigDecimal(String.valueOf(args[1]));
     this.value2 = new BigDecimal(String.valueOf(args[2]));
}