基于条件构建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
相关产品推荐
相关产品推荐

