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;//總條數
}

已經三天沒吃飯了,大佬行行好

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/12065.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/12065.shtml
英文地址,請注明出處:http://en.pswp.cn/web/12065.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

html5關于WebSocket的一些特點與用例

WebSocket通信機制是一種在單個TCP連接上進行全雙工通信的協議&#xff0c;它允許服務器主動向客戶端推送數據&#xff0c;而無需等待客戶端的請求。以下是WebSocket通信的主要機制&#xff1a; 握手協議&#xff1a;WebSocket通信的第一步是通過HTTP協議進行握手。當客戶端發…

C++ QT設計模式:訪問者模式

基本概念 訪問者模式&#xff08;Visitor Pattern&#xff09;是一種行為型設計模式&#xff0c;它允許你在不改變被訪問類的前提下&#xff0c;定義對其進行操作的新操作。 實現的模塊有&#xff1a; ObjectStructure&#xff08;對象結構&#xff09;&#xff1a;用于存儲…

輕松拿下指針(5)

文章目錄 一、回調函數是什么二、qsort使用舉例三、qsort函數的模擬實現 一、回調函數是什么 回調函數就是?個通過函數指針調?的函數。 如果你把函數的指針&#xff08;地址&#xff09;作為參數傳遞給另?個函數&#xff0c;當這個指針被?來調?其所指向的函數 時&#x…

計算模型的邊界

https://github.com/libigl/libigl.git 這是幾何計算庫&#xff0c;可以計算出模型的邊界 #define _CRT_SECURE_NO_WARNINGS#include <iostream>#include <igl/boundary_loop.h>#include <igl/list_to_matrix.h>int main(){std::vector<std::vector<…

肺部營養“救星”,讓每次呼吸更自由

?#肺科營養#朗格力#班古營養#復合營養素#肺部營養# 正常的健康人,每天自由幸福的呼吸。但是對于肺病患者來說,特別是慢阻肺人群,每一次呼吸都可能是一場挑戰,每一口氣都顯得彌足珍貴。 肺病患者號稱沉默的“呼吸殺手”,它雖然沉默,但不代表它沒能力,除了引起肺功能下降,氧氣…

云商店如何讓更多企業摘到技術普惠的“果實”?

文 | 智能相對論 作者 | 沈浪 現階段&#xff0c;越是工業體系發達的地區&#xff0c;越需要加速技術普惠的步伐。比如&#xff0c;在蘇州&#xff0c;華為云就在聯合當地政府、企業伙伴打造以華為云云商店為重要鏈接的智能化商業增長底座。 華為云云商店以“電商式”的購物…

Git學習——遷移單一倉庫至其他代碼托管平臺

Git學習——遷移單一倉庫至其他代碼托管平臺 簡介流程總結 簡介 因需遷移單一代碼倉庫至其他代碼托管平臺&#xff0c;要遷移的包括倉庫內容以及所有歷史記錄和推送日志。 本文中的方法同樣適用于在同一代碼托管平臺中克隆倉庫。 流程 1. 創建新倉庫&#xff1a; 在目的平臺…

軟件需求規格文檔 (SRS) 模版

文章目錄 軟件需求規格文檔 (SRS) - 范例1. 引言1.1 目的1.2 范圍1.3 定義、縮寫和術語1.4 參考文獻1.5 總體描述 2. 系統概述2.1 系統環境2.2 系統功能概述2.3 用戶特性2.4 假設與約束 3. 功能需求3.1 用戶身份驗證模塊3.1.1 總體概述3.1.2 具體需求3.1.2.1 登錄功能描述3.1.2…

OpenAI春季發布會-免費多模態GPT4O-簡介

前言 2024.5.14&#xff0c;OpenAI宣布即將發布一款性能更為強大的大模型GPT4o&#xff0c;雖然沒有爆出些超級酷炫無敵吊炸天的新玩意&#xff0c;但是這次的多模態模型&#xff0c;大家可以免費用了~~&#xff08;但是&#xff09; 雖然是免費使用&#xff0c;但官方發布會上…

逆向學習記錄--第一天

