使用spring boot来休息webservices异常处理

时间:2017-05-16 15:05:32

标签: java spring rest spring-boot

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

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

  1. 出现错误(响应4xx / 5xx),然后反序列化错误DTO并抛出已检查的异常(需要在使用该库的应用程序中处理)
  2. 在正常情况下,只需反序列化预期的DTO对象并返回。
  3. 我试图通过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块中?)错误响应需要映射到自定义异常(也可以抛出IOException)

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

    有什么想法?提前谢谢

1 个答案:

答案 0 :(得分:0)

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

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

我也遇到过这种情况。虽然只有客户端库将被其他人使用。因此REST API对他们来说是隐藏的。虽然我通过ControllerAdvice处理已知的异常并且总是返回一个像这样的对象 int code; String message; Object payload;  显然,HTTP代码总是200(OK)。

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