Open In App

How to Get a Response Body When Testing the Status Code in WebFlux WebClient?

Last Updated : 21 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Spring WebFlux is an HTTP request client. Reactor is the foundation of WebClient’s functional and fluid API, allowing declarative building of asynchronous logic without requiring knowledge of threads or concurrency. It uses the same codecs that are also used to encode and decode request and response material on the server side, and it is completely non-blocking and streaming-compatible.

Example of Testing the Status Code in WebFlux WebClient

Here is an example of Get a Response Body when Testing the Status Code in WebFlux WebClient.

Java
// Making a POST request and retrieving the response
client.post()
      .exchange()
      .doOnSuccess(response -> {
          // Check if the HTTP status code is 201 (Created)
          if (response.statusCode().value() == 201) {
              // If status code is 201, throw a runtime exception
              throw new RuntimeException("Unexpected HTTP status code 201");
          }
        
      });

Step-by-Step Implementation to get a Response Body When Testing the Status Code in WebFlux WebClient

Below are the steps to implement to get a Response Body while testing the status code in WebFlux WebClient.

Step 1: Add Maven Dependencies

The spring-boot-starter-webflux module has to be imported into our Spring Boot project in order for us to access the WebClient API.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

Step 2: Use WebClient.Builder API

The DefaultWebClientBuilder class, which employs the builder pattern style fluent-API, is another way we might construct the client.

Java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class WebConfig 
{

    @Bean
    public WebClient webClient() 
    {

        // create a WebClient bean with a base URL and default settings
        WebClient webClient = WebClient.builder()
                .baseUrl("http://localhost:3000")
                .defaultCookie("cookie-name", "cookie-value")
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();

        // return the configured WebClient bean
        return webClient;
    }
}

Step 3: Get the WebFlux WebClient to use onStatus

An integrated method for managing a WebClient response is onStatus. This enables us to apply fine-grained functionality depending on certain replies or status categories.

WebClient
.builder()
.build()
.post()
.uri("/some-resource")
.retrieve()
.onStatus(
HttpStatus.INTERNAL_SERVER_ERROR::equals,
response -> response.bodyToMono(String.class).map(Exception::new))

Step 4: Use ExchangeFilterFunction to handle specific status codes

A further method to handle certain status codes and obtain response bodies is to use an ExchangeFilterFunction. The exchange filter is adaptable and may apply to filter functionality based on any Boolean expression, in contrast to onStatus.

Java
/**
 * Processes the client response by checking its HTTP status code and handling specific cases.
 *
 * @param response The client response to be processed.
 * @return A Mono representing the processed response or an error Mono with a custom exception.
 */
private static Mono<ClientResponse> exchangeFilterResponseProcessor(ClientResponse response) 
{
    // extract the HTTP status code from the response
    HttpStatus status = response.statusCode();

    // handle Internal Server Error (500) case
    if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) 
    {
        return response.bodyToMono(String.class)
                .flatMap(body -> Mono.error(new CustomServerErrorException(body)));
    }

    // handle Bad Request (400) case
    if (HttpStatus.BAD_REQUEST.equals(status)) {
        return response.bodyToMono(String.class)
                .flatMap(body -> Mono.error(new CustomBadRequestException(body)));
    }

    // if the response does not match any special case, return it as is
    return Mono.just(response);
}

Step 5: Use a method reference to handler

Now we will use a method reference to handler to test the status code.

Java
// define an ExchangeFilterFunction for handling responses
ExchangeFilterFunction errorResponseFilter = ExchangeFilterFunction
        // use the ofResponseProcessor method to specify a response processor
        .ofResponseProcessor(WebClientStatusCodeHandler::exchangeFilterResponseProcessor);
// this filter is likely to be applied to a WebClient instance for handling HTTP responses

// define an ExchangeFilterFunction for handling responses
ExchangeFilterFunction errorResponseFilter = ExchangeFilterFunction
        // use the ofResponseProcessor method to specify a response processor
        .ofResponseProcessor(WebClientStatusCodeHandler::exchangeFilterResponseProcessor);

Step 6: Apply this ResponseFilter to WebClient

Now use this on a WebClient object to accomplish the same goal as the onStatus chained call:

Java
// make a POST request using WebClient
Mono<String> response = WebClient
        .builder()
        // apply the errorResponseFilter as a filter for handling responses
        .filter(errorResponseFilter)
        .build()
        .post()
        .uri("some-resource")
        .retrieve()
        // extract the response body as a Mono<String>
        .bodyToMono(String.class);

// perform further actions with the response, such as handling or processing it
response.subscribe(
        // onSuccess: Handle the successful response
        successResponse -> {
           
            System.out.println("Successful Response: " + successResponse);
        },
        // onError: Handle errors that may occur during the request
        error -> {
            // Handle and log the error (e.g., network issues, HTTP errors, etc.)
            System.err.println("Error during request: " + error.getMessage());
        },
        // onComplete: Handle completion (optional)
        () -> {
            // Optionally handle completion, if needed
            System.out.println("Request completed successfully");
        }
);

By using the above methods, we can get the response body based on the HTTP Status code in WebFlux WebClient.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads