Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a json field by name using Spring WebClient?

I have the following JSON Response:

{
    "Count": 1,
    "Products": [
        {
            "ProductID": 3423
        },
        {
            "ProductID": 4321
        }
    ]
}

I want to be able to return a List of "Product" from the Products array using WebClient without having to create a separate Dto class with the field 'ArrayList products'

I used something like this

        webClient.get()
                .uri(uriBuilder -> uriBuilder
                .path(URI_PRODUCTS)
                .build())
                .accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToFlux(Product.class)
                .collectList();

It retrieves a List with one Product in it but all the values null. I am able to get it to work with a DTO response such as

...retrieve().bodyToMono(ProductResponse.class).block();

Where the ProductResponse has the List of Products in it. But I am trying to avoid having to create the extra class. Is there a way to pull the field similar to using jsonPath (similar to WebTestClient)?

like image 299
Joe A Avatar asked Feb 12 '19 22:02

Joe A


People also ask

How do I get JSON response from WebClient?

You would just use bodyToMono which would return a Mono object. WebClient webClient = WebClient. create(); String responseJson = webClient. get() .

How do I log a body response in WebClient?

Logging Request and Response with Body HTTP clients have features to log the bodies of requests and responses. Thus, to achieve the goal, we are going to use a log-enabled HTTP client with our WebClient. We can do this by manually setting WebClient. Builder#clientConnector – let's see with Jetty and Netty HTTP clients.

What is the difference between WebClient and RestTemplate?

RestTemplate uses Java Servlet API and is therefore synchronous and blocking. Conversely, WebClient is asynchronous and will not block the executing thread while waiting for the response to come back. The notification will be produced only when the response is ready. RestTemplate will still be used.


1 Answers

after retrieve() you can always .map your result to corresponding type. With the help of JsonNode path() instance method you can do it similar to WebTestClient jsonPath()

webClient.get()
            .uri(uriBuilder -> uriBuilder
                .path(URI_PRODUCTS)
                .build())
            .accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .bodyToMono(JsonNode.class)
            .map(s-> s.path("Products"))
            .map(s->{
                try {
                    return mapper.readValue(s.traverse(), new TypeReference<List<Product>>() {} );
                } catch (IOException e) {
                    e.printStackTrace();
                    return new ArrayList<Product>();
                }
            })
            .block();
like image 154
Nikolay Rusev Avatar answered Oct 23 '22 05:10

Nikolay Rusev