SpringBoot调用通义千问

2024-08-27 22:28

本文主要是介绍SpringBoot调用通义千问,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

提示:今日花了2个小时搞定了一个简易版的AI对话功能

文章目录

目录

文章目录

SpringBoot代码

引入库

controller

返回对象类

工具类

前端代码

 ​编辑

 效果展示

 后端返回



SpringBoot代码

当然我只做了一个简易版的AI对话,你可以在我的基础之上进行改动

引入库

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java --><dependency><groupId>com.alibaba</groupId><artifactId>dashscope-sdk-java</artifactId><version>2.13.0</version></dependency>

controller

package com.xinggui.demo.controller;import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.xinggui.demo.domain.Response;
import com.xinggui.demo.util.ApiTestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@Slf4j
@CrossOrigin(origins = "http://127.0.0.1:5500") // 假设前端在3000端口运行
public class test {@PostMapping("/test")public Response test(String problem){if(problem.length() == 0){return new Response("-1","请输入问题",null);}String result = null;try {result = ApiTestUtil.getProblem(problem);} catch (NoApiKeyException e) {log.error("apiKey错误");} catch (InputRequiredException e) {log.error("输入为空");}return new Response("0","success",result);}
}

返回对象类

package com.xinggui.demo.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Response {private String code;private String msg;private Object data;}

工具类

