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

Java Spring WebClient无法下载文件:生成0字节文件求助

问题排查与解决

核心问题分析

你遇到的0字节空文件问题,大概率是数据流未被正确消费或缓冲区未完成写入/释放导致的。Postman能正常获取说明接口本身没问题,问题出在WebClient的数据流处理逻辑上。

修正后的代码

官方推荐简洁写法

Path path = Paths.get("src/main/resources/" + test + ".bin");

WebClient.create()
        .get()
        .uri(URI.create(download_url))
        .header("Authorization", "Bearer " + token)
        .retrieve()
        .onStatus(HttpStatus::isError, res -> res.bodyToMono(String.class)
                .flatMap(errorMessage -> Mono.error(new CustException(errorMessage, res.statusCode().value()))))
        .bodyToFlux(DataBuffer.class)
        .transform(DataBufferUtils::write)
        .to(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)
        .block();

手动控制缓冲区写法(便于调试)

Path path = Paths.get("src/main/resources/" + test + ".bin");

Mono<Void> writeResult = WebClient.create()
        .get()
        .uri(URI.create(download_url))
        .header("Authorization", "Bearer " + token)
        .retrieve()
        .onStatus(HttpStatus::isError, res -> res.bodyToMono(String.class)
                .flatMap(errorMessage -> Mono.error(new CustException(errorMessage, res.statusCode().value()))))
        .bodyToFlux(DataBuffer.class)
        .doOnNext(DataBufferUtils::release)
        .collectList()
        .flatMap(dataBuffers -> {
            try (FileOutputStream fos = new FileOutputStream(path.toFile())) {
                for (DataBuffer buffer : dataBuffers) {
                    fos.write(buffer.asByteBuffer().array());
                }
                return Mono.empty();
            } catch (IOException e) {
                return Mono.error(e);
            }
        });

writeResult.block();

关键修正点

  • 移除多余的share():该方法会让数据流被多订阅者共享,单写入场景下反而可能导致数据流提前终止。
  • 补全文件打开选项:添加WRITE和TRUNCATE_EXISTING,确保文件被正确写入而非仅创建空文件。
  • 确保缓冲区释放:官方DataBufferUtils.write会自动处理缓冲区释放;手动写法需调用DataBufferUtils.release()避免内存泄漏。
  • 直接阻塞写入结果:DataBufferUtils.write返回的Mono<Void>会在写入完成后才完成,直接block()能确保整个写入流程执行完毕。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:22:37