RestTemplate.postForObject возвращает значение NULL, когда возвращаются ResponseEntity и Http Error. - PullRequest
0 голосов
/ 20 марта 2019

Я вызываю бэкэнд-сервис для возврата объекта PersonResponse:

PersonResponse response = restTemplate.postForObject(url, request, PersonResponse.class);

Класс PersonResponse содержит поле «status», указывающее, успешно ли информация о человеке получена из бэкэнда:

 public class PersonResponse {
    private String name;
    private String address;
    private ResponseStatus status;
     ......
 }

 public class ResponseStatus {
    private String errorCode;
    private String errorMessage;
     ......
 }

Итак, когда ответ был успешно получен (http 200), я смог получить ответ типа PersonResponse.Однако, когда произошла ошибка (400 или 500), серверная часть все равно возвращала бы мне PersonResponse, но только поле «status» заполняется информацией об ошибке, вот как серверная часть возвращала мне ответ:

 backend code:

 PersonResponse errResp = .....; // set the status field with error info
 return new ResponseEntity<PersonResponse>(errResp, HttpStatus.INTERNAL_SERVER_ERROR); 

Но мой звонок ниже дал мне нулевой ответ, хотя он должен дать мне PersonResponse с информацией об ошибке.Может кто-нибудь сообщить мне, почему это так?

try {
PersonResponse response = restTemplate.postForObject(url, request, PersonResponse.class);
} catch (HttpStatusCodeException se) {
  log.debug(se.getResponseBodyAsString()); 
  // I was able to see the error information stored in PersonResponse in the log
}        
return response;  // always null when 500 error is thrown by the backend

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Пожалуйста, прочитайте ниже:

По умолчанию RestTemplate выбросит один из этих exceptions в случае ошибки HTTP:

HttpClientErrorException

- в случаеHTTP статус 4xx

HttpServerErrorException

- в случае HTTP статус 5xx

UnknownHttpStatusCodeException

- в случае неизвестный HTTP status

Все эти exceptions являются расширениями RestClientResponseException.

Теперь, поскольку ваш сервер отвечает 5xx (500 в вашем случае), таким образом, для вашего клиента RestTemplateэто HttpServerErrorException.

Кроме того, response, который вы получаете со статусом HTTP 500 (INTERNAL SERVER ERROR), RestTemplate не будет отображать / десериализовать обратно с POJO, поскольку это неболее успешный (HTTP 200) ответ, даже если бэкэнд обернул код ошибки и сообщение в статус.

Поэтому всегда null в вашем случае.

Теперь на основе ваших потребностей, которые япредположим, что из исходного сообщения, даже в статусе 4xx или 5xx, вы хотите вернуть ResponseEntity.Это можно реализовать для соответствующего catch блока, например:

try {
PersonResponse response = restTemplate.postForObject(url, request, PersonResponse.class);
} catch (HttpStatusCodeException se) {
  log.debug(se.getResponseBodyAsString()); 
  // I was able to see the error information stored in PersonResponse in the log
// Here you have to implement to map the error with PersonResponse 
 ResponseStatus  errorStatus = new ResponseStatus();
 errorStatus.setErrorCode(HTTP500);
 errorStatus.setErrorMessage(YOURMESSAGEFROMERROR);
 PersonResponse  responseObject = new PersonResponse();
 responseObject.setResponseStatus(errorStatus);
 return new ResponseEntity<PersonResponse>(responseObject,HTTPStatus.200Or500); // you can design as you need 200 or 500
 } catch (HttpClientErrorException ex){
   //same way for HTTP 4xx 
}

Также есть другие способы, такие как this : где вы используете SpringExceptionHandler и централизованно в Handler вы решаете, как реагировать наваш клиент, если вы получите 4xx или 5xx из бэкэнда.И, наконец, все зависит от того, как вы проектируете свою систему, поскольку вы сказали, что не имеете никакого контроля над бэкендом, тогда вам нужно реализовать что-то на своем клиенте на основе ответов бэкэнда.

Надеюсь, это поможет.

0 голосов
/ 20 марта 2019

Вы должны обработать HttpClientErrorException, а также попытаться изменить оператор возврата услуг на ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errResp)

...