Java后端对接AI大模型 SSE流式输出实战|实现打字机效果、实时流式问答(可直接商用)
·
Java后端对接AI大模型 SSE流式输出实战|实现打字机效果、实时流式问答(可直接商用)
一、前言:为什么 AI 问答必须用 SSE 流式输出?
现在所有 AI 对话产品(ChatGPT、DeepSeek、文心一言、通义千问)都是流式输出,也就是:
后端不用等 AI 全部回答完毕,而是返回一个字、推一个字,前端实时渲染打字机效果。
传统接口存在致命问题:
- 大模型回答 3000 字需要 3~5 秒
- 前端长时间空白、用户以为卡死
- 超时熔断、响应超时、体验极差
而 SSE(Server-Sent Events) 是目前 AI 问答的工业标准:
- 基于 HTTP 长连接
- 服务端主动持续推送数据
- 无需 WebSocket 复杂握手
- 天然适合 AI 流式问答场景
本文带你从零实现 Java + SpringBoot3 + AI大模型 SSE 流式问答,代码可直接商用。
二、SSE 核心原理(面试必问)
1. 普通接口
一次请求 → 一次完整响应 → 连接关闭
2. SSE 流式接口
一次请求 → 服务端持续分片推送 → 前端逐字渲染 → 对话结束关闭连接
响应头关键标识:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
三、项目依赖(SpringBoot3 最新稳定版)
无需特殊依赖,SpringBoot 原生支持 SSE。
<dependencies>
<!-- Web核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Http工具,调用大模型接口 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<!-- JSON解析 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.52</version>
</dependency>
</dependencies>
四、核心工具类:SSE 流式推送工具
封装通用 SSE 推送、关闭、异常处理工具类,全局复用。
import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/**
* SSE 流式推送工具类
* 用于AI大模型流式输出、实时消息推送
*/
public class SseUtil {
/**
* 创建SSE发射器(超时3分钟)
*/
public static SseEmitter createEmitter() {
// 设置超时时间 3分钟
return new SseEmitter(1000L * 60 * 3);
}
/**
* 推送消息
*/
public static void send(SseEmitter emitter, String content) {
try {
emitter.send(content, MediaType.TEXT_PLAIN);
} catch (Exception e) {
// 客户端断开连接
emitter.complete();
}
}
/**
* 结束推送
*/
public static void complete(SseEmitter emitter) {
if (emitter != null) {
emitter.complete();
}
}
}
五、AI大模型流式问答核心接口(可直接商用)
适配 DeepSeek、GPT、通义千问、智谱 通用流式返回格式。
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import okhttp3.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
@RestController
@RequestMapping("/ai")
public class AiStreamController {
// 大模型API密钥(替换自己的)
private static final String API_KEY = "sk-xxxx";
private static final String AI_URL = "https://api.deepseek.com/v1/chat/completions";
@GetMapping(value = "/chat/stream", produces = "text/event-stream;charset=UTF-8")
public SseEmitter aiChatStream(@RequestParam String prompt) {
// 1. 创建SSE推送器
SseEmitter emitter = SseUtil.createEmitter();
// 2. 异步调用大模型(防止阻塞主线程)
new Thread(() -> {
OkHttpClient client = new OkHttpClient();
try {
// 构建请求参数
JSONObject json = new JSONObject();
json.put("model", "deepseek-chat");
json.put("stream", true); // 开启流式输出!核心
json.put("temperature", 0.7);
// 构建对话消息
JSONObject message = new JSONObject();
message.put("role", "user");
message.put("content", prompt);
json.put("messages", new Object[]{message});
// 构建请求
RequestBody body = RequestBody.create(json.toString(), MediaType.get("application/json; charset=utf-8"));
Request request = new Request.Builder()
.url(AI_URL)
.addHeader("Authorization", "Bearer " + API_KEY)
.post(body)
.build();
// 流式读取返回内容
Response response = client.newCall(request).execute();
BufferedReader reader = new BufferedReader(new InputStreamReader(response.body().byteStream()));
String line;
while ((line = reader.readLine()) != null) {
// 过滤空行和结束标识
if (line.startsWith("data: ") && !line.contains("[DONE]")) {
String data = line.substring(6);
JSONObject resJson = JSON.parseObject(data);
// 逐字获取AI返回内容
String content = resJson.getJSONArray("choices")
.getJSONObject(0)
.getJSONObject("delta")
.getString("content");
// 逐字推送给前端
SseUtil.send(emitter, content);
}
}
// 流式结束
SseUtil.complete(emitter);
} catch (Exception e) {
SseUtil.complete(emitter);
}
}).start();
return emitter;
}
}
六、前端测试(极简页面,可直接运行)
前端使用 EventSource 监听流式响应,实现打字机效果。
<!DOCTYPE html>
<html>
<body>
<div id="result" style="white-space: pre-wrap;"></div>
<script>
// 建立SSE连接
const source = new EventSource("http://localhost:8080/ai/chat/stream?prompt=用Java写一个冒泡排序");
let resDom = document.getElementById("result");
// 接收流式数据
source.onmessage = function (e) {
resDom.innerHTML += e.data;
};
// 连接关闭
source.onclose = function () {
source.close();
};
</script>
</body>
</html>
七、运行效果
\1. 页面不会等待,秒级出现第一个字
\2. AI 内容逐字弹出,完美打字机效果
\3. 全部输出完毕自动关闭连接
\4. 不会超时、不会断流
八、生产环境高频坑点(2026最新)
坑1:忘记设置 stream=true
大模型默认一次性返回全部内容,不会流式推送。
坑2:主线程阻塞
必须异步请求大模型,否则 SSE 推送卡死。
坑3:前端跨域
SSE 属于跨域请求,后端必须配置跨域放行。
坑4:连接不关闭导致内存泄漏
必须捕获异常、手动 complete 关闭连接。
坑5:中文乱码
接口必须指定:produces = "text/event-stream;charset=UTF-8"
九、拓展升级(企业级功能)
- 上下文记忆:拼接 history 对话记录,实现连续对话
- 用户限流:防止恶意刷接口消耗AI额度
- 异常重连:断网自动重连 SSE
- 敏感词过滤:AI输出内容风控
- 对话日志入库:记录问答、耗时、Token消耗
十、总结
SSE 流式输出是 AI 产品的标配技术,相比 WebSocket 更轻量、更简单、更适合问答场景。
本文代码是 2026 年最新企业通用方案:
- SpringBoot3 原生支持
- 零冗余、可直接上线商用
- 适配所有国产大模型
- 解决超时、空白、卡顿等用户体验问题
现在绝大多数 AI 客服、AI 助手、智能问答后台,全部采用这套架构!
更多推荐


所有评论(0)