简体   繁体   English

抛出 RestClientException 时如何检索 HTTP 状态代码和响应正文?

[英]How do I retrieve HTTP status code and response body when an RestClientException is thrown?

The methods of RestTemplate such as postForEntity() throw RestClientException . RestTemplate的方法如postForEntity()抛出RestClientException I would like to extract the HTTP status code and response body from that exception object in the catch block.我想从 catch 块中的异常对象中提取 HTTP 状态代码和响应正文。 How can I do that?我怎样才能做到这一点?

Instead of catching RestClientException , catch the special HttpClientErrorException .不是捕获RestClientException ,而是捕获特殊的HttpClientErrorException

Here's an example:下面是一个例子:

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 provides getStatusCode and getResponseBodyAsByteArray to get the status code and body, respectively. HttpClientErrorException提供了getStatusCodegetResponseBodyAsByteArray分别获取状态码和正文。

Catch RestClientResponseException instead.改为捕获RestClientResponseException It's more generic.它更通用。

From the docs : Common base class for exceptions that contain actual HTTP response data.来自文档:包含实际 HTTP 响应数据的异常的通用基类。

In some cases, HttpClientErrorException is not thrown.在某些情况下,不会抛出HttpClientErrorException For example the following method restTemplate.exchange call:例如下面的方法restTemplate.exchange调用:

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

Gets the http body and marshalls it to an Entity.获取 http 主体并将其编组到实体。 If remote resource returns a rare error, internal marshall does not work and just a RestClientException is thrown.如果远程资源返回一个罕见的错误,内部编组不起作用,只会抛出一个RestClientException

restTemplate.setErrorHandler restTemplate.setErrorHandler

In this case or if you want to handle any error in restTemplate operations, you could use setErrorHandler .在这种情况下,或者如果您想处理restTemplate操作中的任何错误,您可以使用setErrorHandler This method receives a basic ResponseErrorHandler with helpful methods.这个方法接收一个基本的ResponseErrorHandler和有用的方法。

This method hasError allowed me to get the remote http body text and helped me to detect the error of the invocation or in the remote http remote resource:这个方法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
  }
});

Also, you can manually evaluate the body or status and return true or false in order to flag as error or not.此外,您可以手动评估正文或状态并返回 true 或 false 以标记为错误与否。

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;
    }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我只在使用 Java HTTP 客户端时得到 HTTP 响应状态码 451? - Why do I get HTTP Response Status Code 451 only when using the Java HTTP Client? 在WebFlux WebClient中测试状态代码时如何获取响应体? - How to get response body when testing the status code in WebFlux WebClient? 在测试时,如何获取泽西/ dropwizard响应的状态代码和响应标头? - How do I get the status code & response headers of a jersey/dropwizard response, when testing? 当响应具有HTTP错误状态代码时,为什么会出现“只允许一个连接接收订户”? - Why do I get `Only one connection receive subscriber allowed` when the response has an HTTP error status code? 当 HTTP 请求返回状态为 401 时,如何在 Java 中解析响应正文 - How to parse the response body in Java, when the HTTP request has return status 401 如何设置HTTP响应的服务器状态代码? - how to set the server status code for http response? 如果 HTTP 状态码是 WebApplicationException 的子类,如何验证它? - How do I verify the HTTP status code if it is a subclass of WebApplicationException? 如何从RestTemplate读取HTTP状态代码? - How do I read HTTP status code from RestTemplate? Spring Webclient:如何在http状态码为200时获取正文错误 - Spring Webclient : How to get the body on error when the http status code is 200 RestClientException客户端显示用于Spring Client身份验证的空响应正文 - RestClientException client shows empty response body for Spring Client authentication
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM