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

如何在Spring中实现流式返回多个不同MIME类型的multipart消息

Spring 流式输出multipart/related响应的惯用实现方案

手动拼接边界、构造多部分内容的方式容易出现换行符不规范、boundary冲突、不符合RFC标准等问题,Spring 原生提供了多部分响应的构造支持,不需要手动处理任何边界相关逻辑,核心依赖MultipartBodyBuilder实现,改造后的代码如下:

import org.springframework.http.MultipartBodyBuilder;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.Executor;

@GetMapping(value = "/data", produces = MediaType.MULTIPART_RELATED_VALUE)
public ResponseEntity<ResponseBodyEmitter> streamMultipart() {
    // 省略实际内容获取逻辑
    InputStream audio = new ByteArrayInputStream(null); // 异步获取的二进制流
    String json = "{}";
    ResponseBodyEmitter speakEmitter = new ResponseBodyEmitter();

    executor.execute(() -> {
        try {
            // 构造JSON部分
            speakEmitter.send(
                MultipartBodyBuilder.part("json", json)
                    .contentType(MediaType.APPLICATION_JSON)
                    .build()
            );

            // 构造二进制流部分
            speakEmitter.send(
                MultipartBodyBuilder.part("audio", audio.readAllBytes())
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .build()
            );

            // 全部内容发送完成后触发完成
            speakEmitter.complete();
        } catch (IOException e) {
            speakEmitter.completeWithError(e);
        }
    });
    // 无需手动设置Content-Type头,Spring会自动生成带合法boundary的响应头
    return ResponseEntity.ok(speakEmitter);
}

方案说明

  • 修正了原代码中produces配置和实际响应Content-Type不匹配的问题,Spring会根据produces配置自动生成带合法boundary的响应头
  • 所有多部分的边界生成、分隔符拼接、结束符追加都由Spring的MultipartHttpMessageConverter自动处理,完全符合RFC规范
  • 每个部分可以通过MultipartBodyBuilder.PartBuilder单独设置头信息,比如Content-Disposition、自定义头字段等
  • 如果使用Spring WebFlux环境,将ResponseBodyEmitter替换为Flux<MultipartBodyBuilder.Part>即可,逻辑基本一致
  • 如需自定义boundary规则,可以通过自定义配置MultipartHttpMessageConverter实现,一般场景下使用自动生成的boundary即可满足要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:48:05