Spring RestTemplate - Overriding ResponseErrorHandler
rest, resttemplate, spring, spring-mvc
Solution
Following link has useful information about Exception Flow for Spring ResponseErrorHandler .
Adding code here, just in-case the blog is down:
Code for ErrorHandler:
public class MyResponseErrorHandler implements ResponseErrorHandler {
private static final Log logger = LogFactory.getLog(MyResponseErrorHandler.class);
@Override
public void handleError(ClientHttpResponse clienthttpresponse) throws IOException {
if (clienthttpresponse.getStatusCode() == HttpStatus.FORBIDDEN) {
logger.debug(HttpStatus.FORBIDDEN + " response. Throwing authentication exception");
throw new AuthenticationException();
}
}
@Override
public boolean hasError(ClientHttpResponse clienthttpresponse) throws IOException {
if (clienthttpresponse.getStatusCode() != HttpStatus.OK) {
logger.debug("Status code: " + clienthttpresponse.getStatusCode());
logger.debug("Response" + clienthttpresponse.getStatusText());
logger.debug(clienthttpresponse.getBody());
if (clienthttpresponse.getStatusCode() == HttpStatus.FORBIDDEN) {
logger.debug("Call returned a error 403 forbidden resposne ");
return true;
}
}
return false;
}
}
Code for using it in RestTemplate:
RestTemplate restclient = new RestTemplate();
restclient.setErrorHandler(new MyResponseErrorHandler());
ResponseEntity<String> responseEntity = clientRestTemplate.exchange(
URI,
HttpMethod.GET,
requestEntity,
String.class);
response = responseEntity.getBody();
Problem
I am calling a `ReST` service through `RestTemplate` and trying to override `ResponseErrorHandler` in `Spring 3.2` to handle custom error codes. CustomResponseErrroHandler ``` public class MyResponseErrorHandler implements ResponseErrorHandler { @Override public boolean hasError(ClientHttpResponse response) throws IOException { boolean hasError = false; int rawStatusCode = response.getRawStatusCode(); if (rawStatusCode != 200){ hasError = true; } return hasError; } @Override public void handleError(ClientHttpResponse response) throws IOException { //String body = IOUtils.toString(response.getBody()); throw new CustomServiceException(response.getRawStatusCode() , "custom Error"); } } ``` `Spring` framework invokes `hasError` method but not `handleError`, so I couldn't throw my custom exception. After delving into `Spring` `RestTemplate` source code, I realized that the code in `handleResponseError` method is causing the issue - It is looking for `response.getStatusCode` or `response.getStatusText` and throwing exception (as statusCode/statusText is null when `Rest` service throws exception) and it never calls either custom implemented or default `handleError` method in the next line. `Spring` `RestTemplate` source code for `handleResponse` method: ``` private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException { if (logger.isWarnEnabled()) { try { logger.warn(method.name() + " request for \"" + url + "\" resulted in " + response.getStatusCode() + " (" + response.getStatusText() + "); invoking error handler"); } catch (IOException e) { // ignore } } getErrorHandler().handleError(response); } ``` FYI, while service throws exception, I can read rawstatuscode but not statuscode from response How to bypass this framework code and make call my custom handler? Thanks for your help in advance.