You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将Flux<DataBuffer>封装到自定义对象后WebClient上传文件为空如何解决

问题根因

0字节问题的核心原因有两点:

  • Spring WebClient的exchangeToMono方法会在回调返回的Mono完成后自动释放HTTP连接,你在回调中仅将response.bodyToFlux(DataBuffer::class.java)的流引用封装到Mediator对象返回,此时并未消费响应体流,连接释放后这个Flux就会变成无效空流,后续上传时自然没有数据。
  • 你在runBlocking中调用subscribe()触发流执行,subscribe()是异步非阻塞方法,会立刻返回,runBlocking不等流执行完成就退出,也可能导致整个流程提前终止。
修复方案

将上传逻辑放在exchangeToMono的回调内部执行,保证下载连接未释放时就传递响应体流到上传逻辑,同时调整流的触发方式确保流程执行完成,修改后代码如下:

import kotlinx.coroutines.reactive.awaitSingle
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.reactive.function.client.WebClient
import reactor.core.publisher.Mono

runBlocking {
    downloadAndUpload().awaitSingle()
}

private fun downloadAndUpload(): Mono<ResponseEntity<Void>> {
    return WebClient.create("https://server.com/assets/file.pdf")
        .get()
        .exchangeToMono { downloadResponse ->
            // 直接在回调内完成上传,此时下载连接仍处于有效状态
            WebClient.create("http://localhost:3000/upload")
                .put()
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(downloadResponse.bodyToFlux(DataBuffer::class.java), DataBuffer::class.java)
                .retrieve()
                .toBodilessEntity()
        }
        .doOnError { e ->
            println("流程执行出错:${e.message}")
        }
}
额外注意事项
  • 大文件传输时建议调整Spring WebClient的缓冲区配置,避免OOM问题。
  • 正常消费流的场景下Spring会自动管理DataBuffer的内存释放,若有自定义截断、跳过流的操作,需要手动调用DataBufferUtils.release(dataBuffer)避免内存泄漏。

内容的提问来源于stack exchange,提问作者Vahid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:24:04