I'm trying to log a request using Spring 5 WebClient. Do you have any idea how could I achieve that?
(I'm using Spring 5 and Spring boot 2)
The code looks like this at the moment:
try {
return webClient.get().uri(url, urlParams).exchange().flatMap(response -> response.bodyToMono(Test.class))
.map(test -> xxx.set(test));
} catch (RestClientException e) {
log.error("Cannot get counter from opus", e);
throw e;
}
You can easily do it using ExchangeFilterFunction
Just add the custom
logRequest
filter when you create yourWebClient
usingWebClient.Builder
.Here is the example of such filter and how to add it to the
WebClient
.Then just call
myClient.send("get");
and log messages should be there.Output example:
Edit
Some people pointed out in comments that
block()
is bad practice etc. I want to clarify:block()
call here is just for demo purposes. The request logging filter will work anyway. You will not need to addblock()
to your code to makeExchangeFilterFunction
work. You can useWebClient
to perform a http-call in a usual way, chaining methods and returningMono
up the stack until someone will subscribe to it. The only relevant part of the answer islogRequest()
filter. You can ignoresend()
method altogether - it is not part of the solution - it just demonstrates that filter works.Some people also asked how to log the response. To log the response you can write another
ExchangeFilterFunction
and add it toWebClient
. You can useExchangeFilterFunction.ofResponseProcessor
helper for this purpose just the same way asExchangeFilterFunction.ofRequestProcessor
is used. You can use methods ofClientResponse
to get headers/cookies etc.Don't forget to add it to your
WebClient
:But be careful and do not try to read the response body here in the filter. Because of the stream nature of it, the body can be consumed only once without some kind of buffering wrapper. So, if you will read it in the filter, you will not be able to read it in the subscriber.
If you really need to log the body, you can make the underlying layer (Netty) to do this. See Matthew Buckett's answer to get the idea.