javaspringspring-webflux

How to process responses using springwebflux get() and post() methods in an quicker and effective way?


I have tried below code for both of my get() and post() using spring webflux client with JDK17, its working perfectly fine. Its seems like block method taking little bit more time to process response and its blocking the other requests till the current request processing is done. So is there a any way that I can read my responses other than block() method? Final consumers are Java applications uses some key data of JSON response from post() call. and from get() byte response they use to create a file.

Its a SpringBoot (3.X.X) Application runs on Linux Server.

byte[] testResponse1 =  webclient.get()
                       .uri(https://testclient/)
                       .headers(HttpHeaders)
                       .retrieve()
                       .bodyToMono(byte[].class)
                       .block()

String testResponse2 =  webclient.post()
                       .uri(https://testclient/)
                       .contentType(MediaType.MULTIPART_FORM_DATA) 
                       .headers(HttpHeaders)
                       .retrieve()
                       .bodyToMono(String.class)
                       .block()

Solution

  • Using .block() makes the call synchronous and can block other requests in your reactive app. To keep it non-blocking and reactive, you should avoid .block() and instead work with Mono or Flux asynchronously using .subscribe() or chaining operators like .map() or .flatMap().

    webClient.get()
        .uri("https://testclient/")
        .retrieve()
        .bodyToMono(byte[].class)
        .subscribe(response -> {
            // Process byte[] response, e.g., write to file
        });
    
    
    webClient.post()
        .uri("https://testclient/")
    .contentType(MediaType.MULTIPART_FORM_DATA)
        .retrieve()
        .bodyToMono(String.class)
        .subscribe(json -> {
            // Extract key values and use them
        });
    

    OR

    Instead of .block(), let your controller or service method return a Mono or Flux. This way, the calls remain non-blocking, and Spring WebFlux handles the async flow end-to-end.

    public Mono<ResponseEntity<byte[]>> fetchFile() {
        return webClient.get()
            .uri("https://testclient/")
            .retrieve()
            .bodyToMono(byte[].class)
            .map(data -> ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=file.bin")
                .body(data));
    }
    
    public Mono<String> postAndGetJson() {
        return webClient.post()
            .uri("https://testclient/")
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .retrieve()
            .bodyToMono(String.class);
    }