英文:
Spring Webflux - How to aggregate three Flux objects into 1 using Tuple3
问题
我正在尝试使用Tuple3将3个Flux对象聚合成一个,但我仍然卡住了。我在网上搜索到可以使用Mono.zip(),但这不适用于Flux。
public class OrderService {
private final AppWebClient appWebClient;
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Flux<Map<String, List<String>>> fluxOne = this.appWebClient.getFluxOne(orderNoList1);
Flux<Map<String, String>> fluxTwo = this.appWebClient.getFluxTwo(orderNoList2);
Flux<Map<String, List<String>>> fluxThree = this.appWebClient.getFluxThree(orderNoList3);
return Mono.zip(fluxOne, fluxTwo, fluxThree).map(this::combine); //error here
}
private OrderDetailsAggregate combine(
Tuple3<Flux<Map<String, List<String>>>, Flux<Map<String, String>>, Flux<Map<String, List<String>>> > tuple) {
return OrderDetailsAggregate.create(tuple.getT1(), tuple.getT2(), tuple.getT3());
}
}
fluxOne,fluxTwo,fluxThree有不同的数据类型。
OrderDetailsAggregate 类
@Data
@ToString
@AllArgsConstructor(staticName = "create")
public class OrderDetailsAggregate {
private Flux<Map<String, List<String>>> fluxOne;
private Flux<Map<String, String>> fluxTwo;
private Flux<Map<String, List<String>>> fluxThree;
}
如何将它们组合起来?
谢谢。
英文:
I am trying to aggregate 3 Flux objects into 1 using Tuple3
However, I am still stuck. I searched online and saw that you can use Mono.zip() but that doesn't apply to Flux.
public class OrderService {
private final AppWebClient appWebClient;
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Flux<Map<String, List<String>>> fluxOne = this.appWebClient.getFluxOne(orderNoList1);
Flux<Map<String, String>> fluxTwo = this.appWebClient.getFluxTwo(orderNoList2);
Flux<Map<String, List<String>>> fluxThree = this.appWebClient.getFluxThree(orderNoList3);
return Mono.zip(fluxOne, fluxTwo, fluxThree).map(this::combine); //error here
}
private OrderDetailsAggregate combine(
Tuple3< Flux<Map<String, List<String>>>, Flux<Map<String, String>>, Flux<Map<String, List<String>>> > tuple) {
return OrderDetailsAggregate.create(tuple.getT1(), tuple.getT2(), tuple.getT3());
}
}
fluxOne, fluxTwo, fluxThree have different data types.
OrderDetailsAggregate class
@Data
@ToString
@AllArgsConstructor(staticName = "create")
public class OrderDetailsAggregate {
private Flux<Map<String, List<String>>> fluxOne;
private Flux<Map<String, String>> fluxTwo;
private Flux<Map<String, List<String>>> fluxThree;
}
How do I combine them?
Thank you.
答案1
得分: 1
如果您需要从getAggregatedOrderDetails方法返回Mono<OrderDetailsAggregate>,那么为什么不只是创建Mono对象而不使用zip:
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Flux<Map<String, List<String>>> fluxOne = this.appWebClient.getFluxOne(orderNoList1);
Flux<Map<String, String>> fluxTwo = this.appWebClient.getFluxTwo(orderNoList2);
Flux<Map<String, List<String>>> fluxThree = this.appWebClient.getFluxThree(orderNoList3);
OrderDetailsAggregate aggregate = OrderDetailsAggregate.create(fluxOne, fluxTwo, fluxThree);
return Mono.just(aggregate);
}
英文:
If you need to return Mono<OrderDetailsAggregate> from getAggregatedOrderDetails method, then why not just create Mono object without zip:
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Flux<Map<String, List<String>>> fluxOne = this.appWebClient.getFluxOne(orderNoList1);
Flux<Map<String, String>> fluxTwo = this.appWebClient.getFluxTwo(orderNoList2);
Flux<Map<String, List<String>>> fluxThree = this.appWebClient.getFluxThree(orderNoList3);
OrderDetailsAggregate aggregate = OrderDetailsAggregate.create(fluxOne, fluxTwo, fluxThree);
return Mono.just(aggregate);
}
答案2
得分: 1
对我来看,你似乎是将appWebClient返回的Flux视为Mono的方式来处理。
我猜你想要在OrderDetailsAggregate中获取所有Flux的值。如果是这样的话,我建议将Flux收集到Mono中,使用Mono.zip获得一个元组,然后将其映射到你的OrderDetailsAggregate:
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Mono<Map<String, List<String>>> monoOne = this.appWebClient.getFluxOne(orderNoList1).collect(HashMap::new, Map::putAll);
Mono<Map<String, String>> monoTwo = this.appWebClient.getFluxTwo(orderNoList2).collect(HashMap::new, Map::putAll);
Mono<Map<String, List<String>>> monoThree = this.appWebClient.getFluxThree(orderNoList3).collect(HashMap::new, Map::putAll);
return Mono.zip(monoOne, monoTwo, monoThree).map(tuple -> OrderDetailsAggregate.create(tuple.getT1(), tuple.getT2(), tuple.getT3()));
}
如果你只关心Flux中的一个值,那么你可以用next()替代collect()。
编辑:我看到你正在向create()方法传递Flux。所以这个答案只适用于如果你也更改了那个方法。如果你的OrderDetailsAggregate是一个DTO而不是一个服务,那么也许最好不要在其中包含Flux逻辑,而是在getAggregatedOrderDetails方法中执行。
英文:
To me it looks like you are treating the Flux'es your appWebClient is returning as if they were Mono's.
I assume, you want to have all values of the fluxes in your OrderDetailsAggregate. Should that be the case, I would suggest to collect the Flux into a Mono, do a Mono.zip to get a tuple and map that to your OrderDetailsAggregate:
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Mono<Map<String, List<String>>> monoOne = this.appWebClient.getFluxOne(orderNoList1).collect(HashMap::new, Map::putAll);
Mono<Map<String, String>> monoTwo = this.appWebClient.getFluxTwo(orderNoList2).collect(HashMap::new, Map::putAll);
Mono<Map<String, List<String>>> monoThree = this.appWebClient.getFluxThree(orderNoList3).collect(HashMap::new, Map::putAll);
return Mono.zip(monoOne, monoTwo, monoThree).map(tuple -> OrderDetailsAggregate.create(tuple.getT1(), tuple.getT2(), tuple.getT3()));
}
Should you just care about one value from the flux, then you can replace the collect() with next().
Edit: I see you are passing Flux to your create() method. So this answer only applies if you would change that as well. If your OrderDetailsAggregate is a Dto and not a service, then it would perhaps be a good idea to not have that flux logic in there but rather do it in the getAggregatedOrderDetails method.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论