I am trying to log the request-response pairs for every request. The problem is that when the response code is 401, ClientHttpResponse.getBody() throws a ResourceAccessException and i cannot read the response body.  
This is the RestTemplate configuration
RestTemplate restTemplate = new RestTemplate();
// Added this requestFactory to make response object readable more than once.
ClientHttpRequestFactory requestFactory =
        new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
restTemplate.setRequestFactory(requestFactory);
restTemplate.getInterceptors().add(new RequestLoggingInterceptor(vCloudRequest.getAction(),httpHeaders));
    restTemplate.setErrorHandler(new RequestErrorHandler());
return restTemplate;
The last line of the interceptor below throws the following exception.
How can i resolve this problem?
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://example.com/api/sessions": Server returned HTTP response code: 401 for URL: https://example.com/api/sessions; nested exception is java.io.IOException: Server returned HTTP response code: 401 for URL: https://example.com.11/api/sessions
This is the related part of the interceptor.
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    ClientHttpResponse response = execution.execute(request, body);
    String requestString = new String(body);
    // Calling this method because when we make a POST or PUT request and get an error
    // response.getBody() throws IOException. But if we call response.getStatusCode() it works fine.
    // I don't know the reason.
    // I asked a question on stackoverflow
    // https://stackoverflow.com/questions/47429978/resttemplate-response-getbody-throws-exception-on-4-and-5-errors-for-put-and
    response.getStatusCode();
    String responseString = new String(ByteStreams.toByteArray(response.getBody()), Charset.forName("UTF-8"));
...
}
This is the custom error handler
public class RequestErrorHandler implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
        if (!response.getStatusCode().is2xxSuccessful()) {
        return true;
    }
    return false;
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
    JAXBElement<ErrorType> root = null;
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(ErrorType.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        root = jaxbUnmarshaller.unmarshal(new StreamSource(
                response.getBody()), ErrorType.class);
    } catch (JAXBException e) {
        throw new IOException("XML converting error. Cannot convert response to ErrorType");
    }
    ErrorType error = root.getValue();
    throw new VcloudException(error);
}
}
Use HttpComponentsClientHttpRequestFactory instead of SimpleClientHttpRequestFactory.
Also add dependency to 'org.apache.httpcomponents:httpclient.
HttpComponentsClientHttpRequestFactory ccan read body when status is 401.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With