可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 actual JSON 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
and Entity
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.
回答1:
Use the RestTemplate#exchange(..)
methods that return a ResponseEntity
. This gives you access to the status line and headers (and the body obviously).
回答2:
RestTemplate.get/postForObject...
methods behind like me and dislike to fiddle around with the boilerplate stuff needed when using RestTemplate.exchange...
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
.
GET
and 200
回答3:
There can be some slightly trickier use cases someone might fall in (as I did). Consider the following:
Supporting a Page object in order to use it with RestTemplate and ParameterizedTypeReference:
RestPageResponse:
import java.util.ArrayList; import java.util.List; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; public class RestResponsePage<T> extends PageImpl<T>{ private static final long serialVersionUID = 3248189030448292002L; public RestResponsePage(List<T> content, Pageable pageable, long total) { super(content, pageable, total); } public RestResponsePage(List<T> content) { super(content); } public RestResponsePage() { super(new ArrayList<T>()); } }
Using ParameterizedTypeReference
will yield the following:
ParameterizedTypeReference<RestResponsePage<MyObject>> responseType = new ParameterizedTypeReference<RestResponsePage<MyObject>>() {}; HttpEntity<RestResponsePage<MyObject>> response = restTemplate.exchange(oauthUrl, HttpMethod.GET, entity, responseType);
Calling #exchange:
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity<?> entity = new HttpEntity<>(headers); response = restTemplate.exchange("localhost:8080/example", HttpMethod.GET, entity, responseType);
Now here is the "tricky" part.
Trying to call exchange's getStatusCode
will be impossible because the compiler, unfortunately, will be unaware of the "intended" type of response
.
That is because generics are implemented via type erasure which removes all information regarding generic types during compilation (read more - source)
((ResponseEntity<RestResponsePage<MyObject>>) response).getStatusCode()
In this case, you have to explicitly cast the variable to the desired Class to get the statusCode
(and/or other attributes)!
回答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();