通过 Spring WebClient 流式上传大文件
Posted
技术标签:
【中文标题】通过 Spring WebClient 流式上传大文件【英文标题】:Stream-uploading large files via Spring WebClient 【发布时间】:2021-03-07 07:09:39 【问题描述】:我遇到了与此处提到的相同的问题。
Stream upload 'POST' in Spring WebClient
我需要通过 Spring WebClient 上传大文件,并且我不想读取内存中的文件来执行此操作。
我将文件存储在 Minio S3 存储桶中,界面允许我以 java.io.InputStream 的形式接收文件。
然后我想将其作为上传主体流式传输到另一个服务端点。
产生Content type 'application/octet-stream' not supported for bodyType=org.springframework.web.reactive.function.BodyInserters
错误的解决方案是通过以下方式产生的:
public String uploadFile(String fileId, String fileName)
InputStream fileInputStream = minioClient.getObject(bucketName, fileId);
return webClient.post()
.uri(properties.getUrl())
.contentType(APPLICATION_OCTET_STREAM)
.headers(httpHeaders ->
httpHeaders.set(FILE_NAME, fileName);
)
.bodyValue(BodyInserters.fromResource(fileInputStream)
.retrieve()
.bodyToFlux(String.class)
.blockFirst();
【问题讨论】:
【参考方案1】:您可以尝试使用DataBufferUtils.readInputStream(..)
(javadoc) 创建Flux<DataBuffer>
。然后使用适当的BodyInserters.fromDataBuffers(..)
(javadoc) 传递给.bodyValue()
。这应该不会正确地将整个文件加载到内存中,而是缓冲并逐块发送。
我不确定这是否适用于 application/octet-stream
作为内容类型,因为我无法对其进行测试。
【讨论】:
以上是关于通过 Spring WebClient 流式上传大文件的主要内容,如果未能解决你的问题,请参考以下文章
Spring WebClient:如何将大字节 [] 流式传输到文件?
Spring webclient exchangeToFlux()不发出HTTP请求
Spring WebClient 作为 RestTemplate 的替代品
通过@Bean 提供的 RestTemplateBuilder 流式上传缓冲完整文件
Spring Boot 自动配置的 Jackson ObjectMapper 默认不用于 WebFlux WebClient