关于java 调用阿里千问大模型,流式返回,并返回给前端
aaff
FLux曹,找了那么多案例,没一个靠谱的,还得东拼西凑。具体方法类
maven 这两个应该就够用
<!--ai调用--> <dependency> <groupId>com.alibaba</groupId> <artifactId>dashscope-sdk-java</artifactId> <version>2.19.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>@GetMapping(value = "/aiTestTwo", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> simpleStream() throws NoApiKeyException, InputRequiredException { // 直接返回一个 Flux,每个元素会立即发送给前端 Generation gen = new Generation(); Message systemMsg = Message.builder() .role(Role.SYSTEM.getValue()) .content("You are a helpful assistant.") .build(); Message userMsg = Message.builder() .role(Role.USER.getValue()) .content("你是谁?") .build(); GenerationParam param = GenerationParam.builder() // 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:.apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY"))//DASHSCOPE_API_KEY // 模型列表:https://help.aliyun.com/model-studio/getting-started/models .model("qwen-plus") .messages(Arrays.asList(systemMsg, userMsg)) .resultFormat(GenerationParam.ResultFormat.MESSAGE) .incrementalOutput(true) .build(); Flowable<GenerationResult> flowable = gen.streamCall(param); return Flux.from(flowable) .publishOn(Schedulers.boundedElastic()) .map(result -> result.getOutput().getChoices().get(0).getMessage().getContent()) .filter(content -> content != null && !content.isEmpty()); }或者sse调用
@GetMapping(value = "/aiTestTwo", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter simpleStream() throws NoApiKeyException, InputRequiredException { SSE sse = new SSE(60000L); // 直接返回一个 Flux,每个元素会立即发送给前端 Generation gen = new Generation(); Message systemMsg = Message.builder() .role(Role.SYSTEM.getValue()) .content("You are a helpful assistant.") .build(); Message userMsg = Message.builder() .role(Role.USER.getValue()) .content("你是谁?") .build(); GenerationParam param = GenerationParam.builder() // 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:.apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY"))//DASHSCOPE_API_KEY // 模型列表:https://help.aliyun.com/model-studio/getting-started/models .model("qwen-plus") .messages(Arrays.asList(systemMsg, userMsg)) .resultFormat(GenerationParam.ResultFormat.MESSAGE) .incrementalOutput(true) .build(); /*Flowable<GenerationResult> flowable = gen.streamCall(param);*/ gen.streamCall(param).forEach(result -> { System.out.println(result); System.out.println(result.getOutput()); System.out.println(result.getOutput().getChoices()); System.out.println(result.getOutput().getChoices().get(0)); System.out.println(result.getOutput().getChoices().get(0).getMessage()); System.out.println("122212121212"+result.getOutput().getChoices().get(0).getMessage().getContent()); String chunk = result.getOutput().getChoices().get(0).getMessage().getContent(); System.out.print(chunk); // 逐字输出,模拟打字机效果 sse.send(chunk); /* sse.send(SseEmitter.event() .name("message") .data(chunk));*/ }); /*sse.complete();*/ return sse; }html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>SSE 流式测试</title> </head> <body> <h1>SSE 流式数据接收测试</h1> <button onclick="startConnect()">开始连接</button> <button onclick="stopConnect()">断开连接</button> <hr/> <div id="message-box" style="border:1px solid #ccc; padding:10px; min-height:100px;"></div> <script> let eventSource = null; function startConnect() { const box = document.getElementById('message-box'); box.innerText = "正在连接...\n"; // 1. 创建 EventSource 对象,指向后端接口 eventSource = new EventSource('/user/aiTestTwo'); // 2. 监听消息事件 (默认事件名为 'message') eventSource.onmessage = function(event) { // event.data 就是后端 emitter.send() 发送的内容 console.log("收到数据:", event.data); box.innerText += event.data; }; // 3. 监听自定义事件 (如果后端用了 .name("error")) eventSource.addEventListener('error', function(event) { console.error("收到错误:", event.data); box.innerText += "\n[错误]: " + event.data; }); // 4. 监听连接打开事件 eventSource.onopen = function(event) { console.log("连接已建立"); }; // 5. 监听连接关闭/错误事件 eventSource.onerror = function(event) { console.log("连接出错或关闭"); // EventSource 会自动重连,如果需要手动停止,需调用 close() // eventSource.close(); }; } function stopConnect() { if (eventSource) { eventSource.close(); eventSource = null; document.getElementById('message-box').innerText += "\n[连接已断开]"; } } </script> </body> </html>