我如何在Spring webflux / webclient中有条件地链接webclient调用

时间:2019-10-23 15:01:04

标签: java spring spring-webflux

我正在尝试使用WebClient实现以下方案。使用RestTemplate琐碎,但是我不能再这样做了。

使用伪Java代码的Spring控制器的相关部分:

Mono<T1> t1 = webClient.get()...retrieve()...;
Mono<T2> t2;

if (t1.getResult().getValue() > 0) {
    t2 = webClient.get().buildUsing(t1.getResult().getValue())...retrieve()...);
} else {
    t2 = Mono.empty();
}

return(Mono.zip(t1, t2, mergeFunction));

我不是在问如何使用Webflux。我还可以自己添加错误处理。我的问题是,如果第一个呼叫成功,如何将数据传递给第二个呼叫,以及在何处合并两个呼叫的结果,其中一个可能发生也可能不发生。如果我可以使用RestTemplate,那么这项任务绝对是微不足道的。

有一个标题非常相似的问题,但未得到回答。

2 个答案:

答案 0 :(得分:2)

我认为zipWhen非常适合此目的。 zipWhen等待第一个单声道的结果,然后将两个结果合并为Tuple2

WebClient.builder().baseUrl("https://jsonplaceholder.typicode.com/todos/1")
    .build()
    .get()
    .retrieve()
    .bodyToMono(User.class)
    .zipWhen(r -> {
      if (r.getId() == 1) {
        return  WebClient.builder().baseUrl("https://jsonplaceholder.typicode.com/todos/2")
            .build()
            .get()
            .retrieve()
            .bodyToMono(User.class);
      } else {
        return Mono.empty();
      }
    });

结果是Mono<Tuple2<T, T2>>同时包含两个值。

答案 1 :(得分:0)

据我所知,这是我对此的反应性解决方案:

 private static Mono<String> mono() {
    Mono<Integer> t1 = Mono.just(0);

    return t1.flatMap(outerResult -> outerResult > 0
        ? Mono.just("VALUE").map(innerResult -> outerResult + "" + innerResult)
        : Mono.just(outerResult.toString())
    );
}

那么这是怎么回事:

使用.flatMap,您可以订阅新的Mono并获取结果。 在.flatMap的lambda中,您仍然可以得到t1的结果,因此,如果需要订阅,可以在.map上使用t2,也可以执行任何操作需要处理t1的结果以使其达到所需的返回值。