我有两个微服务。第一个从前端接收呼叫,然后调用第二个uService接收一些数据。最后一个返回错误响应(错误请求,可以,这是一个用例)。但是,我丢失了第二个微服务返回的正文(消息),因为第一个微服务在调用中抛出HttpClientErrorException 400 null
这是我的代码:
ResponseEntity<MyEntity> entityResponse = restTemplate.getForEntity(url, MyEntity.class, id);
由于抛出异常,我无法执行entityResponse.getStatusCode()
。
在ControllerAdvice中对其进行处理,即使我从服务返回了自定义消息,我的异常消息也为“ 400 null”。
因此,我想在被调用的uservice中发送响应消息来进行管理。
谢谢。
答案 0 :(得分:0)
我在项目中正在做的事情如下。
MicroService_2调用MicroService_1。
MicroService_1
如果未找到该实体,则MicroService_1例如返回HTTP 404异常。
@RestController
@RequestMapping(value = "/api/v1/")
public class Service1Controller {
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public @ResponseBody MyEntity getMyEntity(@PathVariable String id) throws NotFoundException {
MyEntity result = ...
if(result == null) {
throw new NotFoundException("MyEntity [id: "+id+"] not found");
}
return result;
}
@ControllerAdvice
public class RestEndpointExceptionHandler extends RestExceptionHandler {
@ExceptionHandler(NotFoundException.class)
public ResponseEntity<String> handleNotFoundException(HttpServletRequest req, NotFoundException ex) throws NotFoundException {
return new ResponseEntity<String>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
}
}
MicroService_2
MicroService_2调用MicroService_1并通过HTTP代码捕获异常并重新生成NotFoundException
。
@Override
public MyEntity getMyEntity(Principal principal) {
try {
ResponseEntity<MyEntity> entityResponse = restTemplate.getForEntity(url, MyEntity.class, id);
return entityResponse.getBody();
} catch(HttpClientErrorException e) {
HttpStatus status = e.getStatusCode();
if (status == HttpStatus.NOT_FOUND) {
throw new NotFoundException(e.getResponseBodyAsString()); // should be "MyEntity [id: {id}] not found"
} else {
throw new UnexpectedServerException(e.getResponseBodyAsString());
}
}
}
答案 1 :(得分:0)
如果状态代码为500或400,则弹簧RestTemplate
会引发错误。因此,如果您的第二个服务响应错误,则第一个服务中的RestTemplate调用将引发异常。
HttpClientErrorException
:如果HTTP状态为4xx HttpServerErrorException
:如果HTTP状态为5xx UnknownHttpStatusCodeException
:在HTTP状态未知的情况下要获取响应消息,您可以捕获异常。例如:
try {
ResponseEntity<MyEntity> entityResponse = restTemplate.getForEntity(url, MyEntity.class, id);
} catch(HttpStatusCodeException e) {
// e.getResponseBodyAsString();
}
或定义一个ResponseErrorHandler
。可以在ResponseErrorHandler
的实例化期间设置RestTemplate
。在handleError
方法中,您还可以访问响应消息。
@Override
public void handleError(ClientHttpResponse httpResponse)
throws IOException {
}
答案 2 :(得分:0)
这里的答案解释了如何捕获异常和访问正文是正确的。但是,您可以使用其他方法。您可以使用3D方库来发送Http请求并处理响应。其中一种著名的产品是Apache commons HTTPClient:HttpClient javadoc,HttpClient Maven artifact。到目前为止,鲜为人知但更简单的HTTPClient(由我编写的开源MgntUtils库的一部分):MgntUtils HttpClient javadoc,MgntUtils maven artifact,MgntUtils Github。使用这些库中的任何一个,您都可以独立于Spring发送REST请求并接收响应,作为业务逻辑的一部分