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实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

spring中的ImportSelector接口示例详解

《spring中的ImportSelector接口示例详解》Spring的ImportSelector接口用于动态选择配置类,实现条件化和模块化配置,关键方法selectImports根据注解信息返回... 目录一、核心作用二、关键方法三、扩展功能四、使用示例五、工作原理六、应用场景七、自定义实现Impor

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.