HttpClientErrorException 400 null在MicroServices中使用RestTemplate

时间:2018-08-07 15:02:14

标签: java spring rest spring-mvc

我有两个微服务。第一个从前端接收呼叫,然后调用第二个uService接收一些数据。最后一个返回错误响应(错误请求,可以,这是一个用例)。但是,我丢失了第二个微服务返回的正文(消息),因为第一个微服务在调用中抛出HttpClientErrorException 400 null

这是我的代码:

ResponseEntity<MyEntity> entityResponse = restTemplate.getForEntity(url, MyEntity.class, id);

由于抛出异常,我无法执行entityResponse.getStatusCode()

在ControllerAdvice中对其进行处理,即使我从服务返回了自定义消息,我的异常消息也为“ 400 null”。

因此,我想在被调用的uservice中发送响应消息来进行管理。

谢谢。

3 个答案:

答案 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 javadocHttpClient Maven artifact。到目前为止,鲜为人知但更简单的HTTPClient(由我编写的开源MgntUtils库的一部分):MgntUtils HttpClient javadocMgntUtils maven artifactMgntUtils Github。使用这些库中的任何一个,您都可以独立于Spring发送REST请求并接收响应,作为业务逻辑的一部分