Java 如何从对 URL 的 RestTemplate 调用中提取 HTTP 状态代码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23205213/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to extract HTTP status code from the RestTemplate call to a URL?
提问by john
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.
我正在使用RestTemplate
HTTP 调用我们的服务,它返回一个简单的 JSON 响应。我根本不需要解析那个 JSON。我只需要归还我从该服务中得到的任何东西。
So I am mapping that to String.class
and returning the actual JSON response
as a string.
所以我将它映射到String.class
并将实际JSON response
作为字符串返回。
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?
我试图HTTP Status codes
在点击 URL 后提取。如何从上述代码中提取 HTTP 状态代码?我是否需要以目前的方式对其进行任何更改?
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?
这是我尝试过的,我也能够得到响应和状态代码。但是我是否总是需要像下面那样设置HttpHeaders
和Entity
反对我正在做的事情?
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.
几个问题 - 我是否需要拥有,MediaType.APPLICATION_JSON
因为我只是调用 url 返回响应,它可以返回 JSON 或 XML 或简单的字符串。
采纳答案by Sotirios Delimanolis
Use the RestTemplate#exchange(..)
methods that return a ResponseEntity
. This gives you access to the status line and headers (and the body obviously).
使用RestTemplate#exchange(..)
返回 a的方法ResponseEntity
。这使您可以访问状态行和标题(显然还有正文)。
回答by Menelaos Kotsollaris
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 RestTemplateand ParameterizedTypeReference:
支持 Page 对象以便将其与RestTemplate和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
将产生以下结果:
ParameterizedTypeReference<RestResponsePage<MyObject>> responseType =
new ParameterizedTypeReference<RestResponsePage<MyObject>>() {};
HttpEntity<RestResponsePage<MyObject>> response = restTemplate.exchange(oauthUrl, HttpMethod.GET, entity, responseType);
Calling #exchange:
调用#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
.
尝试调用 exchangegetStatusCode
是不可能的,因为不幸的是,编译器将不知道“预期”类型的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()
((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)!
在这种情况下,您必须显式地将变量强制转换为所需的类以获取statusCode
(和/或其他属性)!
回答by jonashackt
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.
如果你不想像RestTemplate.get/postForObject...
我一样留下围绕方法的漂亮抽象,并且不想在使用RestTemplate.exchange...
(请求和响应实体、HttpHeaders 等)时摆弄所需的样板文件,还有另一个选项可以访问 HttpStatus代码。
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:
只需RestTemplate.get/postForObject...
用 try/catch for org.springframework.web.client.HttpClientErrorException
and包围通常org.springframework.web.client.HttpServerErrorException
,就像在这个例子中一样:
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
.
在org.springframework.web.client.HttpServerErrorException
此添加了一个错误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 :)
现在你可以对所有你想要的 StatusCode 做出简单的反应——除了合适的,匹配你的 HTTP 方法——比如GET
and 200
,它不会作为异常处理,因为它是匹配的。但这应该是直截了当的,如果您正在实施/使用 RESTful 服务:)
回答by santosh kumar
private RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(url,HttpMethod.GET, requestEntity,String.class);
response contains 'body', 'headers' and 'statusCode'
响应包含“body”、“headers”和“statusCode”
to get statusCode : response.getStatusCode();
获取 statusCode : response.getStatusCode();
回答by LazR
exchange(...) works but if you want less code, you can use
exchange(...) 有效,但如果你想要更少的代码,你可以使用
org.springframework.boot.test.web.client.TestRestTemplate.getForEntity(...)
org.springframework.boot.test.web.client.TestRestTemplate.getForEntity(...)
which returns an Entity containing StatusCode. Change your example code to this:
它返回一个包含 StatusCode 的实体。将您的示例代码更改为:
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);
}
回答by Subha Mukherjee
Putting this much of code is enough for me
HttpStatus statusCode = ((ResponseEntity<Object>) responseOfEsoft).getStatusCode();
放这么多代码对我来说已经足够了
HttpStatus statusCode = ((ResponseEntity<Object>) responseOfEsoft).getStatusCode();
回答by Matthieu Gabin
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
如果您想要来自 RestTemplate 的所有 HTTPStatus,包括 4XX 和 5XX,则必须向 restTemplate 提供 ResponseErrorHandler,因为默认处理程序将在 4XX 或 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);
回答by El Fadel Anas
You can use this solution
您可以使用此解决方案
RestTemplate restTemplate = new RestTemplate();
final String baseUrl = "http://www.myexampleurl.com";
URI uri = new URI(baseUrl);
ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class);
//get status code
int statuCode = result.getStatusCodeValue();