RestTemplate
的方法,例如postForEntity()
抛出RestClientException
。我想从catch块中的异常对象中提取HTTP状态代码和响应主体。我怎么能这样做?
答案 0 :(得分:32)
不要抓住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
来获取状态代码和正文。
答案 1 :(得分:1)
在某些情况下,不会引发 HttpClientErrorException 。例如,以下方法 restTemplate.exchange :
ResponseEntity<Employee[]> employees = restTemplate.exchange(url, HttpMethod.GET, entity, Employee[].class);
获取http正文并将其编组为实体。如果远程资源返回一个罕见的错误,则内部编组将不起作用,并且只会抛出 RestClientException 。
在这种情况下,或者如果您想处理 restTemplate 操作中的任何错误,则可以使用 setErrorHandler 。此方法会接收带有帮助方法的基本 ResponseErrorHandler 。
此方法 hasError 允许我获取远程http正文文本,并帮助我检测调用的错误或远程http远程资源中的错误:
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
}
});
您还可以手动评估正文或状态,并返回true或false,以标记是否为错误。
答案 2 :(得分:1)
改为捕获RestClientResponseException
。更通用。
来自docs:常见基类,用于包含实际HTTP响应数据的异常。
答案 3 :(得分:0)
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;
}
}