Spring Boot 如何忽略 HttpStatus 异常

Posted

技术标签:

【中文标题】Spring Boot 如何忽略 HttpStatus 异常【英文标题】:Spring Boot how to ignore HttpStatus Exceptions 【发布时间】:2015-12-28 09:49:15 【问题描述】:

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

我的一个底层服务与数据库交互并以请求的数据进行响应。如果向不存在的 ID 发出请求,我会以 404 HttpStatus 响应:

return new ResponseEntity<>(HttpStatus.NOT_FOUND);

(与某些操作的 400 错误或删除条目等的 204 相同)。

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

我该如何解决这个问题?

对服务的调用在我的代码中是这样实现的:ResponseEntity&lt;Object&gt; data = restTemplate.getForEntity(url, Object.class);

我的 RestTemplate 是这样设置的:

private RestTemplate restTemplate = new RestTemplate();

【问题讨论】:

【参考方案1】:

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

您可以将RestTemplateResponseErrorHandler 设置为带有javadoc 状态的RestTemplate#setErrorHandler(ResponseErrorHandler)

默认情况下,RestTemplate 使用 DefaultResponseErrorHandler

这个默认实现

[...] 检查状态码 ClientHttpResponse: 任何带系列的代码 HttpStatus.Series.CLIENT_ERRORHttpStatus.Series.SERVER_ERROR 是 被认为是一个错误。可以通过覆盖来更改此行为 hasError(HttpStatus) 方法。

如果发生错误,它会抛出您看到的异常。

如果您想更改此行为,您可以提供自己的 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
    
);

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

【讨论】:

以上是关于Spring Boot 如何忽略 HttpStatus 异常的主要内容,如果未能解决你的问题,请参考以下文章

如何忽略 spring-boot-cassandra 默认配置来加载 cassandra 连接实例

Spring Boot 如何忽略 HttpStatus 异常

如何在 Spring Boot 应用程序中禁用/忽略 @PreAuthorize

仅在 XML 中忽略字段,但在 Spring Boot(xml 映射器)中不忽略 json

Spring Boot 休息忽略一类

Spring Boot 忽略 ObjectMapper 模块