You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于条件构建FailSafe.dev RetryPolicy——Spring WebClient空响应重试编译问题

解决方法

1. 先把WebClient的响应解析成目标DTO

得先让WebClient把接口返回的JSON转换成你定义的DTO类(比如叫ApiResponse,里面有getData()方法),而不是直接返回ClientResponse。示例代码:

Mono<ApiResponse> fetchApiResponse() {
    return webClient.get()
        .uri("/你要调用的API路径")
        .retrieve()
        .bodyToMono(ApiResponse.class); // 把响应解析成DTO
}

2. 用Failsafe适配Reactive流(推荐)

如果你用的是Reactive模式(Mono/Flux),得引入failsafe-reactor依赖,这样Failsafe能直接处理Reactive类型,不用强制block:

// 构建重试策略,指定泛型为你的DTO类型
RetryPolicy<ApiResponse> retryPolicy = RetryPolicy.<ApiResponse>builder()
    // 判断数据是否为空,注意还要处理null的情况
    .handleResultIf(response -> response.getData() == null || response.getData().isEmpty())
    .withDelay(Duration.ofSeconds(2))
    .withMaxAttempts(5)
    .build();

// 用Failsafe的Reactor适配器处理Mono
Mono<ApiResponse> result = Failsafe.with(retryPolicy)
    .with(reactorScheduler())
    .getMono(this::fetchApiResponse);

3. 同步场景下的处理(不推荐在Reactive项目里用)

要是你非要用同步的get()方法,那就得把Mono block成具体的DTO实例,这样Failsafe拿到的就是能调用getData()的对象了:

RetryPolicy<ApiResponse> retryPolicy = RetryPolicy.<ApiResponse>builder()
    .handleResultIf(response -> response.getData().isEmpty())
    .withDelay(Duration.ofSeconds(2))
    .withMaxAttempts(5)
    .build();

ApiResponse result = Failsafe.with(retryPolicy)
    .get(() -> fetchApiResponse().block()); // block获取DTO对象

额外提醒

  • 要确保你的ApiResponse类和接口返回的JSON结构完全匹配,不然解析出来的getData()可能还是空或者报错。
  • 如果接口返回的是HTTP 204(无内容),WebClient解析时会抛出WebClientResponseException,这种情况要在重试策略里加上.handle(WebClientResponseException.class),再额外判断是否是204状态码来决定要不要重试。

内容的提问来源于stack exchange,提问作者Yi Qian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 21:15:16