39

throwRestTemplate等方法。我想从 catch 块中的异常对象中提取 HTTP 状态代码和响应正文。我怎样才能做到这一点?postForEntity()RestClientException

4

4 回答 4

63

与其抓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分别提供getStatusCodegetResponseBodyAsByteArray获取状态码和正文。

于 2013-10-18T20:45:24.960 回答
6

RestClientResponseException而是抓住。它更通用。

来自文档:包含实际 HTTP 响应数据的异常的通用基类。

于 2019-08-14T06:20:43.547 回答
1

在某些情况下,不会抛出HttpClientErrorException 。例如下面的方法restTemplate.exchange调用:

ResponseEntity<Employee[]> employees =  restTemplate.exchange(url, HttpMethod.GET, entity, Employee[].class);

获取 http 正文并将其编组到实体。如果远程资源返回一个罕见的错误,则内部编组不起作用,只会抛出RestClientException

restTemplate.setErrorHandler

在这种情况下,或者如果您想处理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 以标记为错误与否。

于 2019-03-04T15:52:45.257 回答
-1
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;
    }
 }
于 2020-11-13T21:17:31.147 回答