RestTemplate
的方法(例如 postForEntity()
)会抛出 RestClientException
。我想在 catch 块中从该异常对象中提取 HTTP 状态码和响应体。我应该怎么做?
RestTemplate
的方法(例如 postForEntity()
)会抛出 RestClientException
。我想在 catch 块中从该异常对象中提取 HTTP 状态码和响应体。我应该怎么做?
不要捕获 RestClientException
,而是捕获特殊的 HttpClientErrorException
。
以下是一个示例:
try {
Link dataCenterLink = serviceInstance.getLink("dataCenter");
String dataCenterUrl = dataCenterLink.getHref();
DataCenterResource dataCenter =
restTemplate.getForObject(dataCenterUrl, DataCenterResource.class);
serviceInstance.setDataCenter(dataCenter);
} catch (HttpClientErrorException e) {
HttpStatus status = e.getStatusCode();
if (status != HttpStatus.NOT_FOUND) { throw e; }
}
HttpClientErrorException
提供了 getStatusCode
和 getResponseBodyAsByteArray
方法,分别用于获取状态码和响应体。
应该捕获 RestClientResponseException
异常,因为它更加通用。
根据文档:这是一个包含实际 HTTP 响应数据的异常通用基类。
RestClientResponseException
包含响应头、响应体和状态码(HttpStatusCode
对象)。 - undefinedResponseEntity<Employee[]> employees = restTemplate.exchange(url, HttpMethod.GET, entity, Employee[].class);
restTemplate.setErrorHandler(new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse arg0) throws IOException {
System.out.println("StatusCode from remote http resource:"+arg0.getStatusCode());
System.out.println("RawStatusCode from remote http resource:"+arg0.getRawStatusCode());
System.out.println("StatusText from remote http resource:"+arg0.getStatusText());
String body = new BufferedReader(new InputStreamReader(arg0.getBody()))
.lines().collect(Collectors.joining("\n"));
System.out.println("Error body from remote http resource:"+body);
return false;
}
@Override
public void handleError(ClientHttpResponse arg0) throws IOException {
// do something
}
});
private void sendActivity(StatsActivity statsActivity) throws InterruptedException
{
LibraryConnectorXapiEditView libraryConnectorXapiEditView = (LibraryConnectorXapiEditView) workerBundle.getConnector();
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Statement statement = libraryConnectorConverter.convertActivityToStatement(statsActivity, workerBundle);
HttpEntity<Statement> request = new HttpEntity<>(statement, headers);
try
{
String lrsEndPoint = libraryConnectorXapiEditView.getLrsEndPoint() + "/statements";
ResponseEntity<String> response = restTemplate.exchange(lrsEndPoint, HttpMethod.POST, request, String.class);
ocnCompletionEventDao.save(this.convertToOcnCompletionEvent(statsActivity, response.getBody(), response.getStatusCodeValue()));
}
catch (HttpClientErrorException ex)
{
ocnCompletionEventDao.save(this.convertToOcnCompletionEvent(statsActivity, ex.getResponseBodyAsString(), ex.getStatusCode().value()));
checkResponse(ex, libraryConnectorXapiEditView);
if(failedAttempts<3)
{
sendActivity(statsActivity);
failedAttempts++;
}
}
}
private void checkResponse(HttpClientErrorException ex, LibraryConnectorXapiEditView libraryConnectorXapiEditView) throws InterruptedException
{
int statusCode = ex.getStatusCode().value();
int retryAfterSeconds = retryAfter(ex.getResponseHeaders());
switch (statusCode)
{
case 401:
headers = xApiAuthorizationUtils.getHeaders(libraryConnectorXapiEditView);
case 429:
if(retryAfterSeconds!=0)
Thread.sleep(retryAfterSeconds);
case 422:
failedAttempts=3;
}
}
HttpStatusCodeException
,它被HttpClientErrorException
和HttpServerErrorException
继承。 - Dariush JafariHttpStatusCodeException
异常,你就可以使用getResponseBodyAsString()
方法来获取响应体的字符串形式。 - Nikhil SahuHttpClientErrorException
只能捕获 4xx 状态码,但无法处理 5xx 状态码。应该使用RestClientResponseException
或者添加HttpServerErrorException
来处理 5xx 状态码。 - johnmweisz