RestTemplate.postForObject Returns 返回ResponseEntity和Http错误时为空
RestTemplate.postForObject Returns Null When ResponseEntity and Http Error Are Returned
我调用后端服务取回 PersonResponse 对象:
PersonResponse response = restTemplate.postForObject(url, request, PersonResponse.class);
PersonResponse class 包含一个 "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)时,后端仍然 return 给我一个 PersonResponse,但只有 "status" 字段填充了错误信息,后端 return 就是这样给我回复:
backend code:
PersonResponse errResp = .....; // set the status field with error info
return new ResponseEntity<PersonResponse>(errResp, HttpStatus.INTERNAL_SERVER_ERROR);
但是我下面的调用 return 给我一个空响应,尽管它应该给我一个带有错误信息的 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
您应该处理 HttpClientErrorException
并尝试将您的服务 return 语句更改为 ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errResp)
请阅读以下内容:
默认情况下,RestTemplate
将在 HTTP
错误的情况下抛出其中之一 exceptions
:
HttpClientErrorException
– 如果是 HTTP
状态 4xx
HttpServerErrorException
– 如果是 HTTP
状态 5xx
UnknownHttpStatusCodeException
– 在 未知 HTTP
状态
的情况下
所有这些exceptions
都是RestClientResponseException
的扩展。
现在,由于您的后端正在响应 5xx(在您的情况下为 500),因此对于您的客户 RestTemplate
它是 HttpServerErrorException
.
此外,您收到的 response
状态为 HTTP 500
(INTERNAL SERVER ERROR)
,RestTemplate
不会 map/de-serialize 返回 POJO,因为它不是更多的是成功 (HTTP 200
) 响应,即使后端将错误代码和消息包装在状态中。
因此,在你的情况下总是null
。
现在根据您的需要,我认为您的原始 post,即使在 4xx 或 5xx 状态下您也想要 return 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 的地方,如果您从后端收到 4xx 或 5xx,则在 Handler 中集中决定如何从客户端响应。
最后这一切都取决于你如何设计你的系统,因为你说你无法控制后端然后你必须根据后端响应在你的客户端实现东西。
希望对您有所帮助。
我调用后端服务取回 PersonResponse 对象:
PersonResponse response = restTemplate.postForObject(url, request, PersonResponse.class);
PersonResponse class 包含一个 "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)时,后端仍然 return 给我一个 PersonResponse,但只有 "status" 字段填充了错误信息,后端 return 就是这样给我回复:
backend code:
PersonResponse errResp = .....; // set the status field with error info
return new ResponseEntity<PersonResponse>(errResp, HttpStatus.INTERNAL_SERVER_ERROR);
但是我下面的调用 return 给我一个空响应,尽管它应该给我一个带有错误信息的 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
您应该处理 HttpClientErrorException
并尝试将您的服务 return 语句更改为 ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errResp)
请阅读以下内容:
默认情况下,RestTemplate
将在 HTTP
错误的情况下抛出其中之一 exceptions
:
HttpClientErrorException
– 如果是 HTTP
状态 4xx
HttpServerErrorException
– 如果是 HTTP
状态 5xx
UnknownHttpStatusCodeException
– 在 未知 HTTP
状态
所有这些exceptions
都是RestClientResponseException
的扩展。
现在,由于您的后端正在响应 5xx(在您的情况下为 500),因此对于您的客户 RestTemplate
它是 HttpServerErrorException
.
此外,您收到的 response
状态为 HTTP 500
(INTERNAL SERVER ERROR)
,RestTemplate
不会 map/de-serialize 返回 POJO,因为它不是更多的是成功 (HTTP 200
) 响应,即使后端将错误代码和消息包装在状态中。
因此,在你的情况下总是null
。
现在根据您的需要,我认为您的原始 post,即使在 4xx 或 5xx 状态下您也想要 return 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 的地方,如果您从后端收到 4xx 或 5xx,则在 Handler 中集中决定如何从客户端响应。 最后这一切都取决于你如何设计你的系统,因为你说你无法控制后端然后你必须根据后端响应在你的客户端实现东西。
希望对您有所帮助。