当前位置: 首页 > 知识库问答 >
问题:

Spring WebClient-如何处理身体Rest的错误

胡鸿禧
2023-03-14

我是一个穿Spring靴的新手,我需要你的帮助。

我使用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状态之前一切正常。如果出现问题(即坏请求),我会收到相同的正文JSON结构,如下所示:

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

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

更新:根据Seelenvirtuose的建议,我将错误添加到类中

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

} 

共有1个答案

梁烨烨
2023-03-14

我自己遇到了这个问题,必须将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"));
     }
  })
)
 类似资料:
  • 问题内容: 我们正在进行有关如何处理REST异常的持续讨论。 响应内容类型:JSON 我们有两种解决方案: 将所有未检查的异常作为JSON响应抛出。 发送请求无效响应代码。 参数: 当出现错误时,为什么要返回JSON?只需发送无效的响应码即可。 相反的观点: 对于普通开发人员而言,响应代码的技术性太强。 你怎么说? 问题答案: 对于JSON API,我最近开发了两者。我总是使用有效的JSON进行响

  • 问题内容: 在REST控制器中同时使用 @ControllerAdvice 和 @Valid 批注时,遇到了麻烦。 我有一个声明如下的rest控制器: 还有一个ErrorHandler类: 问题是,如果我在 RestExample.add* 方法中添加 “引发新的RuntimeException” ,则该异常由 RestErrorHandler 类正确处理。 *** 但是,当向控制器卷曲无效请求时

  • 我正在尝试在javascript中自定义一个可以通过REST调用访问的endpoint。此终结点处理与不同情况相关的多个条件(基本上它生成一次性密码,然后验证它以检查它是否过期等)。 所以基本上结构是这样的: 我在开始时设置了一个对象,然后映射一个json消息,以便检索具有不同代码/消息响应的正文。因此,当终结点输入这些条件时,它将返回对象,并且 Header 始终为 200(调用成功)。像这样:

  • 我正在开发一个仅支持iPhone的iOS 8应用程序。我想只支持iPhone 4S的纵向模式设备。 我有一个图形设计,它采用全屏内容。我使用自动布局来处理视图,并使其适用于所有屏幕。但是,我使用一个小资产来管理从iPhone4S工作的设计。当我在iPhone6S/6看到它时,内容非常小,大量额外的空间被浪费了。 当设备分辨率变大时,我想增加字体大小、图像大小。这个应用程序中有很多屏幕。 例如,我在

  • 问题内容: 我试图弄清楚如何使用boto3进行正确的错误处理。 我正在尝试创建一个IAM用户: 成功调用create_user后,我得到一个整洁的对象,其中包含API调用的http状态代码和新创建的用户的数据。 例: 这很好。但是,如果失败(例如用户已经存在),我只会得到一个类型为botocore.exceptions.ClientError的对象,其中只有文本可以告诉我出了什么问题。 示例:Cl

  • 问题内容: 如何处理此调用上的etimedout错误? 有没有办法等待更长的时间?还是再次请求远程文件? 究竟是什么会导致此错误?仅超时? 问题答案: 这是由于在给定时间内未收到您的请求响应(通过 请求模块选项)引起的。 基本上首先要捕获该错误,您需要在上注册一个处理程序,因此不会再抛出未处理的错误:。这里还有一些解释。 在处理程序中,您可以检查错误是否为ETIMEDOUT并应用自己的逻辑:。 如