DeepSeek API 调用 - Spring Boot 实现
DeepSeek API 调用 - Spring Boot 实现
1. 项目依赖
在 pom.xml 中添加以下依赖:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency>
</dependencies>
2. 项目结构
deepseek-project/
├── src/main/java/com/example/deepseek/
│ ├── DeepSeekApplication.java
│ ├── config/
│ │ └── DeepSeekConfig.java
│ ├── model/
│ │ ├── ChatRequest.java
│ │ ├── ChatResponse.java
│ │ └── Message.java
│ └── service/
│ └── DeepSeekService.java
└── conversation.txt
3. 完整代码实现
3.1 配置类 DeepSeekConfig.java
package com.example.deepseek.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;@Configuration
@Getter
public class DeepSeekConfig {@Value("${deepseek.api.url}")private String apiUrl;@Value("${deepseek.api.key}")private String apiKey;
}
3.2 请求/响应模型
Message.java:
package com.example.deepseek.model;import lombok.Data;@Data
public class Message {private String role;private String content;
}
ChatRequest.java:
package com.example.deepseek.model;import lombok.Data;
import java.util.List;@Data
public class ChatRequest {private String model = "deepseek-ai/DeepSeek-V3";private List<Message> messages;private boolean stream = true;private int max_tokens = 2048;private double temperature = 0.7;private double top_p = 0.7;private int top_k = 50;private double frequency_penalty = 0.5;private int n = 1;private ResponseFormat response_format = new ResponseFormat("text");@Datapublic static class ResponseFormat {private String type;public ResponseFormat(String type) {this.type = type;}}
}
ChatResponse.java:
package com.example.deepseek.model;import lombok.Data;
import java.util.List;@Data
public class ChatResponse {private List<Choice> choices;@Datapublic static class Choice {private Delta delta;}@Datapublic static class Delta {private String content;}
}
3.3 服务类 DeepSeekService.java
package com.example.deepseek.service;import com.example.deepseek.config.DeepSeekConfig;
import com.example.deepseek.model.ChatRequest;
import com.example.deepseek.model.ChatResponse;
import com.example.deepseek.model.Message;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Scanner;@Service
@RequiredArgsConstructor
public class DeepSeekService {private final DeepSeekConfig config;private final WebClient.Builder webClientBuilder;private final ObjectMapper objectMapper = new ObjectMapper();public void startInteractiveChat() {try (Scanner scanner = new Scanner(System.in);PrintWriter fileWriter = new PrintWriter(new FileWriter("conversation.txt", true))) {while (true) {System.out.print("\n请输入您的问题 (输入 q 退出): ");String question = scanner.nextLine().trim();if ("q".equalsIgnoreCase(question)) {System.out.println("程序已退出");break;}// 保存问题saveToFile(fileWriter, question, true);// 发起对话请求Flux<String> responseFlux = sendChatRequest(question);StringBuilder fullResponse = new StringBuilder();responseFlux.doOnNext(chunk -> {System.out.print(chunk);fullResponse.append(chunk);}).doOnComplete(() -> {// 保存完整回复saveToFile(fileWriter, fullResponse.toString(), false);System.out.println("\n----------------------------------------");fileWriter.println("\n----------------------------------------");fileWriter.flush();}).blockLast();}} catch (IOException e) {e.printStackTrace();}}private Flux<String> sendChatRequest(String question) {ChatRequest request = new ChatRequest();Message userMessage = new Message();userMessage.setRole("user");userMessage.setContent(question);request.setMessages(Collections.singletonList(userMessage));return webClientBuilder.build().post().uri(config.getApiUrl()).header("Authorization", "Bearer " + config.getApiKey()).header("Content-Type", "application/json").bodyValue(request).retrieve().bodyToFlux(String.class).filter(line -> line.startsWith("data: ") && !line.equals("data: [DONE]")).map(line -> {try {String jsonStr = line.substring(6);ChatResponse response = objectMapper.readValue(jsonStr, ChatResponse.class);return response.getChoices().get(0).getDelta().getContent();} catch (Exception e) {return "";}}).filter(content -> !content.isEmpty());}private void saveToFile(PrintWriter fileWriter, String content, boolean isQuestion) {String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));if (isQuestion) {fileWriter.printf("\n[%s] Question:\n%s\n\n[%s] Answer:\n", timestamp, content, timestamp);} else {fileWriter.print(content);}fileWriter.flush();}
}
3.4 主应用类 DeepSeekApplication.java
package com.example.deepseek;import com.example.deepseek.service.DeepSeekService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class DeepSeekApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(DeepSeekApplication.class, args);DeepSeekService deepSeekService = context.getBean(DeepSeekService.class);deepSeekService.startInteractiveChat();}
}
3.5 配置文件 application.properties
deepseek.api.url=https://api.siliconflow.cn/v1/chat/completions
deepseek.api.key=YOUR_API_KEY
4. 代码详解
4.1 关键特性
- 使用 Spring WebFlux 的响应式编程模型
- 流式处理 API 响应
- 文件记录对话
- 错误处理和异常管理
4.2 主要组件
DeepSeekConfig: 管理 API 配置DeepSeekService: 处理对话逻辑和 API 交互- 模型类: 定义请求和响应结构
5. 使用方法
- 替换
application.properties中的YOUR_API_KEY - 运行
DeepSeekApplication - 在控制台输入问题
- 输入 ‘q’ 退出程序
- 查看
conversation.txt获取对话记录
6. 性能和可扩展性
- 使用响应式编程提高并发性能
- 灵活的配置管理
- 易于扩展和定制
7. 注意事项
- 确保正确配置 API Key
- 处理网络异常
- 注意内存使用
总结
Spring Boot 实现提供了一个健壮、可扩展的 DeepSeek API 调用方案,利用响应式编程提供高效的流式对话体验。
立即体验
快来体验 DeepSeek:https://cloud.siliconflow.cn/i/vnCCfVaQ
相关文章:
DeepSeek API 调用 - Spring Boot 实现
DeepSeek API 调用 - Spring Boot 实现 1. 项目依赖 在 pom.xml 中添加以下依赖: <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></depe…...
图数据库Neo4j面试内容整理-节点(Node)
在图数据库中,节点(Node)是图结构中的基本构建块,代表实体或对象。节点通常用于存储数据模型中的主要对象,比如人、商品、地点等。在图数据库中,节点是通过标签(Label)来分类的,并且可以包含属性(Property)来描述它们的详细信息。 1. 节点的组成<...
使用verilog 实现 cordic 算法 ----- 旋转模式
1-设计流程 ● 了解cordic 算法原理,公式,模式,伸缩因子,旋转方向等,推荐以下链接视频了解 cordic 算法。哔哩哔哩-cordic算法原理讲解 ● 用matlab 或者 c 实现一遍算法 ● 在FPGA中用 verilog 实现,注意…...
2.14寒假
这几天复习的搜索把之前做过的题目看了一下。 解析:int dx[5]{0,0,1,0,-1}; 和 int dy[5]{0,1,0,-1,0};:这两个数组用于表示上下左右四个方向的偏移量,方便在 DFS 中访问相邻的元素。o 和 p 分别表示当前搜索位置的行和列。边界条件判断&…...
基于逻辑概率的语义信道容量(Semantic Channel Capacity)和语义压缩理论(Semantic Compression Theory)
基于逻辑概率的语义信道容量(Semantic Channel Capacity)和语义压缩理论(Semantic Compression Theory)是语义通信(Semantic Communication, SemCom)的核心研究方向,它们旨在优化通信效率&#…...
DeepSeek R1本地部署教程
尽管许多卖课博主声称能轻松运行满血版DeepSeek R1,但满血版R1模型参数高达671B,仅模型文件就需要404GB存储空间,运行时更需要约1300GB显存。 对于没有卡的普通玩家来说,运行的条件苛刻,且门槛极高。基于此࿰…...
CEF132编译指南 MacOS 篇 - 获取 CEF 源码 (五)
1. 引言 在完成了所有必要工具的安装和配置之后,我们正式进入获取 CEF132 源码的阶段。对于 macOS 平台,CEF 的源码获取过程需要特别注意不同芯片架构(Intel 和 Apple Silicon)的区别以及版本管理。本篇将作为 CEF132 编译指南系…...
TypeScript装饰器 ------- 学习笔记分享
目录 一. 简介 二. 类装饰器 1. 基本语法 2. 应用举例 3. 关于返回值 4. 关于构造类型 5. 替换被装饰的类 三. 装饰器工厂 四. 装饰器组合 五. 属性装饰器 1. 基本语法 2. 关于属性遮蔽 3. 应用举例 六. 方法装饰器 1. 基本语法 2. 应用举例 七. 访问器装饰器 …...
FPGA实现UltraScale GTH光口视频转USB3.0传输,基于FT601+Aurora 8b/10b编解码架构,提供2套工程源码和技术支持
目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目我这里已有的 GT 高速接口解决方案本博已有的FPGA驱动USB通信方案 3、工程详细设计方案工程设计原理框图输入Sensor之-->OV5640摄像头动态彩条输入视频之-->ADV…...
蓝桥杯篇---实时时钟 DS1302
文章目录 前言特点简介1.低功耗2.时钟/日历功能3.32字节的额外RAM4.串行接口 DS1302 引脚说明1.VCC12.VCC23.GND4.CE5.I/O6.SCLK DS1302 寄存器1.秒寄存器2.分钟寄存器3.小时寄存器4.日寄存器5.月寄存器6.星期寄存器7.年寄存器8.控制寄存器 DS1302 与 IAP25F2K61S2 的连接1.CE连…...
C语言蓝桥杯1003: [编程入门]密码破译
要将"China"译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母. 例如,字母"A"后面第4个字母是"E"."E"代替"A"。因此,"China"应译…...
【MySQL在Centos 7环境安装】
文章目录 一. 卸载不必要的环境二. 检查系统安装包三. 卸载这些默认安装包四. 获取mysql官⽅yum源五. 安装mysql yum 源,对⽐前后yum源六. 看看能不能正常⼯作七. 安装mysql服务八. .查看配置⽂件和数据存储位置九. 启动服务并查看服务是否存在十. 登陆⽅法十一. 设…...
科技引领未来,中建海龙C-MiC 2.0技术树立模块化建筑新标杆
在建筑行业追求高效与品质的征程中,中建海龙科技有限公司(简称“中建海龙”)以其卓越的创新能力和强大的技术实力,不断书写着装配式建筑领域的新篇章。1 月 10 日,由深圳安居集团规划,中建海龙与中海建筑共…...
玩转观察者模式
文章目录 什么是观察者模式解决方案结构适用场景实现方式观察者模式优缺点优点:缺点:什么是观察者模式 观察者模式通俗点解释就是你在观察别人,别人有什么变化,你就做出什么调整。观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个“观察…...
Baklib知识中台构建企业智能运营核心架构
内容概要 在数字化转型的浪潮中,企业对于知识的系统化管理需求日益迫切。Baklib作为新一代的知识中台,通过构建智能运营核心架构,为企业提供了一套从知识汇聚到场景化落地的完整解决方案。其核心价值在于将分散的知识资源整合为统一的资产池…...
Anaconda +Jupyter Notebook安装(2025最新版)
Anaconda安装(2025最新版) Anaconda简介安装1:下载anaconda安装包2: 安装anaconda3:配置环境变量4:检查是否安装成功5:更改镜像源6:更新包7:检查 Jupyter Notebook一.Jup…...
正成为现代城市发展的必然趋势的智慧交通开源了
智慧交通视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。通过人流密集检测…...
手撕Transformer编码器:从Self-Attention到Positional Encoding的PyTorch逐行实现
Transformer 编码器深度解读 代码实战 1. 编码器核心作用 Transformer 编码器的核心任务是将输入序列(如文本、语音)转换为富含上下文语义的高维特征表示。它通过多层自注意力(Self-Attention)和前馈网络(FFN&#x…...
Webpack和Vite插件的开发与使用
在现代开发中一般各公司都有自己的监控平台,对前端而言如果浏览器报错的话就可以通过埋点收集错误日志,再结合sourcemap文件可以帮助我们定位到错误代码,帮助我们排查问题。这里就记录一下之前在webpack和vite两个环境中的插件开发࿰…...
HTTP的状态码
HTTP 状态码 当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。 常见的HTTP状态码 …...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
