java Webflux合并两个下游调用的结果(并忽略失败)

inb24sb2  于 2023-02-14  发布在  Java
关注(0)|答案(1)|浏览(175)

我知道我的问题已经被问过很多次了,但我觉得仍然没有令人满意的答案。
基本上我有两个下游服务,我想调用(并行),然后我想组合结果并返回它(作为Json)。两个调用都可能失败,但两个结果都不是强制的,所以空的组合响应也是可能的:

class FirstResponse {...}
class SecondResponse {...}
class CombinedResponse {
   private FirstResponse first;
   private SecondResponse second;
}
class FirstService {
   Mono<FirstResponse> get(){ 
      return webclient.get(...)
        .bodyToMono(FirstResponse.class)
        .onErrorResume(throwable -> Mono.empty);
   }
}
class SecondService {
   Mono<SecondResponse> get(){ 
      return webclient.get(...)
        .bodyToMono(SecondResponse.class)
        .onErrorResume(throwable -> Mono.empty);
   }
}
@RestController(...)
class CombinationController {
   @GetMapping(...)
   Mono<CombinedResponse> getCombined() {
      Mono.zip(firstService.get(), secondService.get(), (first, second) -> {
          return new CombinedResponse(first, second);
      })
   }
}

现在,如果调用firstService失败,secondService的响应也会被忽略,但我实际上希望CombinedResponse仍然得到(部分填充)。
作为一个免责声明,我必须说,我目前正在从rxjava1迁移我的代码,在那里,如果发生下游错误,我只返回Single.just(null)。这允许我压缩两个结果,并只将值设置为null

mwg9r5ms

mwg9r5ms1#

关于Mono.zip()
任何信号源的错误或空完成将导致其他信号源被取消,并分别导致产生的Mono立即错误或完成。
另外,reactor不允许null值,所以你应该在你的情况下做一些变通。在一些简单的情况下,很容易定义一些默认值以防出错(例如,空String),但对于自定义类型,创建一个空对象会很奇怪。
作为这种情况的替代方案,我建议使用Optional,不过这个解决方案增加了一些样板代码。
首次服务:

class FirstService {
   Mono<Optional<FirstResponse>> get(){ 
      return webclient.get(...)
        .bodyToMono(FirstResponse.class)
        .map(Optional::of)
        .onErrorReturn(Optional.empty());
   }
}

第二次服务:

class SecondService {
   Mono<Optional<SecondResponse>> get(){ 
      return webclient.get(...)
        .bodyToMono(SecondResponse.class)
        .map(Optional::of)
        .onErrorReturn(Optional.empty());
   }
}

和“组合器”:

@GetMapping(...)
Mono<CombinedResponse> getCombined() {
    Mono.zip(firstService.get(), secondService.get())
            .map(tuple -> {
                // check optionals here from tuple.getT1() and tuple.getT2()
                // and do whatever you want 
            })
            ...
}

相关问题