首页 > 解决方案 > 从 Webflux 的 GET 操作内部对外部休息服务进行 Get 和 PUT 调用

问题描述

我们使用 WebFlux 在 rest 服务中公开了一个 GET 操作。在此 GET 操作中,如果单独调用外部 Rest 服务的 GET(或 SET)操作,则一切正常。但是,如果我们尝试在同一个操作中合并这两个调用,那么代码将失败,它不会对后端服务进行任何调用。从 GET 控制器操作调用的服务操作中使用的示例代码是:

公共无效句柄地址(映射句柄地址请求){元组4> serviceConnectionDetails = commerceConnectorHelper .prepareDataForCheckOutCart(handleAddressRequest);

  serviceConnectionDetails._3
             .get() 
             .uri(CartRequestTranslator.getAddressDetailsEndPoint(serviceConnectionDetails._1, serviceConnectionDetails._2, serviceConnectionDetails._4.get(ServiceOperation.GET_USER_ADDRESSES))) 
             .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML) 
             .retrieve() 
             .bodyToMono(MonoAddressModel.class)
             .map(add -> add.getAddresses())
             .flatMapMany(Flux::fromIterable).filter(defaultAddress -> defaultAddress.isDefaultAddress())
             .flatMap(obj -> {

                 System.out.println("Address default is "+obj.getId());

                 serviceConnectionDetails._3
                 .put()
                 .uri(CartRequestTranslator.putAddressDetailsEndPoint(serviceConnectionDetails._1, serviceConnectionDetails._2, serviceConnectionDetails._4.get(ServiceOperation.GET_USER_ADDRESSES), obj.getId()))
                 .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
                 .exchange()
                 .flatMap(test -> test.bodyToMono(String.class));

                 //returning a dummy flux object
                 return Flux.just("sdsdsd");
             });

   return ;

}

如果你们中的任何人都可以在这里分享任何输入,那就太好了。

标签: springspring-bootreactive-programmingspring-webfluxproject-reactor

解决方案


如反应器参考文档中所述,在您订阅之前不会发生任何事情

在您的代码片段中,put 操作返回的 Publisher 未链接到管道中,因此没有任何内容会订阅它。

大大简化您的代码片段以清除细节,它应该看起来更像这样:

Mono<Void> result = webClient
    .get().uri(uri).retrieve()
    .bodyToMono(MonoAddressModel.class)
    .map(model -> model.getAddress())
    .flatMap(address -> {
         return webClient.get().uri(address)
                    .exchange()
                    .then();
    });

如果更复杂的设置(例如您的代码段)不起作用,我会建议几件事:

  • 尝试在方法中重新组合操作;很容易推理出每个步骤都有明确类型的小函数
  • 尝试log()在管道中的多个位置添加运算符;也许过滤器运算符没有很好地实现,您实际上是在过滤所有值。

推荐阅读