How to extract HTTP status code from the RestTemplate call to a URL?
Solution 1
Use the RestTemplate#exchange(..)
methods that return a ResponseEntity
. This gives you access to the status line and headers (and the body obviously).
Solution 2
If you don´t want to leave the nice abstraction around RestTemplate.get/postForObject...
methods behind like me and dislike to fiddle around with the boilerplate stuff needed when using RestTemplate.exchange...
(Request- and ResponseEntity, HttpHeaders, etc), there´s another option to gain access to the HttpStatus codes.
Just surround the usual RestTemplate.get/postForObject...
with a try/catch for org.springframework.web.client.HttpClientErrorException
and org.springframework.web.client.HttpServerErrorException
, like in this example:
try {
return restTemplate.postForObject("http://your.url.here", "YourRequestObjectForPostBodyHere", YourResponse.class);
} catch (HttpClientErrorException | HttpServerErrorException httpClientOrServerExc) {
if(HttpStatus.NOT_FOUND.equals(httpClientOrServerExc.getStatusCode())) {
// your handling of "NOT FOUND" here
// e.g. throw new RuntimeException("Your Error Message here", httpClientOrServerExc);
}
else {
// your handling of other errors here
}
The org.springframework.web.client.HttpServerErrorException
is added here for the errors with a 50x
.
Now you´re able to simple react to all the StatusCodes you want - except the appropriate one, that matches your HTTP method - like GET
and 200
, which won´t be handled as exception, as it is the matching one. But this should be straight forward, if you´re implementing/consuming RESTful services :)
Solution 3
If you want all the HTTPStatus from a RestTemplate including 4XX and 5XX, you will have to provide an ResponseErrorHandler to the restTemplate, since the default handler will throw an exception in case of 4XX or 5XX
We could do something like that :
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public boolean hasError(HttpStatus statusCode) {
return false;
}
});
ResponseEntity<YourResponse> responseEntity =
restTemplate.getForEntity("http://your.url.here", YourResponse.class);
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.XXXX);
Solution 4
private RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(url,HttpMethod.GET, requestEntity,String.class);
response contains 'body', 'headers' and 'statusCode'
to get statusCode : response.getStatusCode();
Solution 5
exchange(...) works but if you want less code, you can use
org.springframework.boot.test.web.client.TestRestTemplate.getForEntity(...)
which returns an Entity containing StatusCode. Change your example code to this:
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
HttpStatus statusCode = response.getStatusCode();
To test it you can use this snippet from my unit test:
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
assertResponseHeaderIsCorrect(response, HttpStatus.OK);
/**
* Test the basics of the response, non-null, status expected, etc...
*/
private void assertResponseHeaderIsCorrect(ResponseEntity<String> response, HttpStatus expectedStatus) {
assertThat(response).isNotNull();
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON_UTF8);
assertThat(response.getStatusCode()).isEqualTo(expectedStatus);
}
john
Updated on July 08, 2022Comments
-
john almost 2 years
I am using
RestTemplate
to make an HTTP call to our service which returns a simple JSON response. I don't need to parse that JSON at all. I just need to return whatever I am getting back from that service.So I am mapping that to
String.class
and returning the actualJSON response
as a string.RestTemplate restTemplate = new RestTemplate(); String response = restTemplate.getForObject(url, String.class); return response;
Now the question is -
I am trying to extract
HTTP Status codes
after hitting the URL. How can I extract HTTP Status code from the above code? Do I need to make any change into that in the way I doing it currently?Update:-
This is what I have tried and I am able to get the response back and status code as well. But do I always need to set
HttpHeaders
andEntity
object like below I am doing it?RestTemplate restTemplate = new RestTemplate(); //and do I need this JSON media type for my use case? HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); //set my entity HttpEntity<Object> entity = new HttpEntity<Object>(headers); ResponseEntity<String> out = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); System.out.println(out.getBody()); System.out.println(out.getStatusCode());
Couple of question - Do I need to have
MediaType.APPLICATION_JSON
as I am just making a call to url which returns a response back, it can return either JSON or XML or simple string.