Spring 2.0 WebFlux:将多个 Mono<String> (其中字符串是转换为字符串的 json)合并为单个 Flux<String>



我有三个单声道的JSON字符串,如下

Mono<String> strInventoryResp=invWebClient.get().
            uri("/findATSInventory?skuId="+skuId).
            exchange().flatMap(resp-> resp.bodyToMono(String.class));

    Mono<String> strProductResponse=productClient.get().
            uri("/v2/products/id/"+skuId).
            exchange().flatMap(resp-> resp.bodyToMono(String.class));

    Mono<String> strItemResp=productClient.get().
            uri("/v2/items?id="+skuId).
            exchange().flatMap(resp-> resp.bodyToMono(String.class));

我想将其合并到JSON字符串的通量中,这样结果也是JSON字符串。

我尝试了磁通静态方法,但是,显然它不会以JSON格式返回,如下所示

Flux.merge(strProductResponse,strItemResp,strInventoryResp);

如何返回组合的单声道响应的通量,以便在调用调用此方法的控制器时在浏览器中返回有效的JSON字符串流?

编辑:我的问题陈述是使用Web通量调用这三个API,并将结果组合为一个。控制器将调用此方法并返回UI的组合结果。有其他方法吗?

这就是我要解决的方式。

@Test
public void buildResponse() {
    final Mono<String> customerName = Mono.just("customer name");
    final Mono<String> customerPreference = Mono.just("customer preference");
    final Mono<String> cusomterShippingInformation = Mono.just("cusomter shipping information");
    final Mono<JsonObjectYouWantToReturn> returnThisAsAResponse = customerName
            .map(Builder::new)
            .zipWith(customerPreference)
            .map(t -> t.getT1().withCustomerPreference(t.getT2()))
            .zipWith(cusomterShippingInformation)
            .map(t -> t.getT1().withCustomerShippingInformation(t.getT2()))
            .map(Builder::build);
}
private class Builder {
    private String customerName;
    private String customerPreference;
    private String customerShippingInfo;
    public Builder(String customerName) {
        this.customerName = customerName;
    }
    public Builder withCustomerPreference(String customerPreference) {
        this.customerPreference = customerPreference;
        return this;
    }
    public Builder withCustomerShippingInformation(String t3) {
        this.customerShippingInfo = t3;
        return this;
    }

    public JsonObjectYouWantToReturn build() {
        return new JsonObjectYouWantToReturn(customerName, customerPreference, customerShippingInfo);
    }
}
private class JsonObjectYouWantToReturn {
    public final String customerName;
    public final String customerPreference;
    public final String customerShippingInfo;

    public JsonObjectYouWantToReturn(String customerName, String customerPreference, String customerShippingInfo) {
        this.customerName = customerName;
        this.customerPreference = customerPreference;
        this.customerShippingInfo = customerShippingInfo;
    }
}

诸如Piotr的另一个解决方案,但使用reduce,Lombok和不变的聚合器。

@Test
public void test() {
    Mono<String> strInventoryResp = Mono.just("strInventoryResp");
    Mono<String> strProductResponse = Mono.just("strProductResponse");
    Mono<String> strItemResp = Mono.just("strItemResp");
    Mono<Aggregator> result = Flux.merge(
            strInventoryResp.map(s -> Aggregator.builder().strInventoryResp(s).build()),
            strItemResp.map(s -> Aggregator.builder().strItemResp(s).build()),
            strProductResponse.map(s -> Aggregator.builder().strProductResponse(s).build()))
            .reduce((aggregator, aggregator2) -> aggregator.toBuilder()
                    .strInventoryResp(Optional.ofNullable(aggregator2.strInventoryResp)
                            .orElseGet(() -> aggregator.strInventoryResp))
                    .strProductResponse(Optional.ofNullable(aggregator2.strProductResponse)
                            .orElseGet(() -> aggregator.strProductResponse))
                    .strItemResp(Optional.ofNullable(aggregator2.strItemResp)
                            .orElseGet(() -> aggregator.strItemResp))
                    .build());
    //now you have Mono with filled Aggregator and you can make your json result
}
@Builder(toBuilder = true)
private static class Aggregator {
    private final String strInventoryResp;
    private final String strProductResponse;
    private final String strItemResp;
}

,我对您的示例有一个通知。看来您有多个网络客户端。这是一个不好的做法。由于线程使用情况(多个Web客户端将创建许多线程)

,因此您应该更喜欢一个Web客户端来应用程序。

相关内容

最新更新