Wanted to add my implementation of this as well. I apologize for all the missing semi-colons, this is written in Groovy.
I needed something more configurable than the accepted answer provided. Here's a rest template bean that's very agile and will log everything like the OP is looking for.
Custom Logging Interceptor Class:
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.nio.charset.Charset
class HttpLoggingInterceptor implements ClientHttpRequestInterceptor {
private final static Logger log = LoggerFactory.getLogger(HttpLoggingInterceptor.class)
@Override
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=================================================")
}
}
}
Rest Template Bean Definition:
@Bean(name = 'myRestTemplate')
RestTemplate myRestTemplate(RestTemplateBuilder builder) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(10 * 1000) // 10 seconds
.setSocketTimeout(300 * 1000) // 300 seconds
.build()
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager()
connectionManager.setMaxTotal(10)
connectionManager.closeIdleConnections(5, TimeUnit.MINUTES)
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig)
.disableRedirectHandling()
.build()
RestTemplate restTemplate = builder
.rootUri("https://domain.server.com")
.basicAuthorization("username", "password")
.requestFactory(new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient)))
.interceptors(new HttpLoggingInterceptor())
.build()
return restTemplate
}
Implementation:
@Component
class RestService {
private final RestTemplate restTemplate
private final static Logger log = LoggerFactory.getLogger(RestService.class)
@Autowired
RestService(
@Qualifier("myRestTemplate") RestTemplate restTemplate
) {
this.restTemplate = restTemplate
}
// add specific methods to your service that access the GET and PUT methods
private <T> T getForObject(String path, Class<T> object, Map<String, ?> params = [:]) {
try {
return restTemplate.getForObject(path, object, params)
} catch (HttpClientErrorException e) {
log.warn("Client Error (${path}): ${e.responseBodyAsString}")
} catch (HttpServerErrorException e) {
String msg = "Server Error (${path}): ${e.responseBodyAsString}"
log.error(msg, e)
} catch (RestClientException e) {
String msg = "Error (${path})"
log.error(msg, e)
}
return null
}
private <T> T putForObject(String path, T object) {
try {
HttpEntity<T> request = new HttpEntity<>(object)
HttpEntity<T> response = restTemplate.exchange(path, HttpMethod.PUT, request, T)
return response.getBody()
} catch (HttpClientErrorException e) {
log.warn("Error (${path}): ${e.responseBodyAsString}")
} catch (HttpServerErrorException e) {
String msg = "Error (${path}): ${e.responseBodyAsString}"
log.error(msg, e)
} catch (RestClientException e) {
String msg = "Error (${path})"
log.error(msg, e)
}
return null
}
}