当前位置: 首页 > news >正文

Spring Boot 整合讯飞星火3.5通过接口Api接口实现聊天功能(首发)复制粘贴即可使用,后续更新WebSocket实现聊天功能

程序员必备网站:

天梦星服务平台 (tmxkj.top)icon-default.png?t=N7T8https://tmxkj.top/#/

1.pom.xml

        <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.72</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId></dependency><dependency><groupId>org.jetbrains</groupId><artifactId>annotations</artifactId><version>13.0</version><scope>compile</scope></dependency>
spark:ai:hostUrl: https://spark-api.xf-yun.com/v3.5/chatappId: ####apiSecret: #####apiKey: ######

2.实体类

import cn.hutool.json.JSONObject;
import lombok.Data;@Data
public class SparkDto {private JSONObject payload;private JSONObject parameter;private JSONObject header;
}
@Data
public class SparkParamDto {private String content;
}

 

3.Tool工具类


import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.example.springbootServiceNetwork.demos.web.Config.JwtInfo;
import com.example.springbootServiceNetwork.demos.web.Dto.SparkDto;
import com.example.springbootServiceNetwork.demos.web.Dto.SparkParamDto;
import okhttp3.HttpUrl;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;/*** 讯飞星火工具类*/
public class SparkUtil {/*** 构建 鉴权方法* @param hostUrl* @param apiKey* @param apiSecret* @return* @throws Exception*/public static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {URL url = new URL(hostUrl);// 时间SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);format.setTimeZone(TimeZone.getTimeZone("GMT"));String date = format.format(new Date());// 拼接String preStr = "host: " + url.getHost() + "\n" +"date: " + date + "\n" +"GET " + url.getPath() + " HTTP/1.1";// System.err.println(preStr);// SHA256加密Mac mac = Mac.getInstance("hmacsha256");SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");mac.init(spec);byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));// Base64加密String sha = Base64.getEncoder().encodeToString(hexDigits);// System.err.println(sha);// 拼接String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);// 拼接地址HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().//addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).//addQueryParameter("date", date).//addQueryParameter("host", url.getHost()).//build();// System.err.println(httpUrl.toString());return httpUrl.toString();};/*** 构建请求参数* @param jwtInfo* @param appId* @param sparkParam* @return* @throws Exception*/public static String getSparkJson(JwtInfo jwtInfo, String appId, SparkParamDto sparkParam) throws Exception {SparkDto sprarkDto = new SparkDto();//----------------payload-----------------JSONObject payload=new JSONObject();JSONObject message=new JSONObject();JSONArray text=new JSONArray();JSONObject textObj=new JSONObject();textObj.put("role","user");textObj.put("content",sparkParam.getContent());text.add(textObj);message.put("text",text);payload.put("message",message);sprarkDto.setPayload(payload);//----------------parameter-----------------JSONObject parameter=new JSONObject(); // parameter参数JSONObject chat=new JSONObject();chat.put("domain","generalv2");chat.put("temperature",0.5);chat.put("max_tokens",2000);parameter.put("chat",chat);sprarkDto.setParameter(parameter);//----------------header-----------------JSONObject header = new JSONObject();header.put("app_id", appId);header.put("uid", jwtInfo.getUserId());sprarkDto.setHeader(header);return JSON.toJSONString(sprarkDto);}}

4.业务层

