cellepo
cellepo

Reputation: 4479

Spring RestTemplate: How to reach state to check #is4xxClientError, instead of RestClientException 1st?

In my experience, after calling Spring's RestTemplate#exchange that subsequently receives '404 - Not Found' response, a RestClientException is thrown instead of returning a ResponseEntity that can have its status checked (i.e: with ResponseEntity#getStatusCode#is4xxClientError).

I don't understand why HttpStatus#is4xxClientError even exists if instead an Exception is thrown that prevents returning a ResponseEntity with HttpStatus to call #is4xxClientError on...

I'm reasonably convinced what I just described is the actual situation, because I can find other accounts on the internet that confirm that (i.e: Spring MVC - RestTemplate launch exception when http 404 happens).

How can I get to a state in Java code using RestTemplate where I can indeed check ResponseEntity#getStatusCode#is4xxClientError when RestTemplate#exchange receives 404, rather than being prevented by the RestClientException? Is it something to do with RestTemplate configuration?

Or am I correct that is not actually possible, and maybe the existence of ResponseEntity#getStatusCode#is4xxClientError is actually a 'bug'?

Upvotes: 2

Views: 3154

Answers (1)

Hemant Patel
Hemant Patel

Reputation: 3260

RestTemplate has a method

public void setErrorHandler(ResponseErrorHandler errorHandler);

And ResponseErrorHandler interface look like this.

public interface ResponseErrorHandler {

    boolean hasError(ClientHttpResponse response) throws IOException;

    void handleError(ClientHttpResponse response) throws IOException;
}

Whenever RestTemplate processes a response, it first call ResponseErrorHandler#hasError(), if it returns true, ResponseErrorHandler#handleError() is called which may throw exception.

If you don't set ResponseErrorHandler#setErrorHandler(), it defaults to DefaultResponseErrorHandler.java.
Default implementation treats 4xx / 5xx series status code as error and throws RestClientException (not this exception but subclasses of this exception).

You can always write your own ResponseErrorHandler and override the default behavior. So this way you can get a ResponseEntity object even in case of 4xx / 5xx (by writing your own implementation of ResponseErrorHandler and returning always false from the method hasError()).

Once you have ResponseEntity object, you can use ResponseEntity#getStatusCode()#is4xxClientError() method for the same purpose.

Upvotes: 5

Related Questions