简体   繁体   中英

RestTemplate.postForObject Returns Null When ResponseEntity and Http Error Are Returned

I call a backend service to get back a PersonResponse object:

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

The PersonResponse class contains a "status" field to indicate if a person's info is successfully retrieved from the backend :

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

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

So when the response was retrieved successfully (http 200), I was able to get back a response of type PersonResponse. However, when there was an error (400 or 500), backend would still return me a PersonResponse, but only the "status" field is populated with the error information, this is how backend returned me the response:

 backend code:

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

But my call below returned me a null response, although it should gave me a PersonResponse with the error information. Can someone let me know why is that?

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

Please read below :

By default, the RestTemplate will throw one of these exceptions in case of an HTTP error:

HttpClientErrorException

– in case of HTTP status 4xx

HttpServerErrorException

– in case of HTTP status 5xx

UnknownHttpStatusCodeException

– in case of an unknown HTTP status

All these exceptions are extensions of RestClientResponseException .

Now, since your back end is responding with 5xx (500 in your case) , thus for your client RestTemplate it is a HttpServerErrorException .

Further, the response you're receiving with HTTP 500 (INTERNAL SERVER ERROR) status, RestTemplate will not map/de-serialize back with the POJO as it is no more a success ( HTTP 200 ) response, even though backend wrapped the errorCode and message in status.

Therefore, always null in your case.

Now based on your need which I suppose from your original post, even in 4xx or 5xx status you want to return ResponseEntity. This you can implement for respective catch block like :

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 
}

Also, there are other ways like this : where you use SpringExceptionHandler and centrally in Handler you decide how to respond from your client if you recieve 4xx or 5xx from backend. And at the end it all depends on how you're desiging your system, since you said you have no control on backend then you have to implement things at your client based on backend responses.

Hope this helps.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM