Default Error Handling By default, the RestTemplate will throw one of these exceptions in the case of an HTTP error: HttpClientErrorException – in the case of HTTP status 4xx. HttpServerErrorException – in the case of HTTP status 5xx. UnknownHttpStatusCodeException – in the case of an unknown HTTP status.
Class RestTemplate. Synchronous client to perform HTTP requests, exposing a simple, template method API over underlying HTTP client libraries such as the JDK HttpURLConnection , Apache HttpComponents, and others.
RestTemplate provides a synchronous way of consuming Rest services, which means it will block the thread until it receives a response. RestTemplate is deprecated since Spring 5 which means it's not really that future proof.
The getForObject method fetches the data for the given response type from the given URI or URL template using HTTP GET method. To fetch data for the given key properties from URL template we can pass Object Varargs and Map to getForObject method. The getForObject returns directly the object of given response type.
You want to create a class that implements ResponseErrorHandler
and then use an instance of it to set the error handling of your rest template:
public class MyErrorHandler implements ResponseErrorHandler {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
// your error handling here
}
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
...
}
}
[...]
public static void main(String args[]) {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new MyErrorHandler());
}
Also, Spring has the class DefaultResponseErrorHandler
, which you can extend instead of implementing the interface, in case you only want to override the handleError
method.
public class MyErrorHandler extends DefaultResponseErrorHandler {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
// your error handling here
}
}
Take a look at its source code to have an idea of how Spring handles HTTP errors.
Spring cleverly treats http error codes as exceptions, and assumes that your exception handling code has the context to handle the error. To get exchange to function as you would expect it, do this:
try {
return restTemplate.exchange(url, httpMethod, httpEntity, String.class);
} catch(HttpStatusCodeException e) {
return ResponseEntity.status(e.getRawStatusCode()).headers(e.getResponseHeaders())
.body(e.getResponseBodyAsString());
}
This will return all the expected results from the response.
You should catch a HttpStatusCodeException
exception:
try {
restTemplate.exchange(...);
} catch (HttpStatusCodeException exception) {
int statusCode = exception.getStatusCode().value();
...
}
Another solution is the one described here at the end of this post by "enlian": http://springinpractice.com/2013/10/07/handling-json-error-object-responses-with-springs-resttemplate
try{
restTemplate.exchange(...)
} catch(HttpStatusCodeException e){
String errorpayload = e.getResponseBodyAsString();
//do whatever you want
} catch(RestClientException e){
//no response payload, tell the user sth else
}
Spring abstracts you from the very very very large list of http status code. That is the idea of the exceptions. Take a look into org.springframework.web.client.RestClientException hierarchy:
You have a bunch of classes to map the most common situations when dealing with http responses. The http codes list is really large, you won't want write code to handle each situation. But for example, take a look into the HttpClientErrorException sub-hierarchy. You have a single exception to map any 4xx kind of error. If you need to go deep, then you can. But with just catching HttpClientErrorException, you can handle any situation where bad data was provided to the service.
The DefaultResponseErrorHandler is really simple and solid. If the response status code is not from the family of 2xx, it just returns true for the hasError method.
I have handled this as below:
try {
response = restTemplate.postForEntity(requestUrl, new HttpEntity<>(requestBody, headers), String.class);
} catch (HttpStatusCodeException ex) {
response = new ResponseEntity<String>(ex.getResponseBodyAsString(), ex.getResponseHeaders(), ex.getStatusCode());
}
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