java.net.http httpclient sendasync consumer callback says unexpected return value

644 Views Asked by At

I am using Java 17. I am trying to get the response from a message service and create a map object. Then send it to the caller method. I am using java.net.http.

I am willing to use a callback so that I could not use join or get to delay the main thread. But at my callback, the message shown unexpected return value.

My attempts are as below:

    LinkedHashMap<String, Object> retVal = new LinkedHashMap<>();

HttpRequest request = HttpRequest.newBuilder(URI.create(url))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(params))
                .build();               
        
HttpClient.newHttpClient()
                .sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(responseBody -> {
                    try {
                        LinkedHashMap<String, Object> responseMap = new ObjectMapper().readValue(responseBody.body(), new TypeReference<>() {});

                        ArrayList<LinkedHashMap<String, String>> resultList = (ArrayList<LinkedHashMap<String, String>>) responseMap.get("result");
                        HashMap<String, String> resultMap = resultList.get(0);
                        retVal.put("status", resultMap.get("status"));
                        retVal.put("message", resultMap.get("message"));
                    } catch (JsonProcessingException e) {
                        retVal.put("status", "FAILED");
                        retVal.put("message", e.getMessage());
                        e.printStackTrace();
                    }
                    return retVal;
                })
                .exceptionally(ex -> {
                    retVal.put("status", "FAILED");
                    retVal.put("message", ex.getMessage());
                    System.out.println("Exception occurred: " + ex.getMessage());
                    return retVal;
                })
                .thenAccept(callback);  
                
// Define a callback function
        Consumer<LinkedHashMap<String, Object>> callback = responseBody -> {
            // Send the response back to the caller here
            return responseBody;
        };  

How can I achieve this?

1

There are 1 best solutions below

5
fascynacja On

Method:

public CompletableFuture<Void> thenAccept(Consumer<? super T> action)

can only accept a Consumer object. A Consumer object does not return anything, it only consumes an action so it could for instance look like this:

Consumer<LinkedHashMap<String, Object>> callback = System.out::println;

The best would be to use your consumer method and do there whatever you would like to do with the retVal variable. Instead of returning you have to do your logic inside the callback method. For instance:

Consumer<LinkedHashMap<String, Object>> callback = linkedMap -> {
    if (linkedMap != null) {
        linkedMap.keySet().forEach(k -> doSomethingWithEveryKey(k));
    }
};

If you would like to create a fully asynchronous and non-blocking application you can use Spring Webflux, where your method can look like:

@GetMapping("/firstCall")
public Mono<String> getMessage() {
    return this.client.get().uri("/secondCall").accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .bodyToMono(String.class)
            .map(this::mapResponse);
}

private String mapResponse(String input) {
    return "modified response";
}