Log Request and Response with Spring RestTemplate

In this Spring boot rest interceptor example, learn to use ClientHttpRequestInterceptor with Spring RestTemplate to log request and response headers and body in Spring AOP style.

1. Spring REST Interceptor Usages

We can use this interceptor for many useful tasks.

  1. To add a custom header to the response
  2. To log HTTP request and response headers and body
  3. To deny certain requests etc.

2. REST Interceptor to Log Requests and Responses

Below given RequestResponseLoggingInterceptor class implements ClientHttpRequestInterceptor interface. It implements intercept() method. In this method, we are logging the request and response details sent from RestTemplate.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StreamUtils;
  
import java.io.IOException;
import java.nio.charset.Charset;
 
public class RequestResponseLoggingInterceptor implements ClientHttpRequestInterceptor {
    
    private final Logger log = LoggerFactory.getLogger(this.getClass());
  
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException 
    {
        logRequest(request, body);
        ClientHttpResponse response = execution.execute(request, body);
        logResponse(response);
 
        //Add optional additional headers
        response.getHeaders().add("headerName", "VALUE");
 
        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=================================================");
        }
    }
}

3. Register ClientHttpRequestInterceptor with RestTemplate

Now add the above interceptor with RestTemplate’s setInterceptors() method.

@Bean
public RestTemplate restTemplate() 
{
    RestTemplate restTemplate = new RestTemplate();
 
    restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(clientHttpRequestFactory()));
    restTemplate.setMessageConverters(Collections.singletonList(mappingJacksonHttpMessageConverter()));
 
    restTemplate.setInterceptors( Collections.singletonList(new RequestResponseLoggingInterceptor()) );
 
    return restTemplate;
}

It is very important to note that we are allowed to read a response body only once. Next time the body will be empty. So if we want to prevent this behavior, we must use the BufferingClientHttpRequestFactory that buffers all outgoing and incoming streams in memory.

BufferingClientHttpRequestFactory allows us to read the response body multiple times for a single request.

Read More: RestTemplate with HttpClient

4. Demo

Start the application and execute any REST API using RestTemplate. Observe the logs.

2018-06-18T15:27:38.203+0530 DEBUG ===========================request begin=============================================
2018-06-18T15:27:38.203+0530 DEBUG URI         : <URL>
2018-06-18T15:27:38.203+0530 DEBUG Method      : POST
2018-06-18T15:27:38.203+0530 DEBUG Headers     : {Accept=[application/json], Content-Type=[application/json]}
2018-06-18T15:27:38.204+0530 DEBUG Request body: <BODY>
2018-06-18T15:27:38.204+0530 DEBUG ==========================request end================================================
 
2018-06-18T15:27:38.203+0530 DEBUG ===========================response begin=============================================
2018-06-18T15:27:38.203+0530 DEBUG Status code      : 200
2018-06-18T15:27:38.203+0530 DEBUG Status text      : OK
2018-06-18T15:27:38.203+0530 DEBUG Headers        : {Accept=[application/json], Content-Type=[application/json]}
2018-06-18T15:27:38.204+0530 DEBUG Response BODY    : <BODY>
2018-06-18T15:27:38.204+0530 DEBUG ==========================response end================================================

Drop me your questions in the comments section.

Happy Learning !!

Comments

Subscribe
Notify of
guest
7 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.