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.
@Slf4j @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("===========================request begin================================================"); 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("==========================request end================================================"); } } private void logResponse(ClientHttpResponse response) throws IOException { if (log.isDebugEnabled()) { log.debug("============================response begin=========================================="); 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("=======================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.
Leave A Comment