我正在使用Spring Boot构建一个应用程序。此应用程序是分布式的,这意味着我有多个相互调用的API。

我的基础服务之一与数据库进行交互,并以请求的数据进行响应。如果请求不存在的ID,我将返回404 HttpStatus:

return new ResponseEntity<>(HttpStatus.NOT_FOUND);

(与某些操作上的400错误相同,或对于删除条目而言为204等)。

问题是我有一些其他的Spring Boot应用程序调用这些API,当它们请求不存在的条目时,它们会在请求时抛出org.springframework.web.client.HttpClientErrorException: 404 Not Found Exception。但是404状态码是有意的,不应返回此异常(导致我的Hystrix断路器调用其后备功能)。

我怎么解决这个问题?

在我的代码中,对服务的调用是这样实现的:ResponseEntity<Object> data = restTemplate.getForEntity(url, Object.class);
我的RestTemplate设置如下:
private RestTemplate restTemplate = new RestTemplate();

最佳答案

Spring的 RestTemplate 使用ResponseErrorHandler处理响应中的错误。此接口(interface)提供了一种确定响应是否有错误的方法(ResponseErrorHandler#hasError(ClientHttpResponse))以及如何处理该错误的方法(ResponseErrorHandler#handleError(ClientHttpResponse))。

您可以使用其javadoc状态为 RestTemplate 设置ResponseErrorHandlerRestTemplate#setErrorHandler(ResponseErrorHandler)


此默认实现



如果发生错误,它将引发您所看到的异常。

如果要更改此行为,可以提供自己的ResponseErrorHandler实现(也许通过覆盖DefaultResponseErrorHandler),该实现不会将4xx视为错误或不会引发异常。

例如

restTemplate.setErrorHandler(new ResponseErrorHandler() {
    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return false; // or whatever you consider an error
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        // do nothing, or something
    }
});

然后,您可以检查ResponseEntity返回的getForEntity的状态码并自行处理。

10-04 18:55