Spring WebClient:如何将大byte []流式传输到文件?

Dav*_* L. 8 java spring project-reactor spring-webflux spring-webclient

看起来Spring RestTemplate不能将响应直接流式传输到文件而不将其全部缓存在内存中。使用较新的Spring 5实现此目标的合适方法是WebClient什么?

WebClient client = WebClient.create("https://example.com");
client.get().uri(".../{name}", name).accept(MediaType.APPLICATION_OCTET_STREAM)
                    ....?
Run Code Online (Sandbox Code Playgroud)

我看到人们已经找到了解决此问题的一些变通方法/技巧RestTemplate,但是我对使用正确的方法更感兴趣WebClient

有许多RestTemplate用于下载二进制数据的示例,但是几乎所有示例都将其加载byte[]到内存中。

Z4-*_*Z4- 10

使用最近稳定的 Spring WebFlux(撰写本文时为 5.2.4.RELEASE):

final WebClient client = WebClient.create("https://example.com");
final Flux<DataBuffer> dataBufferFlux = client.get()
        .accept(MediaType.TEXT_HTML)
        .retrieve()
        .bodyToFlux(DataBuffer.class); // the magic happens here

final Path path = FileSystems.getDefault().getPath("target/example.html");
DataBufferUtils
        .write(dataBufferFlux, path, CREATE_NEW)
        .block(); // only block here if the rest of your code is synchronous

Run Code Online (Sandbox Code Playgroud)

对我来说,不明显的部分是bodyToFlux(DataBuffer.class),正如目前在关于Spring 文档通用部分中提到的那样,在 WebClient 部分中没有直接引用它。

  • DataBuffer 基本上看起来就像ByteBuffer。我没有看到读取器和写入器之间发生任何协调,也没有看到任何方法来设置缓冲区的大小限制。您如何知道 DataBuffer 是反应性的(或多线程协调的)且有大小限制? (2认同)
  • 没关系,显然流会根据需要生成尽可能多的 DataBuffer,每个 DataBuffer 都包含一块响应数据。不确定大小是如何确定的,也许是在 Netty 配置中。每个 DataBuffer 在发送到 Flux 时都是完整的,因此不需要协调。 (2认同)

归档时间:

查看次数:

1386 次

最近记录:

5 年,11 月 前