Java 中实现流式输出(Streaming Output)常见于以下几种应用场景:

  • ✅ 与前端配合展示“逐步加载”(如聊天 AI 实时回复);
  • ✅ 大文件分块下载;
  • ✅ 后端实时日志/进度反馈;
  • ✅ SSE(Server-Sent Events)/ WebSocket 流式推送。

✅ 1. 使用 SseEmitter 实现服务端逐步发送(Spring Boot)

@RestController
public class StreamController {

    @GetMapping("/stream")
    public SseEmitter stream() {
        SseEmitter emitter = new SseEmitter(0L); // 不设置超时时间

        new Thread(() -> {
            try {
                for (int i = 1; i <= 10; i++) {
                    emitter.send("第 " + i + " 条数据");
                    Thread.sleep(500);
                }
                emitter.complete();
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        }).start();

        return emitter;
    }
}

前端监听方式(HTML 示例):

<script>
  const source = new EventSource("/stream");
  source.onmessage = e => {
    console.log("收到数据:", e.data);
  };
</script>

✅ 2. 使用 ResponseBodyEmitter 流式输出普通 HTTP 内容

@GetMapping("/text-stream")
public ResponseBodyEmitter streamText() {
    ResponseBodyEmitter emitter = new ResponseBodyEmitter();

    new Thread(() -> {
        try {
            for (int i = 0; i < 5; i++) {
                emitter.send("行:" + i + "\n", MediaType.TEXT_PLAIN);
                Thread.sleep(1000);
            }
            emitter.complete();
        } catch (IOException | InterruptedException e) {
            emitter.completeWithError(e);
        }
    }).start();

    return emitter;
}

📌 适用于纯文本输出,不需要 text/event-stream 的场景。


✅ 3. 使用 Flux<String>(Spring WebFlux)实现响应式流输出

@GetMapping(value = "/flux-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamFlux() {
    return Flux.interval(Duration.ofMillis(500))
               .map(i -> "flux 数据:" + i)
               .take(10);
}

📌 WebFlux 和 reactive stack 专用,效果类似于 SseEmitter


✅ 4. 控制台或日志流式输出(非 Web)

public class StreamDemo {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 1; i <= 5; i++) {
            System.out.print("第 " + i + " 行\r");
            Thread.sleep(500);
        }
    }
}

📌 控制台实时输出(如进度条),常用于 CLI 工具。


总结:根据场景选方式

场景推荐方式
后端推送给浏览器SseEmitter 或 Flux(SSE)
控制台实时输出System.out.print
REST 接口返回大文件/大数据StreamingResponseBody 或 OutputStream
与前端聊天/AI 对话联动SseEmitter + WebClient