Edit: Note that this implementation is not thread-safe. It doesn't currently work for concurrent requests
This can be done by implementing your extension of the Jackson2JsonEncoder
that logs the request body.
This is explained in this blog post: https://andrew-flower.com/blog/webclient-body-logging (which provides a thread-safe version).
When building your WebClient, you can specify the custom encoder:
WebClient webClient = WebClient.builder()
.baseUrl(...)
.codecs(codecConfigurer -> {
codecConfigurer.defaultCodecs().jackson2JsonEncoder(loggingEncoder);
})
...
.build();
An example of an encoder that produces the serialized bytes is this:
public class LoggingJsonEncoder extends Jackson2JsonEncoder {
private final Consumer<byte[]> payloadConsumer;
public LoggingJsonEncoder(final Consumer<byte[]> payloadConsumer) {
this.payloadConsumer = payloadConsumer;
}
@Override
public DataBuffer encodeValue(final Object value, final DataBufferFactory bufferFactory,
final ResolvableType valueType, @Nullable final MimeType mimeType, @Nullable final Map<String, Object> hints) {
// Encode/Serialize data to JSON
final DataBuffer data = super.encodeValue(value, bufferFactory, valueType, mimeType, hints);
// Interception: Generate Signature and inject header into request
payloadConsumer.accept(extractBytesAndReset(data));
// Return the data as normal
return data;
}
private byte[] extractBytesAndReset(final DataBuffer data) {
final byte[] bytes = new byte[data.readableByteCount()];
data.read(bytes);
data.readPosition(0);
return bytes;
}
}
So you could create the encoder with a consumer that prints to Stdout, and pass it to the WebClient builder in the first snippet.
LoggingJsonEncoder loggingEncoder = new LoggingJsonEncoder(bytes -> System.out.print(new String(bytes)));
Bear in mind that this will be slow because it is synchronously reading the whole serialized data. So use this only in dev/debug mode.