package com.xinggui.demo.util;import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;
import io.reactivex.Flowable;import java.util.Arrays;
import java.util.concurrent.Semaphore;public class ApiTestUtil {public static String getProblem(String problem) throws NoApiKeyException, InputRequiredException {Constants.apiKey = "请填写你自己的API-key";// 实例化生成器对象Generation gen = new Generation();// 构建用户消息,角色为USER,内容为中国首都的介绍Message userMsg =Message.builder().role(Role.USER.getValue()).content(problem).build();// 构建生成参数,包括模型名称、消息列表、结果格式等GenerationParam param = GenerationParam.builder().model("qwen-max") // 选择使用的模型.messages(Arrays.asList(userMsg)) // 用户的询问消息.resultFormat(GenerationParam.ResultFormat.MESSAGE) // 结果以消息格式返回.topP(0.8).enableSearch(true) // 设置搜索启用及topP参数.incrementalOutput(true) // 以增量方式获取流式输出.build();// 调用生成器的流式调用方法,返回结果为一个Flowable流Flowable<GenerationResult> result = gen.streamCall(param);// 使用StringBuilder来拼接完整的回复内容StringBuilder fullContent = new StringBuilder();// 阻塞方式处理每一个流式输出的消息,并打印出来result.blockingForEach(message -> {// 将当前消息的内容追加到完整内容中fullContent.append(message.getOutput().getChoices().get(0).getMessage().getContent());// 打印当前的消息内容(JSON格式)System.out.println(JsonUtils.toJson(message));});// 打印最终的完整内容System.out.println("Full content: \n" + fullContent.toString());return fullContent.toString();}
}

前端代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AI Chat Interface</title><!-- 引入 Vue 3 的 CDN --><script src="https://unpkg.com/vue@3/dist/vue.global.js"></script><style>/* 样式 */body {font-family: Avenir, Helvetica, Arial, sans-serif;background-color: #f4f4f9;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;}.chat-container {display: flex;flex-direction: column;height: 80vh;width: 80vw;max-width: 600px;border: 1px solid #ccc;border-radius: 10px;overflow: hidden;background-color: #fff;}.chat-window {flex: 1;padding: 10px;overflow-y: auto;background-color: #f4f4f9;position: relative;}.chat-message {display: flex;margin-bottom: 10px;align-items: flex-start;}.message-left {flex-direction: row;}.message-right {flex-direction: row-reverse;}.avatar {width: 40px;height: 40px;border-radius: 50%;background-color: #007bff;display: flex;justify-content: center;align-items: center;color: white;font-weight: bold;margin: 0 10px;}.message-bubble {max-width: 70%;padding: 10px;border-radius: 20px;background-color: #007bff;color: white;word-wrap: break-word;}.message-left .message-bubble {background-color: #e4e6eb;color: black;}.chat-input {display: flex;padding: 10px;border-top: 1px solid #ccc;background-color: #fff;}.chat-input input {flex: 1;padding: 10px;border: 1px solid #ccc;border-radius: 20px;outline: none;}.chat-input button {margin-left: 10px;padding: 10px 20px;border: none;background-color: #007bff;color: white;border-radius: 20px;cursor: pointer;outline: none;}.chat-input button:hover {background-color: #0056b3;}/* From Uiverse.io by SchawnnahJ */ .loader {position: relative;width: 2.5em;height: 2.5em;transform: rotate(165deg);}.loader:before, .loader:after {content: "";position: absolute;top: 50%;left: 50%;display: block;width: 0.5em;height: 0.5em;border-radius: 0.25em;transform: translate(-50%, -50%);}.loader:before {animation: before8 2s infinite;}.loader:after {animation: after6 2s infinite;}@keyframes before8 {0% {width: 0.5em;box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);}35% {width: 2.5em;box-shadow: 0 -0.5em rgba(225, 20, 98, 0.75), 0 0.5em rgba(111, 202, 220, 0.75);}70% {width: 0.5em;box-shadow: -1em -0.5em rgba(225, 20, 98, 0.75), 1em 0.5em rgba(111, 202, 220, 0.75);}100% {box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);}}@keyframes after6 {0% {height: 0.5em;box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);}35% {height: 2.5em;box-shadow: 0.5em 0 rgba(61, 184, 143, 0.75), -0.5em 0 rgba(233, 169, 32, 0.75);}70% {height: 0.5em;box-shadow: 0.5em -1em rgba(61, 184, 143, 0.75), -0.5em 1em rgba(233, 169, 32, 0.75);}100% {box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);}}.loading {position: relative;bottom: -20px;display: flex;align-items: center;justify-content: center;}</style>
</head>
<body><div id="app"><div class="chat-container"><div class="chat-window"><div v-for="(message, index) in messages" :key="index" class="chat-message" :class="{'message-left': message.isUser, 'message-right': !message.isUser}"><div class="avatar">{{ message.isUser ? '自己' : 'AI' }}</div><div class="message-bubble">{{ message.text }}</div></div><div class="loading"  v-if="loading"><div style="display: flex;align-items: center;justify-content: center;"><div class="loader"></div><div style="margin-left: 10px;font-weight: bold; color: #e64c87;">加载中</div></div></div></div><div class="chat-input"><input v-model="userInput" @keydown.enter="sendMessage" placeholder="Type your question..." /><button @click="sendMessage">Send</button></div></div></div><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>const { createApp } = Vue;createApp({data() {return {userInput: '',messages: [{ text: '你有什么需要问的问题吗?', isUser: false }],loading:false};},methods: {sendMessage() {if (this.userInput.trim()) {// 添加用户的消息this.messages.push({ text: this.userInput, isUser: true });// 模拟AI回复(你可以在这里调用AI的接口)this.simulateAIResponse(this.userInput);// 清空输入框this.userInput = '';}},async simulateAIResponse(userText) {this.loading = true;const res =await axios.post("http://localhost:8888/test", {"problem": this.userInput},{ headers: { "Content-Type": "multipart/form-data" } })this.messages.push({text: `AI回答内容: ${res.data.data}`,isUser: false,});this.loading = false;},},}).mount('#app');</script>
</body>
</html>

这里我使用VScode中的liveServer插件,启动项目

后端对http://127.0.0.1:5500做了跨域配置

 

 

 效果展示

 这里还添加了一个Loading效果

 

 后端返回

 今日时间2024年8月27日,希望可以帮助到你

这篇关于SpringBoot调用通义千问的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112952

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Java中的.close()举例详解

《Java中的.close()举例详解》.close()方法只适用于通过window.open()打开的弹出窗口,对于浏览器的主窗口,如果没有得到用户允许是不能关闭的,:本文主要介绍Java中的.... 目录当你遇到以下三种情况时,一定要记得使用 .close():用法作用举例如何判断代码中的 input

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S