【问题标题】:How to stream binary data in a response body in Spring WebFlux如何在 Spring WebFlux 的响应正文中流式传输二进制数据
【发布时间】:2018-06-05 20:47:03
【问题描述】:

我正在使用 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 是否有相当于StreamingResponseBody 的东西?或者,我应该导入传统的 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)
}

【问题讨论】:

  • @Frischling 谢谢,但它不是重复的,使用基于注释的控制器和请求映射时,使用 ServerResponse 不起作用。见:stackoverflow.com/a/50026023

标签: java spring spring-mvc kotlin spring-webflux


【解决方案1】:

目前,我发现的最佳解决方案是返回 ServerHttpResponse

由于ServerHttpResponse 只允许写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)
}

那么Flux&lt;ByteArray&gt;可以简单地写成这样:

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

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

【讨论】:

    【解决方案2】:

    有点晚了。但是,扫描 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
        );
    }
    

    【讨论】:

    • 我的错,我没有时间测试这种方法。如果您不赞成,请发表评论。也许我可以改进我的答案。
    猜你喜欢
    • 2018-01-13
    • 2012-08-27
    • 2018-11-22
    • 2022-01-21
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 2010-09-25
    • 2014-09-25
    相关资源
    最近更新 更多