【问题标题】:Spring WebClient - How to handle the errors on the body RestSpring WebClient - 如何处理主体 Rest 上的错误
【发布时间】:2021-09-25 19:46:21
【问题描述】:

我是 Spring Boot 新手,需要您的帮助。

我使用 WebClient 发出 GET 请求,我收到如下 JSON 正文:

{
    "status": "OK",
    "error": [],
    "payload": {
        "name": "John",
        "surname": "Doe"
...
    }
}

所以我有一个 DTO 类来映射响应。像这样的:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseAccountDTO {
    
    private String status;
    private List<ErrorDTO> errors;
    private User payload;

}

我用这个方法做的:

public ResponseUserDTO retrieveUserById(String userId) {
    return webClient.get()
        .uri(GET_USER_BY_ID_V4, accountId)
        .header("Auth-Schema", AUTH_SCHEMA)
        .header("apikey", API_KEY)
        .accept(MediaType.APPLICATION_JSON)
        .retrieve()
        .onStatus(HttpStatus::is4xxClientError, response -> {
            System.out.println("4xx error");
            return Mono.error(new RuntimeException("4xx"));
        })
        .onStatus(HttpStatus::is5xxServerError, response -> {
            System.out.println("5xx error");
            return Mono.error(new RuntimeException("5xx"));
        })
        .bodyToMono(ResponseDTO.class)
        .block();
}

最后我用这个方法测试一下:

UserRestClient userRestClient = new UserRestClient(webClient);

@Test
void retrieveUser() {
    ResponseDTO response = userRestClient.retrieveUserById("123");
    UserDTO user = response.getPayload();
    System.out.println("user surname: " + user.surname);
    assertEquals("Doe", user.getSurname());
}

一切正常,直到响应具有 KO 状态。如果出现问题(即 BAD REQUEST),我会收到相同的正文 JSON 结构,如下所示:

{
    "status": "KO",
    "errors": [
        {
            "code": "ER000",
            "description": "Wrong ID parameter",
            "params": ""
        }
    ],
    "payload": {}
}

有没有办法将我的 DTO 类上的 JSON 主体也与 KO 状态一起映射? 我想在我的 retrieveUser() 方法上返回错误描述。

更新: 我按照 Seelenvirtuose 的建议添加了我的 ErrorDTO 类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ErrorDTO {
    
    private String code;
    private String description;
    private String params;

} 

【问题讨论】:

  • 您的 DTO 类似乎能够容纳整个 JSON 结构(如果 ErrorDTO 设计良好)。你有什么问题?
  • 嗨 Seelen,我刚刚添加了我的课程 ErrorDTO 代码。问题是当我收到错误时,它会出现在这里.onStatus(HttpStatus::is4xxClientError, response -&gt; {
  • 我真的不明白。这段代码有什么问题?请添加任何错误或任何可能适合您的问题的问题描述。如果您不想对错误状态做出反应,那么就不要调用onStatus 方法。
  • 如果我不调用 onStatus 则会引发错误并且永远不会到达方法的结尾,因此我的 ErrorDTO 中没有数据
  • 抛出什么错误?

标签: java json error-handling spring-webclient


【解决方案1】:

我自己也遇到了这个问题,不得不将 json 错误响应转换为 ErrorDTO 对象。

希望下面的代码可以帮助您找到所需的内容。

以下代码可以应用于任何状态代码(例如 4xx、5xx 甚至 2xx,但您不需要 2xx)

.onStatus(HttpStatus::is4xxClientError, error -> error
  .bodyToMono(Map.class)
  .flatMap(body -> {      
     try {
         var message = objectMapper.writeValueAsString(body);
         ErrorDTO errorResponse = objectMapper.readValue(message, ErrorDTO.class);
         return Mono.error(new ServiceException(error.statusCode().value(), "My custom error message",                                                         errorResponse));
     } catch (JsonProcessingException jsonProcessingException) {
         return Mono.error(new ServiceException("Cannot parse the error response"));
     }
  })
)

【讨论】:

    猜你喜欢
    • 2020-06-03
    • 2021-08-06
    • 2019-12-04
    • 1970-01-01
    • 2018-07-08
    • 2020-09-17
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多