     图片解析

import com.example.springbootServiceNetwork.demos.web.Config.JwtInfo;
import com.example.springbootServiceNetwork.demos.web.Config.Result;
import com.example.springbootServiceNetwork.demos.web.Dto.SparkParamDto;public interface SparkService {Result SparkChat(SparkParamDto sparkParam, JwtInfo jwtInfo);
}
@Service
public class SparkServiceImpl implements SparkService {@Value("${spark.ai.hostUrl}")private  String  hostUrl;@Value("${spark.ai.appId}")private  String appId;@Value("${spark.ai.apiSecret}")private  String apiSecret;@Value("${spark.ai.apiKey}")private  String apiKey;@Overridepublic Result SparkChat(SparkParamDto sparkParamDto, JwtInfo jwtInfo) {Result result = new Result();try {// 构建鉴权urlString authUrl = getAuthUrl(hostUrl, apiKey, apiSecret);OkHttpClient client = new OkHttpClient.Builder().build();String url = authUrl.toString().replace("http://", "ws://").replace("https://", "wss://");Request request = new Request.Builder().url(url).build();String body = getSparkJson(jwtInfo,appId,sparkParamDto);StringBuilder builderSb =new StringBuilder();CompletableFuture<String> messageReceived = new CompletableFuture<>();WebSocket webSocket = client.newWebSocket(request, new WebSocketListener(){@Overridepublic void onOpen(WebSocket webSocket, Response response) {webSocket.send(body);}@Overridepublic void onMessage(WebSocket webSocket, String res) {JSONObject obj = JSON.parseObject(res);String str= obj.getJSONObject("payload").getJSONObject("choices").getJSONArray("text").getJSONObject(0).getString("content");builderSb.append(str);if(obj.getJSONObject("header").getLong("status")==2){webSocket.close(1000, "Closing WebSocket connection");messageReceived.complete(res); // 将收到的消息传递给 CompletableFuture}}});String resItem = messageReceived.get(30, TimeUnit.SECONDS);; // 阻塞等待消息返回webSocket.close(1000, "Closing WebSocket connection");result.setData(builderSb.toString());result.setCode(200);result.setMsg("天梦星");}catch (Exception e){e.printStackTrace();}return result;}}

5.控制层

import com.example.springbootServiceNetwork.demos.web.Config.JwtInfo;
import com.example.springbootServiceNetwork.demos.web.Config.Result;
import com.example.springbootServiceNetwork.demos.web.Dto.SparkParamDto;
import com.example.springbootServiceNetwork.demos.web.Service.JwtRedistService;
import com.example.springbootServiceNetwork.demos.web.Service.SparkService;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@RestController
@RequestMapping("/Spark")
public class SparkController {@Resourceprivate SparkService sparkService;@Resourceprivate JwtRedistService jwtRedistService;@PostMapping("/chat")public Result SparkChatApi(@RequestBody SparkParamDto sparkParam, @RequestHeader("token") String token){JwtInfo jwtInfo = jwtRedistService.getUserInfo(token);if(jwtInfo.getPass()){return sparkService.SparkChat(sparkParam,jwtInfo);}else {return jwtInfo.getResult();}}
}

6.测试

http://localhost:8082/Spark/chat{"content":"帮我写一份本地js模糊查询"
}{"code": 200,"msg": "天梦星","data": "以下是一个简单的本地 JavaScript 模糊查询的示例代码:\n\n```javascript\n// 假设有一个数据列表,包含商品的名称和价格\nconst products = [\n  { name: \"苹果\", price: 1.99 },\n  { name: \"香蕉\", price: 0.99 },\n  { name: \"橙子\", price: 2.49 },\n  { name: \"草莓\", price: 3.99 },\n];\n\n// 实现模糊查询函数\nfunction searchProducts(keyword) {\n  // 将关键字转换为小写,以忽略大小写的差异\n  const lowerCaseKeyword = keyword.toLowerCase();\n\n  // 使用数组的 filter 方法进行模糊查询\n  const results = products.filter((product) => {\n    // 将商品名称转换为小写,并使用 includes 方法检查是否包含关键字\n    return product.name.toLowerCase().includes(lowerCaseKeyword);\n  });\n\n  return results;\n}\n\n// 测试模糊查询函数\nconst keyword = \"果\"; // 输入要查询的关键字\nconst searchResults = searchProducts(keyword);\nconsole.log(searchResults);\n```\n\n上述代码中,我们首先定义了一个包含商品名称和价格的数据列表 `products`。然后实现了一个 `searchProducts` 函数,该函数接受一个关键字作为参数,并返回包含该关键字的商品列表。在函数内部,我们将关键字转换为小写,并使用数组的 `filter` 方法对商品列表进行模糊查询。最后,我们通过调用 `searchProducts` 函数并打印结果来进行测试。"
}

