如何在 Spring Webflux 中返回 Mono<Map<String, Flux<Integer>>> 响应?

Posted

技术标签:

【中文标题】如何在 Spring Webflux 中返回 Mono<Map<String, Flux<Integer>>> 响应?【英文标题】:How can I return a Mono<Map<String, Flux<Integer>>> response in Spring Webflux? 【发布时间】:2018-12-19 16:49:51 【问题描述】:

所以现在,我返回的响应看起来像

    @GetMapping("/integers")
    @ResponseStatus(code = HttpStatus.OK)
    public Mono<Map<String, Flux<Integer>>> getIntegers() 
        Mono<Map<String, Flux<Integer>>> integers = 
               Mono.just(Map.of("Integers", integerService.getIntegers()));
        return integers;
    

这给了我一个回应

"Integers":"scanAvailable":true,"prefetch":-1

我希望它也能流式传输Flux&lt;Integer&gt; 部分,但它没有。我将如何在 Spring webflux 中执行此操作?

【问题讨论】:

【参考方案1】:

Spring WebFlux 只能处理一种响应式类型,而不会处理嵌套的响应式类型(例如 Mono&lt;Flux&lt;Integer&gt;&gt;)。你的控制器方法可以返回一个Mono&lt;Something&gt;、一个Flux&lt;Something&gt;、一个ResponseEntity&lt;Mono&lt;Something&gt;&gt;、一个Mono&lt;ResponseEntity&lt;Something&gt;&gt;等——但不能嵌套反应类型。

您在响应中看到的奇怪数据是 Jackson 实际上试图序列化一个反应类型(因此您看到的是数据的承诺,而不是数据本身)。

在这种情况下,您可以像这样重写您的方法:

@GetMapping("/integers")
@ResponseStatus(code = HttpStatus.OK)
public Mono<Map<String, Flux<Integer>>> getIntegers() 
    Flux<Integer> integers = integerService.getIntegers();
    Mono<Map<String, List<Integer>>> result = integers
            // this will buffer and collect all integers in a Mono<List<Integer>>
            .collectList()
            // we can then map that and wrap it into a Map
            .map(list -> Collections.singletonMap("Integers", list));
    return result;

您可以在the Spring WebFlux reference documentation 中阅读有关支持的返回值的更多信息。

【讨论】:

我明白了,我最终链接了@Getmapping 来生成 MediaType.APPLICATION_STREAM_JSON_VALUE 因为我不确定返回纯 Flux 是否会将数据流式传输到客户端而不做任何排序的缓冲。很大程度上,由于我要返回十亿个重对象(整数只是实际业务对象的占位符)在您的情况下,如果 Flux , integers.collectToList() 是否会抛出堆外内存异常整数有很多东西要流式传输 对不起,编辑了上面的评论。在写所有内容之前,我不小心按了 Enter 哈哈,我经常用 SO cmets 遇到这个问题。你说得对。在这种情况下,流式值是正确的选择 - Flux.collectList 确实缓冲内存中的所有内容,因此这不是大型集合/对象的最佳选择。 呵呵,好吧,我注意到你在 SO 上提出了很多与 spring webflux 相关的问题,所以你的手现在一定是击键快乐这有道理,谢谢! 对我非常有用,谢谢

以上是关于如何在 Spring Webflux 中返回 Mono<Map<String, Flux<Integer>>> 响应?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 spring webflux 读取请求正文

使用 Spring Webflux 返回元素列表

Spring webflux 和 Angular

如何在错误 Spring WebFlux 上调用另一个 api

在 Spring Webflux 中结合非阻塞和阻塞调用并返回结果

spring webflux Flux<DataBuffer> 转换为 InputStream