1. 本地 Ollama 对话网页为什么值得自己搭一套Ollama 装好之后命令行里ollama run就能聊天但每次都要开终端、复制粘贴体验很割裂。更实际的问题是如果你想把本地模型接进自己的工具链、给团队做个内网问答页、或者单纯想练手 SSE 流式推送命令行是满足不了的。这时候用 SpringBoot 搭一个网页后端把 Ollama 的流式输出通过 SSE 推到浏览器就是一条很顺的路径。这篇要解决的就是这条完整链路本地 Ollama 跑起来 → SpringBoot 提供 SSE 接口 → 前端网页逐字显示回复 → 同时留出 TaoToken 统一 Key 的配置骨架方便你以后把请求切到云端模型或做多模型路由。适合有 Java 基础、想跑通「网页访问本地大模型」的开发者也适合正在找 SSE 实战案例的人。我试过把 Ollama 的/api/generate直接暴露给前端结果跨域和流式解析两头卡最后还是回到 SpringBoot 中转的方案。下面按可复制的顺序来每一步都有命令和配置。2. 前置准备Ollama 运行与 TaoToken 通道骨架2.1 确认 Ollama 服务在跑Ollama 安装后默认监听11434端口。启动项目之前先确认服务活着ollama serve如果提示端口被占用说明后台已经在跑了直接验证模型列表ollama list拉一个轻量模型做测试1.5b 在普通笔记本上也能跑ollama run deepseek-r1:1.5b能进对话就说明本地推理链路通了。按CtrlD退出服务不会停。注意SpringBoot 项目启动前必须保证 Ollama 在运行否则 SSE 请求会直接报连接拒绝。2.2 TaoToken 统一 Key 的定位本地 Ollama 不需要 Key但一旦你想把同一套后端代码切到云端模型、或者做本地云端的混合路由就需要一个统一的 API 通道。TaoToken 在这里扮演的是「统一 Key 统一入口」的角色你拿一个 Key通过https://taotoken.net/api这个基地址去调不同模型后端代码不用为每个厂商写一套鉴权。配置骨架放在application.yml里用环境变量注入别硬编码taotoken: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY:} model: deepseek-r1:1.5b对应的settings.json示例如果你用支持该格式的客户端或工具链{ provider: taotoken, baseUrl: https://taotoken.net/api, apiKey: sk-你的Key, model: deepseek-r1:1.5b, stream: true }Key 的获取入口在控制台的 API Keys 页面建议单独建一个项目 Key方便按项目停用。接入文档里有各语言的最小请求示例排障时对照着看比猜快。3. 可复制配置SpringBoot SSE 后端三件套3.1 依赖与项目结构创建 SpringBoot 项目时勾选 Spring Web 和 WebFluxWebClient 在 WebFlux 里。目录结构src/main/java/com/example/ ├── config/WebConfig.java ├── controller/ChatController.java └── service/OllamaService.java src/main/resources/static/index.htmlpom.xml关键依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-webflux/artifactId /dependency3.2 跨域配置前端页面和后端同源时其实不需要但开发阶段用文件方式打开 HTML 会触发跨域先配上Configuration public class WebConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(*) .allowedMethods(*); } }3.3 SSE 控制器RestController RequestMapping(/api) public class ChatController { Autowired private OllamaService ollamaService; GetMapping(/chat-stream) public SseEmitter streamChat(RequestParam String message) { SseEmitter emitter new SseEmitter(0L); ollamaService.streamResponse(message, emitter); return emitter; } }new SseEmitter(0L)表示不设超时长回复不会被截断。默认超时是 30 秒大模型吐字慢的时候很容易踩这个坑。3.4 服务层把 Ollama 流式输出转成 SSEService public class OllamaService { private static final String OLLAMA_API_URL http://localhost:11434/api/generate; private final ObjectMapper objectMapper new ObjectMapper(); public void streamResponse(String message, SseEmitter emitter) { WebClient.create() .post() .uri(OLLAMA_API_URL) .contentType(MediaType.APPLICATION_JSON) .bodyValue(Map.of( model, deepseek-r1:1.5b, prompt, message, stream, true )) .retrieve() .bodyToFlux(String.class) .doOnComplete(() - sendCompletionSignal(emitter)) .subscribe( data - processData(data, emitter), error - handleError(emitter, error) ); } private void processData(String data, SseEmitter emitter) { try { JsonNode json objectMapper.readTree(data); String response json.get(response).asText(); emitter.send(SseEmitter.event().name(message).data(response)); } catch (Exception e) { handleError(emitter, new RuntimeException(数据解析失败: data, e)); } } private void sendCompletionSignal(SseEmitter emitter) { try { emitter.send(SseEmitter.event().name(done).data(COMPLETED)); emitter.complete(); } catch (IOException e) { emitter.completeWithError(e); } } private void handleError(SseEmitter emitter, Throwable error) { try { emitter.send(SseEmitter.event().name(error).data(服务请求失败: error.getMessage())); emitter.completeWithError(error); } catch (IOException e) { emitter.completeWithError(e); } } }这里的关键点Ollama 的流式响应是一行一个 JSON每个 JSON 里response字段是增量文本。bodyToFlux(String.class)按行拆开逐条解析后通过SseEmitter.event().name(message)推给前端。前端监听message事件累加文本监听done事件收尾。4. 验证请求curl 与网页双通道确认4.1 先用 curl 验证 Ollama 本身在启动 SpringBoot 之前直接打 Ollama 的接口确认流式返回正常curl http://localhost:11434/api/generate -d { model: deepseek-r1:1.5b, prompt: 用一句话解释什么是SSE, stream: true }你会看到一行行 JSON 往外冒每行都有response字段。如果这里卡住不动问题在 Ollama 侧不用往下查 SpringBoot。4.2 再验证 SpringBoot 的 SSE 接口项目启动后用 curl 打自己的接口curl -N http://localhost:8080/api/chat-stream?message你好-N关闭缓冲能实时看到event:message和data:...交替出现。看到event:done就说明整条链路通了。4.3 网页端确认index.html放在src/main/resources/static/下启动后直接访问http://localhost:8080/index.html。输入问题AI 回复应该逐字出现末尾有光标闪烁完成后光标消失。前端核心逻辑是EventSourceconst apiUrl http://localhost:8080/api/chat-stream?message${encodeURIComponent(message)}; currentEventSource new EventSource(apiUrl); currentEventSource.addEventListener(message, (event) { fullResponse event.data; updateAIReply(fullResponse); }); currentEventSource.addEventListener(done, () { finalizeAIReply(fullResponse); resetState(); });EventSource默认只支持 GET所以消息通过 query 参数传。消息长了 URL 会超长生产环境建议改成 POST fetch 的 ReadableStream 方案但作为跑通链路GET 足够。5. 本篇常见错排查5.1 连接被拒绝Connection refused报错Connection refused: localhost/127.0.0.1:11434说明 Ollama 没跑。执行ollama serve后重试。如果是远程访问把OLLAMA_API_URL里的localhost改成 Ollama 所在机器的 IP同时确认 Ollama 监听了外部地址。5.2 SSE 请求 30 秒后断开默认SseEmitter超时 30 秒长回复会被截断。改成new SseEmitter(0L)或设置一个足够大的值。另外 Nginx 反代时proxy_read_timeout也要调大否则网关层先断。5.3 前端收不到流式数据一次性全出来检查两处一是curl -N是否实时输出如果 curl 也是攒着一起出问题在后端缓冲二是 Nginx 是否开了proxy_buffering off。SpringBoot 侧确认返回的 Content-Type 是text/event-stream。5.4 中文乱码SseEmitter默认用 UTF-8但如果你手动设置了produces text/event-stream;charsetISO-8859-1就会乱。检查GetMapping有没有多余的 produces 声明去掉即可。5.5 模型名写错导致 404Ollama 返回model not found说明bodyValue里的model字段和ollama list里的名字不一致。注意带 tag 的完整名称比如deepseek-r1:1.5b不能简写成deepseek-r1。5.6 TaoToken Key 未生效如果切到 TaoToken 通道后返回 401先确认TAOTOKEN_API_KEY环境变量真的注入了可以在启动日志里打印一下长度别打印完整 Key。再对照接入文档检查请求头格式通常是Authorization: Bearer sk-xxx。排障阶段建议先用模型对话页面手动发一条确认 Key 本身可用再回到代码里查。6. 把链路固定下来下一步怎么走跑通之后建议把 Ollama 地址、模型名、TaoToken 的 base-url 和 Key 全部抽到application.yml用ConfigurationProperties绑定这样切换本地/云端只改配置不改代码。长期做编码辅助或 Agent 的话可以考虑 Coding Plan 那类按量方案把 Key 管理和额度控制交给平台自己专注在业务逻辑上。最后留一个实用技巧SSE 接口加一个GetMapping(/health)返回 Ollama 的连通状态前端页面加载时先探一下连不上就直接提示「本地模型未启动」比让用户对着转圈的光标猜要友好得多。
企业数字化 ERP 产品动态
相关推荐
玉田县网站建设新手避坑:2026最新设计规范与前端实战指南 玉田县网站建设新手避坑:2026最新设计规范与前端实战指南 自己不会代码想做网站,最头疼的不是买服务器,而是做出来的页面在手机上看像“乱码”,电脑上看像“上世纪产物”。很多玉田县的老板或者刚入行的朋友,拿着几万块预算,做出来的官网却留不住客… · 2026/9/27 22:15:29
Claude Code + MCP 实战:用 TaoToken 统一 Key 打通自动部署工具的发版链路 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 22:15:29
MCP与A2A企业级开发:从原理到代码落地全指南(TaoToken 统一 Key 接入版) /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 22:15:29
1.3 Python网络运维自动化实践之路 5 多年来, 我一直关注着网络运维自动化领域的发展。虽然这个领域里的理论知识一直在不断更新。从业界主流的网络管理标准体系FCAPS, 一直到这些年跟着发展起来的这些新东西。但是一直没找到写网络运维自动化实战方面的书。直到我看到了这一本。我把这本书推荐给云计算领域或者网络… · 2026/9/27 22:54:02
Python中生成器表达式的实现原理和使用场景 用 的人,十有八九都踩过这个坑:当数据规模变大的时候, 你的程序就会陷入停滞状态;如果内存使用量急剧升高, 电脑的运行也会出现严重的卡顿现象。很多人以为这是电脑本身的硬件配置没有办法满足要求, 事实上导致这种情况的根本原因在于你所编写… · 2026/9/27 22:54:02
湖南派森启航网络科技有限公司:Python职业发展的关键助力 湖南派森启航网络科技有限公司:凭何成为职业发展的关键助力在当今的数字化浪潮已经席卷了全世界, 懂得一门编程语言, 就变成了工作中的重要竞争力。因为简单好用, 功能又非常强, 它迅速变成了全球最受欢迎的编程语言里的一个。很多人把这把钥匙当作打开职业新篇章的… · 2026/9/27 22:53:55
计算机视觉零基础怎么入门?从Python到AI大模型+CV项目落地路线 有非常多的人都在询问, 假如一点计算机视觉的基础知识都没有的话, 应当如何开始入门学习。实际上, 这并非意味着要先去购买一大堆专业的图书资料, 也绝不是一上来就去硬着头皮阅读YOLO这样的高深论文文档。更为合理可行的学习路径顺序应当是: 起初要能够学会运用现有的工具或方… · 2026/9/27 22:53:55
设计文档怎么写 设计文档怎么写
设计文档(Design Doc)是架构师最重要的产出物之一。它的核心目的不是"展示我设计得多好",而是让读者在最短时间内理解:要解决什么问题、为什么这样设计、有什么权衡、怎么落地。
下面从类型、结构、写法、常见错误四个层面讲清楚,并结合你那个… · 2026/9/27 22:53:55
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01