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

Spring Boot WebFlux中如何实现两个WebClient请求按顺序执行

Spring Boot WebFlux 双WebClient顺序执行解决方案

该问题的本质是响应式编程的声明式特性:独立定义的两个WebClient请求如果没有组装到同一条响应式流中,订阅后会异步并行执行,不会等待前序请求完成。你可以通过flatMap操作符串联两个请求逻辑,确保第一个请求完成、拿到映射后的POJO后,再触发第二个请求。


错误写法示例(会触发并行执行)

以下写法会导致第二个请求提前触发,拿到的账户数据为null:

// 错误:两个请求逻辑独立声明,无依赖关系
Mono<Account> accountReq = firstWebClient.get()
  .uri("/get/account")
  .retrieve()
  .bodyToMono(Account.class);

// 第二个请求没有依赖第一个的执行结果,订阅后会直接触发
Mono<Result> secondReq = secondWebClient.post()
  .uri("/submit/data")
  .bodyValue(new Account()) // 此时第一个请求还没返回,拿不到实际数据
  .retrieve()
  .bodyToMono(Result.class);

正确写法(顺序执行)

用flatMap操作符将两个请求组装为同一条响应式流:

public Mono<Result> runSequentialRequest() {
    return firstWebClient.get()
            .uri("https://first-api.com/account")
            .retrieve()
            // WebClient默认内置ObjectMapper,可直接反序列化为指定POJO,无需手动调用ObjectMapper
            .bodyToMono(Account.class)
            // 只有上一步拿到非空的Account对象后,才会触发第二个WebClient请求
            .flatMap(account -> secondWebClient.post()
                    .uri("https://second-api.com/submit")
                    .bodyValue(account)
                    .retrieve()
                    .bodyToMono(Result.class));
}

如果需要手动调用ObjectMapper做自定义反序列化,可在中间增加map操作符处理:

public Mono<Result> runSequentialRequestWithCustomMapper() {
    return firstWebClient.get()
            .uri("https://first-api.com/account")
            .retrieve()
            .bodyToMono(String.class)
            // 手动反序列化,该步骤完成后才会进入下一步flatMap
            .map(rawResp -> objectMapper.readValue(rawResp, Account.class))
            .flatMap(account -> secondWebClient.post()
                    .uri("https://second-api.com/submit")
                    .bodyValue(account)
                    .retrieve()
                    .bodyToMono(Result.class));
}

注意事项

  • 全程不要调用block()方法阻塞线程,会破坏响应式非阻塞特性,组装完成的Mono/Flux直接返回给Spring框架,由框架负责订阅执行即可。
  • 如果第一个接口有概率返回空响应,可在bodyToMono后增加switchIfEmpty(Mono.error(new IllegalArgumentException("未获取到有效账户数据")))主动抛出异常,避免非法参数传入第二个请求。
  • 可分别在两个请求的retrieve后增加onErrorResume等操作符自定义异常降级逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:57:03