Spring WebClient:解析+流非常大的JSON

Fri*_*ing 10 spring-webflux

这个问题类似于来自常规 WebClient 请求的 Spring 反应式流数据,不同之处在于我没有立即从我的 WebClient 获取 JSON 数组,而是这样的:

这个 JSON 对象可能非常大(~100MB),因此需要处理并流式传输到客户端,而不是解析。这是我似乎能够获得正确语义的唯一方法:

{
   "result-set":{
      "docs":[
         {
            "id":"auhcsasb1005_100000"
         },
         {
            "id":"auhcsasb1005_1000000"
         },
         {
            "id":"auhcsasb1005_1000001"
         },
         {
            "id":"auhcsasb1005_1000002"
         },
         ...
         ...
         {
            "EOF":true
         }
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)
WebClient.create()
  .get()
  .retrieve()
  .bodyToMono(DontKnowWhatClass.class)
  .flatMapMany(resultSet -> Flux.fromIterable(resultSet.getDocs()))
Run Code Online (Sandbox Code Playgroud)

但这意味着我在内存中反序列化 100MB 或更多,然后从中创建通量。我想知道的是:我是否遗漏了一些重要的东西?我可以以某种方式从这样的对象创建 Flux 吗?遗憾的是,我现在有办法影响结果集对象的呈现方式。

Ada*_*ord -1

您可以接受ServerWebExchange您的控制器,该控制器具有采用 Publisher 的方法exchange.response.writeWith()

如果您有办法以块的形式解析有效负载,您只需创建一个发出各个部分的 Flux 即可。

例如,如果您根本不关心有效负载,只想按原样发送:

    @GetMapping("/api/foo/{myId}")
    fun foo(exchange: ServerWebExchange, @PathVariable myId: Long): Mono<Void> {
        val content: Flux<DataBuffer> = webClient
            .get()
            .uri("/api/up-stream/bar/$myId")
            .exchange()
            .flatMapMany { it.bodyToFlux<DataBuffer>() }

        return exchange.response.writeWith(content)
    }
Run Code Online (Sandbox Code Playgroud)

请务必检查内容协商设置,以避免发生意外的缓冲。