在客户端服务器中处理来自 API 服务器的异常

handle Exceptions from API server in client server

我正在尝试学习如何处理 APIs 服务器中的异常,所以我跟随 this 他为鸟类构建 API 的地方,他最终达到了 API是这样的:

@GetMapping(value = "/params")
public Bird getBirdRequestParam(@RequestParam("birdId") Long birdId) throws EntityNotFoundException {
    Bird bird = birdRepository.findOne(birdId);
    if(bird == null){
        throw new EntityNotFoundException(Bird.class, "id", birdId.toString());
    }
    return bird;
}

并且 ControllerAdvice 有一个方法:

@ExceptionHandler(EntityNotFoundException.class)
protected ResponseEntity<Object> handleEntityNotFound(
        EntityNotFoundException ex) {
    ApiError apiError = new ApiError(NOT_FOUND);
    apiError.setMessage(ex.getMessage());
    return buildResponseEntity(apiError);
}

响应将是这样的鸟

{
"id": 1,
"scientificName": "Atlantic canary",
"specie": "serinus canaria",
"mass": 10,
"length": 11
}

或这样的异常详细信息:

{
"apierror": {
    "status": "NOT_FOUND",
    "timestamp": "09-04-2018 10:11:44",
    "message": "Bird was not found for parameters {id=2}"
}

但问题出在与 API

联系的服务器上

我正在使用:

public void gett(@RequestParam Long id) {
    ResponseEntity<Bird> responseEntity = restTemplate.getForEntity("http://localhost:8181/params" + id, Bird.class);
    bird = responseEntity.getBody();
    model.addAttribute("birdform", bird);
    return "bird";
}

getForEntity 正在等待带有鸟体的响应,但服务器可能会抛出异常,响应可能是 json 的错误。

如何在我的客户端服务器中处理这个问题?

换句话说:

如何在我的客户端服务器中知道 api 服务器抛出了 json 形式的异常。???

我尝试在“Object”变量中获取响应,然后尝试了解它是异常还是带有“instance of”表达式的 bird,就像这段代码

@GetMapping("/getbird")
public String getAll(@RequestParam Long id, Model model) {
    ResponseEntity<Object> responseEntity = restTemplate.getForEntity("http://localhost:8181/api/bird/getone?id=" + id, Object.class);
    if (responseEntity.getBody() instanceof Bird.class) {
        Bird bird= (Bird) responseEntity.getBody();
        model.addAttribute("Bird", bird);
        return "bird-form";
    }
    else{
        // something else
        return "someview";
    }
}

但首先它不起作用(总是 return false 的实例)

第二件事是,我的所有控制器的操作都是一项艰巨的工作。

我希望我能把我的问题解释清楚。

谢谢....

您不需要检查响应正文来查看是否有错误。如果您收到 4XX 响应,restTemplate.getForEntity()(和其他方法)将抛出 HttpClientErrorException,如果您从调用中收到 5XX 响应,则 HttpServerErrorException

要捕获这些异常,您可以使用适当的异常处理方法定义@ControllerAdvice

@ControllerAdvice
class GlobalControllerExceptionHandler {
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)  // 500
    @ExceptionHandler(HttpClientErrorException.class)
    public ApiError handle4xxFromClient(HttpClientErrorException ex) {
        // construct and return a custom ApiError object
    }
}

详情见https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

两种解决方案:

  1. 在您的 reste 模板中使用自定义实现错误处理程序。 restTemplate.setErrorHandler(customerErrorHandler)

  2. 使用 http status,如果从正在查询的服务器获得 错误的 http 状态 ,rest 模板将抛出异常。捕获异常并从异常中获取 ApiError 对象,然后抛出您自己的异常,该异常将由您的客户端服务器中的异常处理程序处理。

要使这些解决方案起作用,您正在查询的服务器需要在发生错误时发送正确的 HTTP 状态代码。