Spring RestTemplate Request & Response Logging
It’s sometimes useful to log HTTP requests and responses when working with a Spring RestTemplate. If you need fine-grained control over exactly what’s logged you can use a custom interceptor to add logging before and after the remote call.
Creating an Interceptor
You’ll need to create a class that extends ClientHttpRequestInterceptor and implement the intercept method as shown below.
@Component
public class LoggingInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
logRequest(request, body);
ClientHttpResponse response = execution.execute(request, body);
logResponse(response);
return response;
}
private void logRequest(HttpRequest request, byte[] body) throws IOException {
if (log.isDebugEnabled()) {
log.debug("===log request start===");
log.debug("URI: {}", request.getURI());
log.debug("Method: {}", request.getMethod());
log.debug("Headers: {}", request.getHeaders());
log.debug("Request body: {}", new String(body, "UTF-8"));
log.debug("===log request end===");
}
}
private void logResponse(ClientHttpResponse response) throws IOException {
if (log.isDebugEnabled()) {
log.debug("===log response start===");
log.debug("Status code: {}", response.getStatusCode());
log.debug("Status text: {}", response.getStatusText());
log.debug("Headers: {}", response.getHeaders());
log.debug("Response body: {}", StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()));
log.debug("===log response end===");
}
}
}
When this class is registered with a RestTemplate Spring will call the intercept method before the request is dispatched, which allows you to log the request. In the logRequest method, I’ve grabbed information from the request that I want to log. Obviously, you can log as much or as little as you like here.
After logging the request I call the execute method on the ClientHttpRequestExecution object to dispatch the request. When the response is received I log the status, headers and body.
Configuring the RestTemplate
To make sure the interceptor is called you’ll need to register it with the RestTemplate . In the example below I’ve added just the LoggingInterceptor, but you’re free to add multiple interceptors and Spring will chain them together for you at runtime.
@Bean
public RestTemplate createRestTemplate(LoggingInterceptor loggingInterceptor, RestErrorHandler restErrorHandler) {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(loggingInterceptor));
return restTemplate;
}
You can of course just enable debug logging on the RestTemplate package but I like using an interceptor as if gives you fine-grained control to log exactly what you want.
Happy coding..