返回ResponseEntity和Http错误时,RestTemplate.postForObject返回Null

时间:2019-03-19 21:28:07

标签: java spring-boot http httpresponse resttemplate

我调用后端服务以获取PersonResponse对象:

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

PersonResponse类包含一个“状态”字段,用于指示是否成功从后端检索了一个人的信息:

 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 个答案:

答案 0 :(得分:1)

请阅读以下内容:

默认情况下,如果发生RestTemplate错误,exceptions将抛出其中一个HTTP

HttpClientErrorException

–在HTTP状态为4xx的情况下

HttpServerErrorException

–对于HTTP状态5xx

UnknownHttpStatusCodeException

–处于未知 HTTP状态

所有这些exceptionsRestClientResponseException的扩展。

现在,由于您的后端响应为5xx(在您的情况下为500),因此对于您的客户RestTemplate,它是HttpServerErrorException

此外,您收到的response状态为HTTP 500 (INTERNAL SERVER ERROR)RestTemplate不会通过POJO映射/反序列化,因为它不再是成功(HTTP 200)响应,即使后端将errorCode和消息包装在状态中。

因此,在您的情况下,始终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则如何从客户端进行响应。 最后,这完全取决于您对系统的设计方式,因为您说您无法控制后端,因此您必须根据后端响应在客户端上实现事情。

希望这会有所帮助。

答案 1 :(得分:0)

您应该处理HttpClientErrorException,并尝试将服务返回语句更改为ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errResp)