Как получить код состояния HTTP и тело ответа при возникновении RestClientException?

Методы RestTemplate, такие как postForEntity() throw RestClientException. Я хотел бы извлечь код состояния HTTP и тело ответа из этого объекта исключения в блоке catch. Как я могу это сделать?


person Vathanak    schedule 23.09.2012    source источник


Ответы (4)


Вместо того, чтобы ловить 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, чтобы получить код состояния и тело соответственно.

person Community    schedule 18.10.2013
comment
Я отредактировал ваш ответ, чтобы добавить еще несколько полезных деталей и сделать этот вопрос/ответ более полезным в качестве канонических. - person Sotirios Delimanolis; 29.07.2016
comment
более общий HttpStatusCodeException наследуется HttpClientErrorException и HttpServerErrorException. - person Dariush Jafari; 15.02.2018
comment
Если вы поймаете HttpStatusCodeException, у вас будет доступ к методу getResponseBodyAsString(). - person Nikhil Sahu; 16.11.2018
comment
Что мне не хватает в этом ответе? Если вы вызываете метод, который возвращает RestClientException, вы не можете просто волшебным образом привести его к HttpClientErrorException, верно? - person IcedDante; 14.06.2019
comment
Большое спасибо! Отличный ответ, как раз то, что мне нужно! - person atom88; 06.11.2020

Вместо этого поймайте RestClientResponseException. Это более общее.

Из документов : общий базовый класс для исключений, содержащих фактические данные ответа HTTP.

person Emmanuel Osimosu    schedule 14.08.2019
comment
Однако перехват этого исключения работает, я предпочел HttpClientErrorException, потому что вы можете получить как тело ответа, так и полный объект/перечисление HttpStatus с соответствующим сообщением. Пример: вы можете получить код 404 вместе с описанием «Не найдено» при использовании другого. - person atom88; 06.11.2020

В некоторых случаях 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, чтобы пометить как ошибку или нет.

person JRichardsz    schedule 04.03.2019

person    schedule
comment
Пожалуйста, не публикуйте только код в качестве ответа, но также объясните, что делает ваш код и как он решает проблему вопроса. Ответы с объяснением, как правило, более полезны и качественны, и с большей вероятностью привлекут положительные голоса. - person Pouria Hemati; 14.11.2020