java - 使用 spring boot 进行 rest webservices 异常处理

标签 java spring rest spring-boot

我正在使用 spring/spring-boot 开发 REST 客户端库和 REST 服务器。该库将用作其他应用程序的依赖项。

什么是处理错误的最佳方法,我考虑过在服务器端处理错误,例如使用 ControllerAdvice 将错误映射到错误 DTO 类。 在客户端(使用 RestTemplate )我想:

  1. 错误情况(响应 4xx/5xx),然后反序列化错误 DTO 并抛出已检查的异常(需要在使用该库的应用程序中处理)
  2. 在正常情况下,只需反序列化预期的 DTO 对象并返回。

我试图通过 ResponseErrorHandler 实现这一目标我提出了两个并不完全令我满意的解决方案,所以我想听听关于它们的意见或获得一些更好的建议:

想法 1:

    public List<SomeDTO> list() throws MyException {
    HttpHeaders headers = new HttpHeaders();
    headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
    HttpEntity<String> request = new HttpEntity<>(headers);
    ResponseEntity<String> response = restTemplate.exchange("endpoint/getAll", HttpMethod.GET, request, String.class);
    String responseBody = response.getBody();
    try {
        if (MyResponseErrorHandler.isError(response.getStatusCode())) {
            ErrorInfo error = objectMapper.readValue(responseBody, ErrorInfo.class);
            throw new MyException();
        } else {
            List<SomeDTO> SomeDTOs = Arrays.asList(objectMapper.readValue(responseBody));
            return SomeDTOs;
        }
    } catch (IOException e) {
        throw new MyException();
    }
}

但看起来每种方法都有很多样板文件。

想法 2 A

在 ResponseErrorHandler 中抛出自定义异常,需要是 Runtime 或 IOException,但在 IOException 的情况下被 ResourceAccessException 包裹。在客户端方法中,可以捕获异常并重新抛出另一个异常。但是在某个地方(在 catch block 中?)错误响应需要映射到自定义异常(什么也可以抛出 IOException)

想法 2 B 不要使用 ResponseErrorHandler,捕获 HttpClientErrorException,使用 getResponseBodyAsString 在 catch block 中从中获取响应主体,将其映射到自定义错误类型(捕获 IOException))

有什么想法吗?提前致谢

最佳答案

REST API 中返回错误的标准方式是 HTTP 代码。

但在这种情况下,您正在开发客户端库,因此您可以选择使其成为您自己的设计。

我也遇到过这种情况。虽然只有客户端库会被其他人使用。所以 REST API 对他们来说是隐藏的。虽然我通过 ControllerAdvice 处理了已知的异常,并且总是返回一个像这样的对象 整数代码; 字符串消息; 对象负载; 显然,HTTP 代码总是 200(OK)。

将响应代码作为 ENUM 的好处是可以获取我已处理的所有错误,包括在客户端中创建异常的特定消息,并且我也知道有效负载对象的特定类(对于成功的请求)。因此在客户端,那些返回代码 (ENUM) 使得从客户端抛出异常变得更容易。

关于java - 使用 spring boot 进行 rest webservices 异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44005156/

相关文章:

java - 通过java调用外部程序

java - 使用类路径在 java 中加载 CSV

java - 如何在 Spring Data Neo4J 3.0.0(发布版)中向节点添加第二个标签?

php - CakePHP RestFul WebService 正确的文档和可下载的代码

REST请求中基于python证书的身份验证

java - RestFul java with mongodb 如何添加@QueryParam

java - 为什么 pom.xml 的 modelVersion 是必需的并且始终设置为 4.0.0?

Selenium WebDriver 中的 JavascriptException

java - 如何查找 BindingResult 中的错误原因

java - Spring RestTemplate 不会使用超时设置