NSSCTF工坊逆向綜合基礎第二題 考查知識點&#xff1a;ida的使用與編程能力 wp&#xff1a; 運行一下&#xff0c;沒有東西&#xff1b; 查殼是64位&#xff0c;沒有殼 直接ida打開 代碼解析&#xff1a;輸入flag&#xff0c;對flag進行用key進行輪換之后再加12&#xff…

鴻蒙 DevEcoStudio:用戶名密碼獲取保存

【使用首選項實現用戶名密碼保存獲取】 打開src/main/ets/entryability路徑下的EntryAbility.ts文件 在 export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {hilog.info(0x0000, testTag, %{public}s, Ability onCreate);下邊添加內容&…

C++:左值(引用)右值(引用)

〇、前言 本文會討論C中的左值&#xff0c;右值&#xff0c;左值引用&#xff0c;右值引用&#xff0c;以及會理清它們之間的關系。 一、左值與右值 &#xff08;一&#xff09;概述 1. 左值是一般指表達式結束后依然存在的持久化對象。右值指表達式結束時就不再存在的臨時…

334_C++_std::bind中使用shared_from_this()

std::bind(&HttpClient::getPwd, shared_from_this(), std::placeholders::_1, std::placeholders::_2);[ HttpClient繼承自NetObj,NetObj是父類,NetObj受到std::shared_pt

分析 vs2019 c++ 中的 decltype 與 declval

&#xff08;1&#xff09; decltype 可以讓推斷其參數的類型。按住 ctrl 點擊 decltype &#xff0c;會發現無法查閱 其定義 &#xff1a; &#xff08;2&#xff09; 但 STL 庫里咱們可以查閱函數 declval 的 定義&#xff0c;很短&#xff0c;摘抄如下&#xff1a; templat…

【氮化鎵】高溫GaN HEMTs大信號模型——ASM-HEMT

這篇文章的標題是《An ASM-HEMT for Large-Signal Modeling of GaN HEMTs in High-Temperature Applications》&#xff0c;由Nicholas C. Miller等人撰寫&#xff0c;發表于2023年9月29日。文章的主要內容是關于一種適用于高溫應用的GaN HEMTs&#xff08;高電子遷移率晶體管&…

Java 高級面試問題及答案1

Java 高級面試問題及答案 問題1: 請解釋Java中的垃圾回收機制&#xff0c;并描述其工作原理。 答案&#xff1a; Java中的垃圾回收&#xff08;Garbage Collection, GC&#xff09;是一種自動內存管理機制&#xff0c;用于識別和回收不再使用的對象&#xff0c;從而釋放內存資…

使用System.Drawing繪制基本幾何圖形

1.使用System.Drawing繪制一個正方形 using System; using System.Drawing; using System.Windows.Forms;public partial class MyForm : Form {public MyForm(){// 你可以在這里設置Form的雙緩沖&#xff0c;以避免繪制時出現的閃爍 this.DoubleBuffered true;}protected o…

LeetCode 每日一題 ---- 【1553.吃掉 N 個橘子的最少天數】

LeetCode 每日一題 ---- 【1553.吃掉 N 個橘子的最少天數】 1553.吃掉N個橘子的最少天數方法&#xff1a;記憶化搜索 1553.吃掉N個橘子的最少天數 方法&#xff1a;記憶化搜索 前兩天給樹澆水&#xff0c;原來澆的是橘子樹哇 今天直接來了個大的【困難】 class Solution {Ma…

Linux——緩沖區

一、問題引入 我們先來看看下面的代碼&#xff1a;我們使用了C語言接口和系統調用接口來進行文件操作。在代碼的最后&#xff0c;我們還使用fork函數創建了一個子進程。 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/wait.h&…

將jar打包成exe可安裝程序,并在html頁面喚醒

一、exe4j將jar打包成exe 1.exe4j下載 下載地址&#xff1a;https://www.ej-technologies.com/download/exe4j/files 2.exe4j打包jar 2.1. welcome 可以選擇歷史配置&#xff0c;新增則直接下一步 2.2. project type選擇“jar in exe” mode 2.3. application info設置應用…