java - Spring Webflux Mono : unable to collect the results as List

标签 java stream spring-webflux

我正在使用 spring webflux 来使用另一个服务,并尝试将结果聚合到不同输入组合的列表中。 但卡在一个点上,我无法订阅并将结果转换为列表

  1. 此方法将获取一个映射并迭代该映射,并使用不同的输入组合调用另一个服务。
    但无法继续 getAPrice() 来完成我想要的:(

    输入:

     public Mono<List<APrice>> getAPrice() {
            return
                    Mono.create(monoSink ->{
                         getActiveMonths()
                                .entrySet().stream()
                                .flatMap(e->getContractPrice(e.getKey(),e.getValue())
                                /* stuck here, don't have any idea how to subccribe and get the AP Object and collect it as a list */
                    });
        } 
    

    输出:

    expected : List[APrice]    
    
  2. 上面的 getAPrice() 调用下面的方法,该方法工作正常并返回有效输入组合的数据

    输入:

     /*Method is Working fine and returns a Mono<APrice> for the right input combination */
    public Mono<APrice> getContractPrice(String key, String value){
        return Mono.create(monoSink ->{
            acServiceWebClient.getPrice(key,value) 
                    .subscribe(aPrice ->  monoSink.success(aPrice),
                            error->{
                                monoSink.error(error);
                            });
        });
    }
    

    输出:

    {
    "id": 11,
    "curveName": "NT",
    "Month": "Mar 2010",
    "price": 160.17,
    "status": "ACTIVE"
    }
    
    private Map<String,String> getActiveMonths()
    {
        Map hm = new HashMap();
        hm.put("key1","value1")
        hm.put("key2","value2")
        return hm;
    }

期待得到一些建议,以更好的方式完成 getAPrice(),如果我遵循错误的方法,这也将有助于纠正我。谢谢

最佳答案

你实际上并不需要 MonoSink为了你的工作。你能做的就是创建一个 Flux来自您的getActiveMonths entrySet然后调用方法getActivePrice与此entrySetkey & value 。所以,你的getAPrice实际上应该看起来像

public Mono<List<APrice>> getAPrice() {

    return Flux.fromIterable(getActiveMonths().entrySet())
        .flatMap(entry -> getContractPrice(entry.getKey(), entry.getValue())).collectList();
}

简单地创建 Flux 有两个原因这里。

  1. 您没有理由以编程方式创建序列(主要用于 MonoSinkFluxSink)。您已经拥有数据,只需使用它,无需任何操作。

  2. 您实际上有一个集合,并且您想要使用它的每个条目,这使其成为 Flux 的良好候选者。 (0-n 个元素)而不是 Mono (0-1 个元素)。

引用这个官方Project Reactor文档使我的观点更加清晰并证明了我的观点。

如果getContractPrice返回Mono<List<APrice>> ?方法如下getAPrice应该看看

public Mono<List<APrice>> getAPrice() {

    return Flux.fromIterable(getActiveMonths().entrySet())
        .flatMap(entry -> getContractPrice(entry.getKey(), entry.getValue()))
        .flatMapIterable(aPrices -> aPrices).collectList();
}

关于java - Spring Webflux Mono : unable to collect the results as List,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58635969/

相关文章:

c# - 为什么 WCF 流响应在写入磁盘时损坏?

java - WebClient 的 bodyToMono 错误

java - ctrl-shift-T 并不总是在 eclipse neon 中打开类型

java - 测试是否对返回 Void 的方法内的变量调用了方法

java - 是否可以调用绝对函数在 TYPE_FORWARD_ONLY 结果集中向前移动行?

java - 如何重试Spring WebClient根据响应重试操作?

java - Spring Security 5.1.5 与 WebFlux 用户禁用不起作用

java - 在 Java 中完全卸载 JDBC 驱动程序

wcf - 如何使用流?将流转换为我从客户端接收到的字节

C++ fstream 在 .txt 文件上总是失败