拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Spring AI Alibaba 入门开发1-环境搭建、ollama部署、Chat和ChatModel、流式输出

目录一、准备工作二、HelloWorld2.1 项目结构2.2 创建父工程2.3 创建子模块——ssa-01-HelloWorld三、微服务调用本地大模型-本章可跳过3.1 准备工作系统与硬件要求本地部署大模型配置推荐列表3.2 开发调用本地大模型四、ChatModel和ChatClient4.1 ChatModel4.2 ChatClient4.3 使用ChatClient调用大模型4.4 两者对比五、同时使用多个模型实现流式输出5.1 流式输出介绍5.2 SSE(Server-Sent Events)服务器发送事件5.3 多模型共存开发5.4 Flux介绍5.5 新增前端交互一、准备工作1、到阿里百炼平台申请API KEY、然后获取base_url、模型code。具体请自行百度。2、我的相关配置JDK 21maven 建议3.9.5SpringBoot : 3.5.5spring-ai: 1.0.0SpringAIAlibaba:1.0.2二、HelloWorld2.1 项目结构2.2 创建父工程只需修改父工程pom.xml即可代码如下properties project.build.sourceEncodingUTF-8/project.build.sourceEncoding project.reporting.outputEncodingUTF-8/project.reporting.outputEncoding maven.compiler.source21/maven.compiler.source maven.compiler.target21/maven.compiler.target java.version21/java.version spring-boot.version3.5.5/spring-boot.version spring-ai.version1.0.0/spring-ai.version SpringAIAlibaba.version1.0.0.2/SpringAIAlibaba.version /properties dependencyManagement dependencies !-- Spring Boot -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-dependencies/artifactId version${spring-boot.version}/version typepom/type scopeimport/scope /dependency !-- Spring AI Alibaba -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-bom/artifactId version${SpringAIAlibaba.version}/version typepom/type scopeimport/scope /dependency !-- Spring AI -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId version${spring-boot.version}/version /plugin /plugins /build repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositories2.3 创建子模块——ssa-01-HelloWorld1、pom.xmlproperties maven.compiler.source21/maven.compiler.source maven.compiler.target21/maven.compiler.target project.build.sourceEncodingUTF-8/project.build.sourceEncoding /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId /dependency !--lombok-- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency !--hutool-- dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.22/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version3.11.0/version configuration compilerArgs arg-parameters/arg /compilerArgs source21/source target21/target /configuration /plugin /plugins /build repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositories2、配置文件application.propertiesserver.port8888 #解决中文乱码 server.servlet.encoding.charsetUTF-8 server.servlet.encoding.enabledtrue server.servlet.encoding.forcetrue spring.application.namessa-01-HelloWorld #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key${qianwen-api} spring.ai.dashscope.base-urlhttps://ws-6tq01jo6mtthlhoq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 spring.ai.dashscope.chat.options.modelqwen-max注意配置api-key时不能使用明文需要先配置环境变量然后在properties中使用${环境变量}3、创建配置类有两种方式获取api-key一种是读取application.properties的内容一种是读取环境变量的值。具体实现如下Configuration public class LLMConfig { //方式1读取配置文件信息 Value(${spring.ai.dashscope.api-key}) private String apiKey; Bean public DashScopeApi dashScopeApi() { return DashScopeApi.builder().apiKey(apiKey).build(); } //方式2读取环境变量 // Bean // public DashScopeApi dashScopeApi2() { // return DashScopeApi.builder().apiKey(System.getenv(qianwen-api)).build(); // } }4、对话模型-Chat Model对话模型Chat Model接收一系列消息Message作为输入与模型 LLM 服务进行交互并接收返回的聊天消息Chat Message作为输出。相比于普通的程序输入模型的输入与输出消息Message不止支持纯字符文本还支持包括语音、图片、视频等作为输入输出。同时在 Spring AI Alibaba 中消息中还支持包含不同的角色帮助底层模型区分来自模型、用户和系统指令等的不同消息。Spring AI Alibaba 复用了 Spring AI 抽象的 Model API并与通义系列大模型服务进行适配如通义千问、通义万相等目前支持纯文本聊天、文生图、文生语音、语音转文本等。以下是框架定义的几个核心 APIChatModel文本聊天交互模型支持纯文本格式作为输入并将模型的输出以格式化文本形式返回。ImageModel接收用户文本输入并将模型生成的图片作为输出返回。AudioModel接收用户文本输入并将模型合成的语音作为输出返回。Spring AI Alibaba 支持以上 Model 抽象与通义系列模型的适配并通过spring-ai-alibaba-starterAutoConfiguration 自动初始化了默认实例因此我们可以在应用程序中直接注入 ChatModel、ImageModel 等 bean当然在需要的时候也可以自定义 Model 实例。5、创建controller使用两种方式与大模型进行交互一种是.call()此方式是一次响应所有的内容一种是.stream()文字逐个返回。RestController public class ChatHelloWorldController { Resource private ChatModel chatModel; GetMapping(/hello/call) public String doCall(RequestParam(value msg , defaultValue 高欢) String msg) { String result chatModel.call(msg); return result; } GetMapping(/hello/stream) public FluxString doStream(RequestParam(value msg , defaultValue 宇文泰) String msg) { return chatModel.stream(msg); } }三、微服务调用本地大模型-本章可跳过3.1 准备工作1、本地安装Ollama。注意默认安装C盘建议更换其他位置。安装方法请百度。系统与硬件要求项目最低要求特别说明操作系统Windows 10 22H2 或更新版本家庭版/专业版均可版本过旧可能导致兼容性问题建议更新。处理器 (CPU)4核及以上推荐Intel i7或AMD Ryzen 5以上若没有独立显卡将完全依赖CPU进行推理速度会慢很多。内存 (RAM)16GB 或更高运行大模型时内存是保证系统不崩溃的关键。显卡 (GPU)强烈推荐NVIDIA或AMD独立显卡Ollama支持NVIDIA、AMD Radeon GPU加速。NVIDIA显卡驱动551.61 或更新版本这是官方文档的要求驱动太旧可能无法识别显卡。AMD显卡驱动安装最新版AMD Radeon驱动或支持ROCm/Vulkan的驱动部分RDNA2架构显卡如RX 6000系列可能推荐使用Vulkan加速。存储空间安装程序本身约需4GB另需为模型文件预留几十到上百GB模型文件体积很大强烈建议安装在SSD上以提升加载速度。本地部署大模型配置推荐列表推荐级别模型系列具体推荐模型 (Ollama命令)模型大小 (量化后)显存占用预期速度 (tokens/秒)适用场景 首选推荐Qwen3 (4B)ollama run qwen3:4b-q4_K_M~2.9 GB~3.2 GB30 - 50日常聊天、问答、编程辅助、文本总结体验流畅 次选推荐Qwen2.5 (3B)ollama run qwen2.5:3b-q4_K_M~2.0 GB~2.2 GB40 - 60轻量级任务响应极快适合资源敏感场景 进阶挑战DeepSeek-R1 (7B)ollama run deepseek-r1:7b-q4_K_M~4.4 GB~4.6 GB (略超显存)8 - 15复杂推理、代码生成需要部分CPUGPU混合运行速度较慢确认好模型后可以使用pull命令拉去使用run命令运行具体与docker类似。3.2 开发调用本地大模型1、新建子模块项目结构如下2、修改pom.xml文件dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !--spring-ai-alibaba dashscope-- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId /dependency !--ollama-- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-ollama/artifactId version1.0.0/version /dependency !--lombok-- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency !--hutool-- dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.22/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version3.11.0/version configuration compilerArgs arg-parameters/arg /compilerArgs source21/source target21/target /configuration /plugin /plugins /build repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositories3、application.propertiesserver.port8888 #解决中文乱码 server.servlet.encoding.charsetUTF-8 server.servlet.encoding.enabledtrue server.servlet.encoding.forcetrue spring.application.namessa-02-ollama #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key${qianwen-api} spring.ai.ollama.base-urlhttp://localhost:11434 spring.ai.ollama.chat.options.modelqwen3:4b4、新建controllerRestController public class OllamaController { Resource(name ollamaChatModel) private ChatModel chatModel; GetMapping(/ollama) private FluxString ollama(RequestParam(value msg ,defaultValue 高欢) String msg){ return chatModel.stream(msg); } }5、新建启动类public class SSA_02_OllamaApplication { public static void main(String[] args) { SpringApplication.run(SSA_02_OllamaApplication.class, args); } }6、运行如下四、ChatModel和ChatClient4.1 ChatModel对话模型Chat Model接收一系列消息Message作为输入与模型 LLM 服务进行交互并接收返回的聊天消息Chat Message作为输出。相比于普通的程序输入模型的输入与输出消息Message不止支持纯字符文本还支持包括语音、图片、视频等作为输入输出。同时在 Spring AI Alibaba 中消息中还支持包含不同的角色帮助底层模型区分来自模型、用户和系统指令等的不同消息。Spring AI Alibaba 复用了 Spring AI 抽象的 Model API并与通义系列大模型服务进行适配如通义千问、通义万相等目前支持纯文本聊天、文生图、文生语音、语音转文本等。以下是框架定义的几个核心 APIChatModel文本聊天交互模型支持纯文本格式作为输入并将模型的输出以格式化文本形式返回。ImageModel接收用户文本输入并将模型生成的图片作为输出返回。AudioModel接收用户文本输入并将模型合成的语音作为输出返回。Spring AI Alibaba 支持以上 Model 抽象与通义系列模型的适配并通过spring-ai-alibaba-starterAutoConfiguration 自动初始化了默认实例因此我们可以在应用程序中直接注入 ChatModel、ImageModel 等 bean当然在需要的时候也可以自定义 Model 实例。ChatModel适合简单大模型交互场景。4.2 ChatClientChatClient提供了与 AI 模型通信的 Fluent API它支持同步和反应式Reactive编程模型。与ChatModel、Message、ChatMemory等原子 API 相比使用ChatClient可以将与 LLM 及其他组件交互的复杂性隐藏在背后因为基于 LLM 的应用程序通常要多个组件协同工作例如提示词模板、聊天记忆、LLM Model、输出解析器、RAG 组件嵌入模型和存储并且通常涉及多个交互因此协调它们会让编码变得繁琐。当然使用ChatModel等原子 API 可以为应用程序带来更多的灵活性成本就是您需要编写大量样板代码。ChatClient 类似于应用程序开发中的服务层它为应用程序直接提供AI 服务开发者可以使用 ChatClient Fluent API 快速完成一整套 AI 交互流程的组装。包括一些基础功能如定制和组装模型的输入Prompt格式化解析模型的输出Structured Output调整模型交互参数ChatOptions还支持更多高级功能聊天记忆Chat Memory工具/函数调用Function CallingRAGChatClient是高级封装基于ChatModel创建适合快速构建保准化复杂AI服务支持同步和流式交互集成多种高级功能。4.3 使用ChatClient调用大模型1、项目结构2、创建子模块修改pom.xmldependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !--spring-ai-alibaba dashscope-- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId /dependency !--lombok-- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency !--hutool-- dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.22/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version3.11.0/version configuration compilerArgs arg-parameters/arg /compilerArgs source21/source target21/target /configuration /plugin /plugins /build repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositories创建启动类SpringBootApplication public class SSA_03_ChatModel_ChatClient_Application { public static void main(String[] args) { SpringApplication.run(SSA_03_ChatModel_ChatClient_Application.class, args); } }创建配置文件server.port8888 #解决中文乱码 server.servlet.encoding.charsetUTF-8 server.servlet.encoding.enabledtrue server.servlet.encoding.forcetrue spring.application.namessa-02-ChatModel-ChatClient #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key${qianwen-api} spring.ai.ollama.base-urlhttp://localhost:11434 spring.ai.ollama.chat.options.modelgoekdenizguelmez/JOSIEFIED-Qwen2.5:7b-q4_k_m创建controller注意下面通过两种方式创建ChatClient对象。方式一在config里通过Bean注解创建——推荐Configuration public class LLMConfig { Value(${spring.ai.dashscope.api-key}) private String apiKey; Bean public DashScopeApi dashScopeApi() { return DashScopeApi.builder().apiKey(apiKey).build(); } Bean public ChatClient chatClient(ChatModel dashScopeChatModel) { return ChatClient.builder(dashScopeChatModel).build(); } }RestController public class ChatClient_V2_Controller { Resource private ChatClient chatClient; GetMapping(/client1) public String doClient1(RequestParam(value msg ,defaultValue 请简单介绍侯莫陈崇) String msg) { return chatClient.prompt().user(msg).call().content(); } }第二种方式在controller里通过构造方法创建——不推荐RestController public class ChatClientController { private final ChatClient chatClient; public ChatClientController(ChatModel dashScopeChatModel) { this.chatClient ChatClient.builder(dashScopeChatModel).build(); } GetMapping(/client) public String doClient(RequestParam(value msg ,defaultValue 南北朝时期最勇猛的将领是谁) String msg) { return chatClient.prompt().user(msg).call().content(); } }4.4 两者对比五、同时使用多个模型实现流式输出5.1 流式输出介绍1、流式输出(StreamingOutput)是一种逐步返回大模型生成结果的技术生成一点返回一点允许服务器将响应内容分批次实时传输给客户端而不是等待全部内容生成完毕后再一次性返回。这种机制能显著提升用户体验尤其适用于大模型响应较慢的场景如生成长文本或复杂推理结果2、实现方式Spring AI Alibaba两种流式输出分别为ChatModel和ChatClient。5.2 SSE(Server-Sent Events)服务器发送事件Server-Sent由服务器发送。Events事件指服务器主动推送给客户端的数据或消息。Server-SentEvents(SSE)服务器发送事件实现流式输出。Server-Sent Events (SSE) 是一种允许服务端可以持续推送数据片段如逐词或逐句到前端的 Web 技术。通过单向的HTTP长连接使用一个长期存在的连接让服务器可以主动将数据推给客户端SSE是轻量级的单向通信协议适合AI对话这类服务端主导的场景核心概念SSE 的核心思想是客户端发起一个请求服务器保持这个连接打开并在有新数据时通过这个连接将数据发送给客户端。这与传统的请求-响应模式客户端请求一次服务器响应一次连接关闭有本质区别。SSE下一代Stream able Http。总结一种让服务器能够主动、持续地向客户端比如你的网页浏览器推送数据的技术。SSE适用场景5.3 多模型共存开发1、创建子模块项目结构2、修改pom.xmldependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !--spring-ai-alibaba dashscope-- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId /dependency !--lombok-- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId version1.18.38/version /dependency !--hutool-- dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.22/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version3.11.0/version configuration compilerArgs arg-parameters/arg /compilerArgs source21/source target21/target /configuration /plugin /plugins /build repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositories3、新增配置文件server.port8888 #解决中文乱码 server.servlet.encoding.charsetUTF-8 server.servlet.encoding.enabledtrue server.servlet.encoding.forcetrue spring.application.namessa-01-HelloWorld #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key${qianwen-api} spring.ai.dashscope.base-urlhttps://ws-6tq01jo6mtthlhoq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 #spring.ai.dashscope.chat.options.modelqwen-max4、创建启动类SpringBootApplication public class SSA_04_Stream_OutputApplication { public static void main(String[] args) { SpringApplication.run(SSA_04_Stream_OutputApplication.class, args); } }5、新增配置类-创建ChatModel对象Configuration public class LLMConfig { //定义各个模型名称 private final String DEEPSEEK_MODEL deepseek-v4-pro; private final String QWEN_MODEL qwen-max; //创建deepseek的ChatModel Bean(name deepseek) public ChatModel deepseek() { return DashScopeChatModel.builder().dashScopeApi( DashScopeApi.builder().apiKey(System.getenv(qianwen-api)).build()) .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build()) .build(); } //创建qwen的ChatModel Bean(name qwen) public ChatModel qwen() { return DashScopeChatModel.builder().dashScopeApi( DashScopeApi.builder().apiKey(System.getenv(qianwen-api)).build() ).defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build()) .build(); } }6、新增controller-使用ChatModel调用大模型RestController public class ChatModelController { Resource(name deepseek) private ChatModel deepseekChatModel; Resource(name qwen) private ChatModel qwenChatModel; GetMapping(/model/deepseek) public FluxString doDeepSeekModel(RequestParam(value msg,defaultValue 你是谁) String msg) { return deepseekChatModel.stream(msg); } GetMapping(/model/qwen) public FluxString doQwenModel(RequestParam(value msg,defaultValue 你是谁) String msg) { return qwenChatModel.stream(msg); } }7、新增配置类-创建ChatClient对象Configuration public class LLMConfig { //定义各个模型名称 private final String DEEPSEEK_MODEL deepseek-v4-pro; private final String QWEN_MODEL qwen-max; //创建deepseek的ChatModel Bean(name deepseek) public ChatModel deepseek() { return DashScopeChatModel.builder().dashScopeApi( DashScopeApi.builder().apiKey(System.getenv(qianwen-api)).build()) .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build()) .build(); } //创建qwen的ChatModel Bean(name qwen) public ChatModel qwen() { return DashScopeChatModel.builder().dashScopeApi( DashScopeApi.builder().apiKey(System.getenv(qianwen-api)).build() ).defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build()) .build(); } Bean(name deepseekChatClient) public ChatClient deepseekChatClient(Qualifier(deepseek) ChatModel deepseek) { return ChatClient.builder(deepseek) .defaultOptions(ChatOptions.builder().model(DEEPSEEK_MODEL).build()).build(); } Bean(name qwenChatClient) public ChatClient qwenChatClient(Qualifier(qwen) ChatModel qwen) { return ChatClient.builder(qwen).defaultOptions(ChatOptions.builder().model(QWEN_MODEL).build()).build(); } }8、创建controller-使用ChatClientdiaoyong 调用大模型RestController public class ChatModelController { Resource(name deepseek) private ChatModel deepseekChatModel; Resource(name qwen) private ChatModel qwenChatModel; Resource(name deepseekChatClient) private ChatClient deepseekChatClient; Resource(name qwenChatClient) private ChatClient qwenChatClient; GetMapping(/model/deepseek) public FluxString doDeepSeekModel(RequestParam(value msg,defaultValue 你是谁) String msg) { return deepseekChatModel.stream(msg); } GetMapping(/model/qwen) public FluxString doQwenModel(RequestParam(value msg,defaultValue 你是谁) String msg) { return qwenChatModel.stream(msg); } GetMapping(/client/deepseek) public FluxString deDeepSeekClient(RequestParam(value msg,defaultValue 你是谁) String msg) { return deepseekChatClient.prompt(msg).stream().content(); } GetMapping(/client/qwen) public FluxString doQwenClient(RequestParam(value msg,defaultValue 你是谁) String msg){ return qwenChatClient.prompt(msg).stream().content(); } }5.4 Flux介绍Flux是SpringWebFlux中的一个核心组件属于响应式编程模型的一部分。它主要用于处理异步、非阻塞的流式数据能够高效地处理高并发场景。Flux可以生成和处理一系列的事件或数据如流式输出等。看类注释和类所在的jar包我们就明白SAA中的流式输出是通过ReactorStreams技术实现的和SpringWebFlux的底层实现是一样的技术。具体执行流程ReactorStreams会订阅数据源当有数据时ReactorStreams以分块流的方式发送给客户端用户。5.5 新增前端交互在/resoure/static添加index.html!DOCTYPE html html head titleSSE流式chat/title style body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 20px; } #messageInput { width: 90%; padding: 10px; font-size: 16px; border: 1px solid #ccc; border-radius: 4px; margin-bottom: 10px; } button { padding: 10px 20px; font-size: 16px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; } button:hover { background-color: #0056b3; } #messages { margin-top: 20px; padding: 15px; background-color: #f9f9f9; border: 1px solid #ddd; border-radius: 8px; max-height: 300px; overflow-y: auto; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } #messages div { padding: 8px 0; border-bottom: 1px solid #eee; font-size: 14px; color: #333; } #messages div:last-child { border-bottom: none; } /style /head body textarea idmessageInput rows4 cols50 placeholder请输入你的问题.../textareabr button onclicksendMsg()发送提问/button div idmessages/div script function sendMsg() { // 获取用户输入的消息 const message document.getElementById(messageInput).value; if (message ) return false; //1 客户端使用 JavaScript 的 EventSource 对象连接到服务器上的一个特定端点URL const eventSource new EventSource(client/qwen?question message); //2 监听消息事件 eventSource.onmessage function (event) { // 获取流式返回的数据 const data event.data; // 将接收到的数据展示到页面上 const messagesDiv document.getElementById(messages); messagesDiv.innerHTML event.data; }; //3 监听错误事件 eventSource.onerror function (error) { console.error(EventSource 发生错误, error); eventSource.close(); // 关闭连接 }; } /script /body /html修改对应的controllerGetMapping(/client/qwen) public FluxString doQwenClient(RequestParam(value question) String msg){ return qwenChatClient.prompt(msg).stream().content(); }启动后输入http://localhost:8888/index.html
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门