[英]How to pass upstream error response to downstream service using RestTemplate
我无法处理从一个微服务到另一个微服务的错误响应。 假设服务 A 调用服务 B。B返回:
{
"timestamp": "2020-04-18T13:02:30.543+0000",
"status": 404,
"error": "Not Found",
"message": "Cannot find product with productId = 1",
"path": "/products/quantity/1"
}
作为ResponseEntity
中的主体。 我必须在 A 中获取相同的响应消息、状态和错误。我正在使用RestTemplate
从 A 调用 B。
我试过了
public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
return (clientHttpResponse.getStatusCode().series() == CLIENT_ERROR ||
clientHttpResponse.getStatusCode().series() == SERVER_ERROR
);
}
@Override
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
if(clientHttpResponse.getStatusCode().series() == CLIENT_ERROR) {
HttpStatus httpStatus = clientHttpResponse.getStatusCode();
}
else if(clientHttpResponse.getStatusCode().series() == SERVER_ERROR) {
throw new RecordNotFoundException("Record Not found");
}
}
但在这里我只能获得ResponseCode
而不是包含错误和消息的整个ResponseBody
。
您的错误处理程序应如下所示:
public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
return (clientHttpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR
|| clientHttpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR);
}
@Override
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
HttpStatus statusCode = clientHttpResponse.getStatusCode();
switch (statusCode.series()) {
// handle client errors. Throw HttpClientErrorException
// ex.getResponseBodyAsString();
case CLIENT_ERROR:
HttpClientErrorException ex = new HttpClientErrorException(statusCode,
clientHttpResponse.getStatusText(), clientHttpResponse.getHeaders(),
this.getResponseBody(clientHttpResponse), this.getCharset(clientHttpResponse));
throw ex;
case SERVER_ERROR:
// handle server errors, may be the same as client errors, by throwing
// HttpServerErrorException
break;
default:
// default behavior for other errors
throw new RestClientException("Some Exception message");
}
}
private Charset getCharset(ClientHttpResponse response) {
HttpHeaders headers = response.getHeaders();
MediaType contentType = headers.getContentType();
return contentType != null ? contentType.getCharset() : null;
}
private byte[] getResponseBody(ClientHttpResponse response) {
byte[] result = new byte[0];
try {
// this is org.springframework.util.FileCopyUtils class
result = FileCopyUtils.copyToByteArray(response.getBody());
} catch (IOException var3) {
// Handle I/O exception
}
return result;
}
}
然后捕获异常并通过 getResponseBodyAsString() 方法获得响应。
但是,如果您没有公开 REST 服务,我认为您可能会返回状态码为 200 的应用程序逻辑错误。为所有具有以下字段的响应创建一个基本 class:errorCode、errorMessage、errorCause(例如)。 通过您的 REST 响应类扩展它。 如果一切正常 - 返回带有 errorCode 0 的常规响应。但是如果您在处理请求时遇到错误,请返回带有一些 errorCode(不是 0)的响应,并填写 errorMessage 和 errorCause 字段。 这不是“最佳实践”,但有时可能对您来说很全面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.