 备注:这步骤是我的业务流程,你可以省略不写

JwtInfo jwtInfo = jwtRedistService.getUserInfo(token);

返回数据格式,已有忽略

@Data
public class Result {private Integer code;//状态码private Object msg;//状态信息或者报错信息private Object data;//返回数据private Integer count;//总条数
}

已经三天没吃饭了,大佬行行好

 

相关文章:

Spring Boot 整合讯飞星火3.5通过接口Api接口实现聊天功能(首发)复制粘贴即可使用,后续更新WebSocket实现聊天功能

程序员必备网站&#xff1a; 天梦星服务平台 (tmxkj.top)https://tmxkj.top/#/ 1.pom.xml <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.72</version></dependency><depen…...

信息系统项目管理师——十大管理过程输入、工具和技术、输出(论文篇)一

一、项目整合管理 制定项目章程 在项目管理中&#xff0c;制定项目章程是一个关键的初始过程&#xff0c;它正式授权项目的开始并为项目设定高层次的方向。项目章程的编制涉及特定的输入、采用的工具和技术&#xff0c;以及产生的输出。以下是这些方面的详细说明&#xff1a;…...

Java——代码块

1、概念分类 使用 {} 定义的一段代码称为代码块&#xff0c;根据代码块定义的位置以及关键字&#xff0c;可分为以下四种 普通代码块静态代码块构造代码块同步代码块 2、普通代码块 定义在方法中的代码块&#xff0c;这种用法较少见&#xff1a; 3、构造代码块 构造块&…...

Ajax额

原生Ajax xml 已被json取代 http 请求方法urlhttp版本号 network 谷歌浏览器查看请求报文和响应报文 F12 network header里面有 请求头 响应头 点击view source 可以查看请求响应行 请求体在请求行头下面 get请求有url参数&#xff0c;请求体变为query String…...

5.15项目进度总结

今天完成了随机选人和实时显示的功能&#xff08;还需要维护&#xff09;&#xff0c;使得程序可以对用户的操作进行实时的显示。 实时显示的思路&#xff1a;在登录后开一个线程用一个socket去链接服务端并查询需要实时的信息&#xff0c;同时服务端把这个socket记录下来&…...

POETIZE个人博客系统源码 | 最美博客

简介&#xff1a; POETIZE个人博客系统源码 | 最美博客 这是一个 SpringBoot Vue2 Vue3 的产物&#xff0c;支持移动端自适应&#xff0c;配有完备的前台和后台管理功能。 网站分两个模块&#xff1a; 博客系统&#xff1a;具有文章&#xff0c;表白墙&#xff0c;图片墙&…...

回复完成 输入框还显示值的问题

回复完成 输入框还显示值的问题 解决代码 先把id 值清空 再构建下这个输入框 $("#details_article_reply_content").val(""); // 清空textareavar editor editormd("article_details_reply", {width: "100%",height: "100%"…...

C语言----斐波那契数列(附源代码)

各位看官们好&#xff0c;当我写了上一篇博客杨辉三角后&#xff0c;有一些看官叫我讲一下斐波那契数列。对于这个大家应该是有了解的。最简单的规律就是f(n)f(n-2)f(n-1)。就是当前是前两项之和&#xff0c;然后下标1和0都是1.从第三项开始计算的。那么我们知道规律&#xff0…...

javax.net.ssl.SSLException: Received fatal alert: protocol_version已经解决

起因&#xff1a; 在帮别人讲解项目时&#xff0c;将项目的tomcat配置完&#xff0c;点击运行后&#xff0c;报错&#xff0c;信息如标题。 解决办法&#xff1a; 在csdn百度问题&#xff0c;得到的方法主要有几个&#xff1a; 1.jdk要配置在1.8以上&#xff1b; 2.数据库地…...

uniapp 实现下拉刷新 下滑更新

效果图 在app或者小程序中向下滑动 会出现刷新数据 ,而上拉到底 需要更新数据 功能实现 主要俩种方式 依赖生命周期 在page.json中开启 page.json "style" : {"navigationBarTitleText" : "小小练习","backgroundTextStyle": &qu…...

海豚调度器如何看工作流是在哪个worker节点执行

用海豚调度器&#xff0c;执行一个工作流时&#xff0c;有时成功&#xff0c;有时失败&#xff0c;怀疑跟worker节点环境配置不一样有关。要怎样看是在哪个worker节点执行&#xff0c;在 海豚调度器 Web UI 中&#xff0c;您可以查看任务实例&#xff0c;里面有一列显示host&a…...

凸优化理论学习三|凸优化问题(一)

系列文章目录 凸优化理论学习一|最优化及凸集的基本概念 凸优化理论学习二|凸函数及其相关概念 文章目录 系列文章目录一、优化问题&#xff08;一&#xff09;标准形式的优化问题&#xff08;二&#xff09;可行点和最优点&#xff08;三&#xff09;局部最优点&#xff08;四…...

【Unity Shader入门精要 第7章】基础纹理补充内容:MipMap原理

1.纹理采样 我们对纹理采样进行显示的过程&#xff0c;可以理解为将屏幕上的一个像素&#xff08;下文用像素表示&#xff09;映射到纹理上的一个像素&#xff08;下文用纹素表示&#xff09;&#xff0c;然后用纹理上的这个像素的颜色进行显示。 理想情况下&#xff0c;屏幕…...

JeeSite Vue3:前端开发页面如何动态设置菜单展示模式?

推荐阅读&#xff1a; JeeSite Vue3&#xff1a;前端开发的未来之路(更新版) 随着技术的飞速发展&#xff0c;前端开发技术日新月异。在这个背景下&#xff0c;JeeSite Vue3 作为一个基于 Vue3、Vite、Ant-Design-Vue、TypeScript 和 Vue Vben Admin 的前端框架&#xff0c;引…...

微信小程序-禁止页面下拉回弹

微信小程序-禁止页面下拉回弹,主要是pages.json中的这3个配置: "enablePullDownRefresh": false, 这个配置项用于控制页面是否支持下拉刷新。当设置为false时&#xff0c;用户无法通过下拉页面来触发刷新操作。 "disableScroll": true, 这个配置项用于控…...

测试环境搭建整套大数据系统(十六:超级大文件处理遇到的问题)

一&#xff1a;yarn出现损坏的nodemanger 报错现象 日志&#xff1a;1/1 local-dirs usable space is below configured utilization percentage/no more usable space [ /opt/hadoop-3.2.4/data/nm-local-dir : used space above threshold of 90.0% ] ; 1/1 log-dirs usabl…...

C++ 并发编程指南(11)原子操作 | 11.6、计算机内存结构

文章目录 一、计算机内存结构1、内存的基本组成2、内存的类型3、内存的结构层次4、CPU架构5、局部性原理6、总结 前言 在探讨计算机的运行效率和数据处理能力时&#xff0c;内存结构无疑是一个至关重要的部分。内存&#xff0c;作为计算机系统中的关键组件&#xff0c;承担着存…...

正则表达式教程

正则表达式在线工具网站&#xff1a;https://regexr.com...

SEO之为什么研究关键词(二)

初创企业需要建站的朋友看这篇文章&#xff0c;谢谢支持&#xff1a; 我给不会敲代码又想搭建网站的人建议 新手上云 &#xff08;续上一篇。。。。。&#xff09; 3、寻找有效流量 排名和流量都不是目的&#xff0c;有效流量带来的转化才是目的。就算公司有足够的实力将一些…...

Mysql 创建索引

1. 在创建表时添加索引 在使用CREATE TABLE语句创建表的同时&#xff0c;可以直接定义索引。例如&#xff0c;创建一个包含索引的表&#xff1a; CREATE TABLE clothes (id INT PRIMARY KEY,c_brand VARCHAR(100),c_type VARCHAR(50),c_size VARCHAR(10),price DECIMAL(10, 2…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...