javaspring-webfluxspring-webclientjsonnode

spring-webflux : How to Extract user defined object from Mono<T> or Flux<T> from the response without blocking?


getUserDetails Method returns Mono of Type JsonNode. But I Actually want to return a Mono<User.java> or Flux<User.java>. please help modifying getBulkUserInfo or getUserDetails to get the Mono<User.java> or Flux<User.java>

public Mono<JsonNode> getUser(BigInteger Id){
    return this.client.get()
            .uri("/URL/{Id}",Id)
            .retrieve()
            .bodyToMono(JsonNode.class);
}

public Flux getBulkUsers(List<BigInteger> Ids){
    return Flux.fromIterable(Ids).flatMap(this::getUser);
}

But The json response from the Url is something like

{
"resultholder": {
            "totalResults": "1",
            "profiles": {
                "profileholder": {
                    "user": {
                        "country": "IND",
                        "zipCode": "560048",
                        "name":"Test"
                    }
                }
            }            
        }
}

I tried different ways but nothing worked subscribe() and .doOnNext(resp -> resp.get("resultholder").get("profiles").get("profileholder").get("user"))

    .bodyToMono(JsonNode.class)
.doOnNext(resp ->{return
 JSONUtils.deserialize(resp.get("resultholder").get("profiles").get("profileholder").get("user"), User.class)})

Solution

  • This is pretty straightforward and there is no need to block. Its just applying further mappings on the response. You can use the following code for your problem

     return webClient
                .get()
                .uri("profilesEndPoint/" + id)
                .retrieve()
                .bodyToMono(JsonNode.class)
                .map(jsonNode ->
                        jsonNode.path("resultholder").path("profiles").path("profileholder").path("user")
                ).map(
                        userjsonNode -> mapper.convertValue(userjsonNode, User.class)
                );
    

    Where mapper is jackson ObjectMapper

    private final ObjectMapper mapper = new ObjectMapper();

    If you have any issues please refer to this code here :