代码之家  ›  专栏  ›  技术社区  ›  ESala

如何在Spring WebFlux中在响应体中传输二进制数据

  •  12
  • ESala  · 技术社区  · 8 年前

    我正在使用Spring WebFlux制作一个项目。

    过去我用过 StreamingResponseBody 用于将响应流式传输回客户端,但我在WebFlux中找不到等效的响应。

    例子:

    import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
    
    @GetMapping("/video")
    public StreamingResponseBody stream() {
        InputStream videoStream = ...
        StreamingResponseBody res = (os) -> { IOUtils.copy(videoStream, os); }
        return res;
    }
    

    是否有 流入口阀体 对于WebFlux?或者,我应该导入传统的Spring MVC并将其混合使用吗?

    编辑 :到目前为止,我通过访问 ServerHttpResponse (以下示例)。但我仍然想知道更好的解决方案。

    @GetMapping("/video")
    fun stream2(response: ServerHttpResponse): Mono<Void> {
        val factory = response.bufferFactory()
        val publisher = videoStream
                .observeVideoParts()
                .map { factory.wrap(it.bytes) }
        return response.writeWith(publisher)
    }
    
    2 回复  |  直到 8 年前
        1
  •  3
  •   ESala    8 年前

    目前,我找到的最佳解决方案是返回 ServerHttpResponse .

    自从 服务器HTTPResponse 仅允许写入 DataBuffer 对象,但不是 ByteArray 对象,我创建了一个扩展函数,在编写之前对其进行包装:

    fun ServerHttpResponse.writeByteArrays(bytes: Flux<ByteArray>): Mono<Void> {
        val factory = this.bufferFactory()
        val dataBuffers = bytes.map { factory.wrap(it) }
        return this.writeWith(dataBuffers)
    }
    

    然后a Flux<ByteArray> 可以简单地这样写:

    @GetMapping("/video")
    fun stream2(response: ServerHttpResponse): Mono<Void> {
        val videoParts: Flux<ByteArray> = ...
        return response.writeByteArrays(videoParts)
    }
    

    我仍然愿意接受其他解决方案。

        2
  •  1
  •   PeMa    6 年前

    有点晚了。然而,在浏览Spring core和Webflux的最新文档时,我认为以下内容应该是可行的:

    @GetMapping("/stream/{path}")
    public Flux<DataBuffer> getVideo(
            @PathVariable("path") String path,
            ServerHttpResponse response
    ) {
        return DataBufferUtils.read(
                new FileSystemResource(path),
                response.bufferFactory(),
                512
        );
    }