Accessing Request Body in Spring WebClient

When working with Spring WebClient, you may encounter situations where the JSON representation of an object doesn't match what's actually sent to the third-party API. This discrepancy can cause issues, particularly when implementing encryption logic that depends on the exact request body format.

The challenge is that WebClient doesn't provide a straightforward way to access the request body once it's been serialized. After exploring various approaches, a practical solution emerges: directly passing the pre-serialized JSON string to the request instead of relying on WebClient's automatic serialization.

The Solution

Instead of passing an object to WebClient and letting it handle the serialization, you can serialize the object yourself and send the resulting JSON string directly. This approach gives you full control over the exact format of the request body.

Here's the implementation:

MultiValueMap<String, String> headers = authenticationService.buildHeaders(requestPayload);

return this.webClient.post()
    .uri("/")
    .headers(httpHeaders -> {
        httpHeaders.addAll(headers);
    })
    .bodyValue(SerializationUtils.toJsonString(requestPayload))
    .retrieve()
    .bodyToFlux(String.class);

Previously, the code might have used body(Mono.just(requestPayload), RequestClass.class), which relies on WebClient's internal serialization mechanism. By switching to bodyValue(SerializationUtils.toJsonString(requestPayload)), you pass the exact JSON string that was used during encryption, ensuring consistency between your encryption logic and the actual request.

Accessing Request Metadata with Filters

If your use case involves logging or monitoring rather than encryption, you can use WebClient's filter mechanism to capture request metadata such as headers and cookies:

ExchangeFilterFunction loggingFilter = ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
    log.info("Request URI: {}", clientRequest.url());
    log.info("Request Headers: {}", clientRequest.headers());
    log.info("Request Cookies: {}", clientRequest.cookies());
    return Mono.just(clientRequest);
});

WebClient customClient = WebClient.builder()
    .baseUrl(baseUrl)
    .filter(loggingFilter)
    .defaultHeaders(headers)
    .build();

Note that this filter approach only provides access to request metadata, not request body itself. The filter executes before the body is serialized, making it impossible to capture the body through this mechanism.

Summary

When you need precise control over the request body format in WebClient, the most effective approach is to handle serialization yourself and pass the JSON string directly. This eliminates discrepancies between how your application serializes data and how WebClient handles it internally. For logging purposes, use the filter function to access request metadata, though the body itself cannot be captured through this approach.

Tags: spring-webflux webclient java reactive-programming http-client

Posted on Wed, 27 May 2026 19:42:33 +0000 by Notoriouswow