关于java 调用阿里千问大模型,流式返回,并返回给前端

aaff

FLux曹,找了那么多案例,没一个靠谱的,还得东拼西凑。具体方法类

maven 这两个应该就够用

java 复制代码
   <!--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>
java 复制代码
  @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

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>
相关推荐
咖啡八杯3 分钟前
GoF设计模式——解释器模式
java·后端·spring·设计模式
不好听6136 分钟前
React 核心概念:JSX、组件与数据驱动
前端·react.js
触底反弹7 分钟前
🔥 React 零基础入门(中):500 行屎山代码到组件化的蜕变
前端·javascript·react.js
不好听6138 分钟前
React vs Vue:两大前端框架技术选型深度对比
前端·vue.js·react.js
GuWenyue9 分钟前
Cursor黑盒拆解!1套LangChain.js手写Mini编程Agent,自动生成React项目,效率提升60%
前端·数据库·人工智能
GuWenyue9 分钟前
传统Agent工具两大痛点!300行代码落地MCP跨语言工具,彻底解耦LLM与工具
前端·人工智能·算法
优橙教育16 分钟前
5G网优培训 vs Java开发:转行选哪个?
java·开发语言·5g
小林ixn1 小时前
从 onclick 到 React 合成事件,再到完整应用逻辑:一次前端架构的深度剖析
前端·react.js·前端框架
Csvn2 小时前
🧩「找不到模块」排查全记录——Monorepo 下 TypeScript 路径别名的 5 种「不通」与根治方案
前端
腻害兔2 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程