Spring Boot 牵手Spring AI,玩转DeepSeek大模型

作者:小码哥_常日期:2026/4/1

Spring Boot 牵手Spring AI,玩转DeepSeek大模型

引言:开启 AI 集成之旅

在当今这个 AI 技术迅猛发展的时代,你是否想过如何将强大的大模型融入到我们日常的 Java 开发中,为应用赋予智能交互的能力呢?今天,我们就来探索如何通过 Spring Boot 集成 Spring AI,进而调用 DeepSeek 大模型,为你的项目注入全新的 AI 活力。这不仅能让你深入了解 AI 与后端开发融合的前沿技术,还能为你在实际项目中运用 AI 技术提供宝贵的经验 。接下来,就让我们一步步揭开这个神秘的面纱,看看如何搭建一个高效智能的 AI 集成应用吧!

一、技术探秘:Spring Boot、Spring AI 和 DeepSeek

(一)Spring Boot 简介

Spring Boot 就像是 Java 开发领域的超级助手,基于 Spring 框架,通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了 Spring 应用的搭建和开发过程。打个比方,如果把开发一个 Java 应用比作建造一座房子,那么 Spring Boot 就是一个精心设计好的房屋框架,它不仅帮你搭建好了基础结构,还把各种常用的功能模块(如数据库连接、Web 服务等)都预先配置好了,你只需要专注于填充房子内部的 “家具”,也就是实现业务逻辑即可 。

在 Java 开发中,Spring Boot 已然成为了不可或缺的重要角色,占据着核心地位。它解决了传统 Spring 开发中配置繁琐、依赖管理复杂等痛点,让开发者能够快速构建独立的、生产级别的 Spring 应用 。无论是开发小型的 Web 应用,还是大型的企业级微服务架构,Spring Boot 都能提供强大的支持,使得开发效率大幅提升,项目的维护和扩展也变得更加容易 。

(二)Spring AI 介绍

Spring AI 则是 Spring 家族中专门为人工智能应用开发打造的利器,是一个由 Spring 团队开发的开源框架。它的出现,为开发者提供了一套简洁、统一的 API 接口,就像一把万能钥匙,让我们可以轻松地调用各种大语言模型(LLMs),如通义千问、ChatGPT 等 。

通过 Spring AI,开发者可以摆脱不同 AI 服务之间接口差异的困扰,用一种统一的方式与各种 AI 服务进行交互。同时,它还集成了嵌入向量数据库、提示工程等能力,为 AI 应用的开发提供了更丰富的功能支持 。比如,在开发一个智能客服系统时,我们可以利用 Spring AI 快速连接到不同的语言模型,实现对用户问题的智能解答,而无需关心底层模型的复杂调用细节 。

(三)DeepSeek 大模型解析

DeepSeek 作为一款备受瞩目的大模型,在自然语言处理方面展现出了卓越的能力和独特的特点 。它拥有大规模的预训练模型,通过在海量文本数据上进行无监督学习,构建了丰富的语言知识体系,能够准确解析各种自然语言描述,理解其中蕴含的意图和关键信息 。

DeepSeek 具备上下文感知能力,在处理自然语言时,会充分考虑整个对话或文档的上下文信息,从而更准确地理解每个语句的含义,消除歧义。这一特性使得它在实际应用中表现出色,特别是在多轮对话场景下,能够更好地与用户进行交互 。

此外,DeepSeek 在多任务支持方面表现优秀,能够同时处理多种不同类型的任务,如文本生成、问答系统、代码生成等 。而且,针对中文语言的特点进行了优化,对中文的理解和处理更加准确、自然,非常适合国内的各种应用场景 。例如,在进行中文文章写作、智能翻译等任务时,DeepSeek 能够生成高质量的结果,满足用户的需求 。

二、实战准备:搭建开发环境

(一)环境要求说明

在开始搭建项目之前,我们需要确保开发环境满足以下要求:

  • JDK 版本:需要安装 JDK 17 或更高版本,因为 Spring Boot 3.2 + 对 JDK 版本有一定要求,高版本的 JDK 能提供更好的性能和特性支持,为项目的开发和运行奠定良好的基础 。
  • Maven 版本:Maven 3.6 + 是必备的构建工具,它可以帮助我们管理项目的依赖关系,自动下载所需的库文件,并且能够方便地进行项目的编译、测试和打包等操作 。
  • Spring Boot 版本:选用 Spring Boot 3.2+,这个版本在性能、功能和兼容性方面都有显著的提升,能够更好地与 Spring AI 集成,为我们的开发提供更多便利 。

(二)创建 Spring Boot 项目

创建 Spring Boot 项目有多种方式,这里我们推荐使用 Spring Initializr,它是 Spring 官方提供的一个快速创建 Spring Boot 项目的工具,非常便捷。

首先,打开浏览器,访问 Spring Initializr 官网(start.spring.io/) 。在页面中,我们可以进行如下配置:

  • 项目基本信息:填写项目的 Group(通常是公司或组织的域名倒序)、Artifact(项目名称),选择 Maven 项目和对应的 Java 版本 。
  • 依赖选择:在 “Dependencies” 区域,搜索并勾选 “Spring Web”,它提供了构建 Web 应用的支持,让我们可以方便地创建 HTTP 接口;勾选 “Lombok”,这是一个能简化 Java 代码编写的工具,通过注解就能自动生成 getter、setter、构造函数等常用代码,减少冗余;还要勾选 “Spring AI (OpenAI)”,它是我们集成 AI 功能的关键依赖 。

配置完成后,点击 “Generate” 按钮,即可下载一个基础的 Spring Boot 项目压缩包。解压后,用 IDE(如 IntelliJ IDEA、Eclipse 等)打开项目,就可以开始后续的开发工作了 。

(三)获取 DeepSeek API 密钥

要调用 DeepSeek 大模型,我们需要先获取 API 密钥,这是我们访问 DeepSeek 服务的身份凭证 。获取步骤如下:

  1. 访问 DeepSeek 开发者平台的官方网站(platform.deepseek.com/ ),如果没有账号,先进行注册并完成实名认证,个人用户需要上传身份证正反面及完成人脸识别验证,企业用户则需提交营业执照扫描件等相关资料 。
  2. 实名认证通过后,登录进入平台的「控制台」,在控制台中找到「API 管理」选项,点击进入。
  3. 在「API 管理」页面,点击「新建应用」按钮,填写应用名称(例如 “SpringAI - DeepSeekDemo”),并选择合适的应用场景(如 “文本生成”“智能问答” 等) 。
  4. 点击「创建」按钮后,系统会为我们生成一个应用,进入该应用的详情页面,在「API 密钥」页面,即可看到生成的 API 密钥 。这个密钥非常重要,一定要妥善保管,不要泄露给他人,建议将其存储在安全的地方,比如环境变量中,避免直接写在代码里,防止密钥泄露带来的安全风险 。

三、集成步骤:让它们携手合作

(一)添加依赖

在 Spring Boot 项目的 pom.xml 文件中,我们需要添加 Spring AI 和 OpenAI 相关依赖 。由于 DeepSeek 模型与 OpenAI API 兼容,我们可以使用 Spring AI 提供的 OpenAI Starter 依赖来实现集成 。具体依赖配置如下:

1
2<dependency>
3    <groupId>org.springframework.ai</groupId>
4    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
5    <version>1.0.0-M6</version>
6</dependency>
7

同时,为了确保能获取到最新的依赖版本,我们还需要在 pom.xml 中添加 Spring Milestones Repository:

1
2<repositories>
3    <repository>
4        <id>spring-milestones</id>
5        <name>Spring Milestones</name>
6        <url>https://repo.spring.io/milestone</url>
7        <snapshots>
8            <enabled>false</enabled>
9        </snapshots>
10    </repository>
11</repositories>
12

添加完依赖后,Maven 会自动下载并管理这些依赖包,为后续的集成工作做好准备 。

(二)配置文件设置

接下来,在 application.properties 配置文件中,我们要设置 DeepSeek 的相关参数 。首先,设置 API 密钥,这是我们访问 DeepSeek 服务的通行证:

1
2spring.ai.openai.api-key=your-deepseek-api-key
3

your-deepseek-api-key替换为你在 DeepSeek 开发者平台获取的真实 API 密钥 。

然后,设置基础 URL,指定我们要访问的 DeepSeek 服务地址:

1
2spring.ai.openai.chat.options.base-url=https://api.deepseek.com/v1
3

这里使用的是 DeepSeek 的官方 API 地址,确保请求能够正确发送到 DeepSeek 服务端 。

最后,设置要使用的模型,比如我们使用deepseek-chat模型:

1
2spring.ai.openai.chat.options.model=deepseek-chat
3

通过这些配置,Spring AI 就知道如何与 DeepSeek 进行通信,以及使用哪个模型来处理我们的请求 。

(三)代码实现

在代码层面,我们需要创建控制器类和服务类,来实现调用 DeepSeek 模型进行文本生成的功能 。

首先,创建一个服务类AIService,在这个类中注入ChatClient,并实现生成响应的方法 。ChatClient是 Spring AI 提供的用于与聊天模型交互的客户端,通过它我们可以方便地调用 DeepSeek 模型 。

1
2import org.springframework.ai.chat.ChatClient;
3import org.springframework.stereotype.Service;
4
5@Service
6public class AIService {
7    private final ChatClient chatClient;
8
9    public AIService(ChatClient chatClient) {
10        this.chatClient = chatClient;
11    }
12
13    public String generateResponse(String prompt) {
14        return chatClient.call(prompt);
15    }
16}
17

在上述代码中,generateResponse方法接收一个用户输入的提示(prompt),然后通过chatClient.call(prompt)方法调用 DeepSeek 模型,获取模型生成的响应 。

接着,创建一个控制器类AIController,用于接收外部的 HTTP 请求,并将请求转发给AIService进行处理,最后将处理结果返回给客户端 。

1
2import org.springframework.web.bind.annotation.*;
3
4@RestController
5@RequestMapping("/api/ai")
6public class AIController {
7    private final AIService aiService;
8
9    public AIController(AIService aiService) {
10        this.aiService = aiService;
11    }
12
13    @PostMapping("/chat")
14    public String chat(@RequestBody String prompt) {
15        return aiService.generateResponse(prompt);
16    }
17}
18

在这个控制器中,@RequestMapping("/api/ai")指定了该控制器处理的请求路径前缀为/api/ai@PostMapping("/chat")表示处理/api/ai/chat路径的 POST 请求,当客户端发送一个包含用户输入提示的 POST 请求到这个路径时,chat方法会被调用 。@RequestBody String prompt用于接收请求体中的用户输入提示,然后调用aiService.generateResponse(prompt)获取 AI 生成的响应,并将其返回给客户端 。通过这样的代码实现,我们就完成了从接收用户请求到调用 DeepSeek 模型生成响应,再到返回响应的整个流程 。

四、功能测试:检验成果

(一)启动项目

一切准备就绪后,就可以启动我们的 Spring Boot 项目了。如果你使用的是 IntelliJ IDEA,只需要找到项目的主启动类,通常是带有@SpringBootApplication注解且包含main方法的类,然后点击主方法旁的绿色运行按钮 ,IDEA 就会帮你启动项目 。

如果使用命令行的方式,首先进入项目的根目录,确保目录下存在pom.xml文件 。然后执行命令mvn spring-boot:run,Maven 会自动下载项目所需的依赖,编译代码,并启动 Spring Boot 应用 。在启动过程中,你可以在控制台看到一系列的日志信息,当看到类似于 “Started [ApplicationName] in [X] seconds” 的日志时,就说明项目已经成功启动,此时应用已经在等待接收外部请求了 。

(二)测试接口

接下来,我们使用 Postman 来测试接口。打开 Postman,创建一个新的 POST 请求 。在请求地址栏中输入http://localhost:8080/api/ai/chat,这里假设你的 Spring Boot 应用使用的是默认端口 8080,如果在配置文件中修改了端口,需要相应地调整请求地址 。

在请求体(Body)部分,选择 “raw” 格式,并将数据类型设置为 “JSON” ,然后输入用户的提问,比如"你能介绍一下Spring Boot的特点吗?" 。点击 “Send” 按钮,Postman 就会向我们的接口发送请求 。

很快,我们就能在响应区看到 DeepSeek 模型返回的结果。如果一切正常,会返回一段关于 Spring Boot 特点的详细描述,例如:“Spring Boot 具有自动配置、起步依赖、内嵌服务器等特点,它简化了 Spring 应用的搭建和开发过程……” 。通过这样的测试,我们可以直观地看到集成是否成功,以及 DeepSeek 模型是否能够准确地处理我们的请求并返回预期的结果 。在实际测试中,你可以尝试不同的问题,全面检验接口的功能和模型的能力 。

五、进阶拓展:解锁更多可能

(一)定制请求参数

在实际应用中,我们常常需要根据不同的业务需求,灵活地调整模型的生成行为。其中一个重要的方式就是定制请求参数,比如调整温度参数。温度参数是一个在自然语言处理中常用的超参数,它主要用于控制生成文本的随机性 。

当我们把温度参数设置得较低时,比如在 0.2 - 0.5 的范围内,模型生成的文本会更加保守、确定 。这就像是一个严谨的学者在撰写学术论文,每一个用词、每一句话都经过深思熟虑,力求准确无误 。例如,在生成技术文档、法律条文解释等对准确性要求极高的内容时,低温度参数设置可以确保生成的文本逻辑清晰、条理分明,避免出现模糊或随意的表述 。

相反,如果我们将温度参数调高,如设置在 0.8 - 1.0 左右,模型生成的文本就会更具创造性和多样性 。此时的模型就像一位富有想象力的艺术家,能够创造出充满新奇想法和独特表达的文本 。在创意写作、故事创作等场景中,高温度参数设置可以让模型生成的故事充满惊喜和意外,为用户带来丰富的阅读体验 。

在 Spring Boot 集成 Spring AI 调用 DeepSeek 的项目中,我们可以通过OpenAIChatCompletionRequest类来方便地设置温度参数 。具体代码如下:

1
2import org.springframework.ai.openai.OpenAIChatCompletionRequest;
3import org.springframework.ai.openai.OpenAIChatModel;
4import org.springframework.beans.factory.annotation.Autowired;
5import org.springframework.stereotype.Service;
6
7@Service
8public class AIService {
9    private final OpenAIChatModel chatModel;
10
11    @Autowired
12    public AIService(OpenAIChatModel chatModel) {
13        this.chatModel = chatModel;
14    }
15
16    public String generateResponse(String prompt, double temperature) {
17        OpenAIChatCompletionRequest request = OpenAIChatCompletionRequest.builder()
18               .messages(List.of(new UserMessage(prompt)))
19               .temperature(temperature)
20               .build();
21        return chatModel.call(request);
22    }
23}
24

在上述代码中,generateResponse方法接收用户输入的提示prompt和温度参数temperature 。通过OpenAIChatCompletionRequest.builder()构建请求对象,设置messages为包含用户提示的消息列表,并设置temperature为传入的温度参数 。最后,调用chatModel.call(request)方法发送请求并获取模型生成的响应 。通过这种方式,我们就能够根据实际需求,灵活地调整温度参数,从而让模型生成出更符合我们期望的文本 。

(二)实现流式输出

在与大模型进行交互时,实现流式输出功能可以极大地提升用户体验 。流式输出就像是你和朋友面对面聊天,对方每想到一点就会马上告诉你,而不是等把所有话都想好了才一次性说出来 。在我们的应用中,当用户向模型发送请求后,模型可以一边生成响应内容,一边将这些内容实时地返回给用户,而不是等到整个响应内容全部生成完毕后才返回 。这样,用户就能更快地看到模型的回复,感受到更加流畅的交互体验 。

在 Spring Boot 中实现流式输出,我们可以借助 Sse(Server - Sent Events,服务器发送事件)技术 。Sse 是一种服务器推送技术,非常适合单向实时数据流的场景 。我们可以使用 Spring MVC(基于 Servlet)中的SseEmitter对象来实现流式输出 。以下是具体的实现代码:

1
2import org.springframework.ai.chat.messages.UserMessage;
3import org.springframework.ai.chat.prompt.Prompt;
4import org.springframework.ai.openai.OpenAiChatModel;
5import org.springframework.http.MediaType;
6import org.springframework.web.bind.annotation.GetMapping;
7import org.springframework.web.bind.annotation.RequestParam;
8import org.springframework.web.bind.annotation.RestController;
9import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
10
11import java.util.List;
12
13@RestController
14public class ChatController {
15    private final OpenAiChatModel chatModel;
16
17    public ChatController(OpenAiChatModel chatModel) {
18        this.chatModel = chatModel;
19    }
20
21    @GetMapping(value = "/ai/generateStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
22    public SseEmitter streamChat(@RequestParam String message) {
23        SseEmitter emitter = new SseEmitter(60_000L); // 创建SSE发射器,设置超时时间为60秒
24        Prompt prompt = new Prompt(new UserMessage(message));
25
26        chatModel.stream(prompt).subscribe(response -> {
27            try {
28                String content = response.getResult().getOutput().getContent();
29                emitter.send(SseEmitter.event().data(content).id(String.valueOf(System.currentTimeMillis())).build());
30            } catch (Exception e) {
31                emitter.completeWithError(e);
32            }
33        }, error -> {
34            emitter.completeWithError(error);
35        }, () -> {
36            emitter.complete();
37        });
38
39        emitter.onCompletion(() -> {
40            System.out.println("SSE connection completed");
41        });
42        emitter.onTimeout(() -> {
43            emitter.complete();
44            System.out.println("SSE connection timed out");
45        });
46
47        return emitter;
48    }
49}
50

在上述代码中,streamChat方法首先创建了一个SseEmitter对象,并设置了超时时间为 60 秒 。然后,根据用户输入的消息创建了一个Prompt对象 。接着,通过chatModel.stream(prompt)订阅模型的流式响应 。在响应的处理逻辑中,每当接收到模型生成的一部分内容时,就通过emitter.send方法将这部分内容发送给客户端 。如果在发送过程中出现异常,就调用emitter.completeWithError(e)方法结束流并返回错误信息 。当整个响应生成完毕后,调用emitter.complete()方法结束流 。此外,还设置了emitter.onCompletionemitter.onTimeout回调方法,分别用于处理流完成和超时的情况 。通过这样的实现,我们就成功地在 Spring Boot 应用中实现了流式输出功能,为用户提供了更加实时、流畅的交互体验 。

(三)对话历史管理

在多轮对话场景中,让模型能够理解上下文是非常关键的 。就像我们和朋友聊天,朋友能记得我们之前说过的话,这样交流起来才会更加顺畅 。Spring AI 提供了ChatMemory接口,帮助我们实现对话历史管理功能,让模型能够记住之前的对话内容,从而更好地理解用户当前的问题,并给出更准确、相关的回答 。

ChatMemory接口主要有三个重要的方法:add方法用于向指定会话添加消息列表,通常是一条用户消息和一条 AI 响应;get方法用于获取某个会话的历史消息;clear方法用于清空某个会话的历史 。Spring AI 已经为我们提供了一种开箱即用的实现 ——MessageWindowChatMemory 。它的工作方式类似于一个 “滑动窗口”,只保留每个会话最近 N 条消息 。当消息数量超过设定的最大值时,会自动把最早的消息丢掉(但会保留系统级别的消息) 。默认情况下,窗口大小是 20 条消息,不过我们也可以根据实际需求进行调整 。

下面是一个使用ChatMemory实现对话历史管理的示例代码:

1
2import org.springframework.ai.chat.ChatMessage;
3import org.springframework.ai.chat.ChatMemory;
4import org.springframework.ai.chat.Message;
5import org.springframework.ai.chat.UserMessage;
6import org.springframework.ai.chat.messages.AiMessage;
7import org.springframework.ai.chat.prompt.Prompt;
8import org.springframework.ai.openai.OpenAiChatModel;
9import org.springframework.beans.factory.annotation.Autowired;
10import org.springframework.stereotype.Service;
11
12import java.util.List;
13
14@Service
15public class ChatService {
16    private final OpenAiChatModel chatModel;
17    private final ChatMemory chatMemory;
18
19    @Autowired
20    public ChatService(OpenAiChatModel chatModel, ChatMemory chatMemory) {
21        this.chatModel = chatModel;
22        this.chatMemory = chatMemory;
23    }
24
25    public String chat(String conversationId, String userInput) {
26        UserMessage userMessage = new UserMessage(userInput);
27        List<Message> history = chatMemory.get(conversationId);
28        history.add(userMessage);
29
30        Prompt prompt = new Prompt(history);
31        String aiResponse = chatModel.call(prompt);
32
33        AiMessage aiMessage = new AiMessage(aiResponse);
34        history.add(aiMessage);
35        chatMemory.add(conversationId, history);
36
37        return aiResponse;
38    }
39
40    public void clearHistory(String conversationId) {
41        chatMemory.clear(conversationId);
42    }
43}
44

在上述代码中,ChatService类注入了OpenAiChatModelChatMemorychat方法接收会话 ID 和用户输入,首先根据会话 ID 从chatMemory中获取历史消息列表,然后将用户当前输入的消息添加到历史消息列表中 。接着,使用包含历史消息的Prompt对象调用模型生成 AI 响应 。最后,将 AI 响应添加到历史消息列表中,并通过chatMemory.add方法将更新后的历史消息保存起来 。clearHistory方法则用于清空指定会话的历史消息 。通过这样的实现,我们就能够利用ChatMemory接口有效地管理对话历史,让模型在多轮对话中能够更好地理解上下文,提供更优质的交互服务 。

六、注意事项:避坑指南

(一)性能优化

在实际应用中,性能优化是至关重要的一环,它直接影响着用户体验和系统的整体运行效率 。为了提升系统性能,我们可以采取多种有效的策略 。 启用响应缓存是一种非常实用的优化手段 。我们可以使用 Spring 的缓存注解,如@Cacheable ,对频繁调用且结果相对稳定的方法进行缓存 。例如,对于那些用户经常询问的常见问题,如 “什么是人工智能?”“如何使用我们的产品?” 等,这些问题的答案通常不会频繁变化,我们可以将模型对这些问题的回答缓存起来 。当用户再次提出相同问题时,系统可以直接从缓存中获取答案,而无需再次调用 DeepSeek 模型 。这样不仅大大减少了模型的调用次数,还能显著提高响应速度,减轻系统的负载压力 。就好像在图书馆里,对于那些经常被借阅的热门书籍,我们可以在图书馆入口处设置一个专门的展示架,当读者来借阅这些热门书籍时,工作人员可以直接从展示架上取书给读者,而不需要再去庞大的书架中寻找,节省了时间和精力 。

合理配置超时设置也是不容忽视的 。我们需要根据 DeepSeek 模型的实际响应时间,为调用设置合适的超时时间 。如果超时时间设置得过短,可能会导致一些正常的请求因为还未得到模型的响应就被判定为超时,从而影响用户体验 。比如,当模型正在处理一个复杂的问题,需要较多的时间来生成答案时,如果超时时间设置得不合理,用户就会收到错误提示,误以为系统出现了故障 。相反,如果超时时间设置得过长,当模型出现异常或网络中断等情况时,系统会等待很长时间才会报错,这会浪费大量的时间资源,降低系统的可用性 。因此,我们要通过实际测试和监控,找到一个最佳的超时时间平衡点 。就像我们在等待公交车时,如果我们设定的等待时间过短,可能会错过本来可以乘坐的公交车;而如果等待时间过长,我们可能会在车站白白浪费很多时间 。通过多次观察公交车的运行时间规律,我们就能找到一个合适的等待时间,既不会错过车,也不会浪费太多时间 。

(二)异常处理

在调用 DeepSeek API 的过程中,难免会遇到各种异常情况,如网络故障、API 密钥无效、模型服务繁忙等 。为了确保系统的稳定性和可靠性,我们需要创建全局异常处理器,对这些异常进行统一的处理 。

首先,我们可以创建一个自定义异常类,比如AIInvocationException ,用于表示调用 AI 服务时出现的异常 。这个自定义异常类可以继承自RuntimeException ,并添加一些额外的属性,如错误码和详细的错误信息,以便我们更准确地定位和处理问题 。例如:

1
2public class AIInvocationException extends RuntimeException {
3    private int errorCode;
4    private String errorMessage;
5
6    public AIInvocationException(int errorCode, String errorMessage) {
7        this.errorCode = errorCode;
8        this.errorMessage = errorMessage;
9    }
10
11    public int getErrorCode() {
12        return errorCode;
13    }
14
15    public String getErrorMessage() {
16        return errorMessage;
17    }
18}
19

然后,创建全局异常处理器类,使用@ControllerAdvice注解将其标记为全局异常处理器 。在这个类中,通过@ExceptionHandler注解来定义不同类型异常的处理方法 。比如,当调用 DeepSeek API 出现网络异常时,我们可以返回一个友好的提示信息给用户,告知用户可能是网络问题导致请求失败,并建议用户检查网络连接后重试 。如果是 API 密钥无效的异常,我们可以返回错误信息,提示用户检查 API 密钥是否正确,并引导用户重新获取或更新 API 密钥 。示例代码如下:

1
2import org.springframework.http.HttpStatus;
3import org.springframework.http.ResponseEntity;
4import org.springframework.web.bind.annotation.ControllerAdvice;
5import org.springframework.web.bind.annotation.ExceptionHandler;
6
7@ControllerAdvice
8public class GlobalExceptionHandler {
9
10    @ExceptionHandler(AIInvocationException.class)
11    public ResponseEntity<String> handleAIInvocationException(AIInvocationException ex) {
12        return new ResponseEntity<>(
13                "AI调用出现异常,错误码:" + ex.getErrorCode() + ",错误信息:" + ex.getErrorMessage(),
14                HttpStatus.INTERNAL_SERVER_ERROR
15        );
16    }
17
18    // 其他异常处理方法,如处理网络异常、API密钥无效异常等
19    @ExceptionHandler(IOException.class)
20    public ResponseEntity<String> handleIOException(IOException ex) {
21        return new ResponseEntity<>("网络异常,请检查网络连接后重试", HttpStatus.INTERNAL_SERVER_ERROR);
22    }
23
24    @ExceptionHandler(IllegalArgumentException.class)
25    public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException ex) {
26        if (ex.getMessage().contains("Invalid API key")) {
27            return new ResponseEntity<>("API密钥无效,请检查并重新设置", HttpStatus.BAD_REQUEST);
28        }
29        return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
30    }
31}
32

通过这样的全局异常处理器,我们可以将不同类型的异常统一转化为友好的错误响应,避免将底层的异常堆栈信息直接暴露给用户,提升系统的安全性和用户体验 。同时,也方便我们对异常进行集中管理和维护,提高代码的可维护性 。


Spring Boot 牵手Spring AI,玩转DeepSeek大模型》 是转载文章,点击查看原文


相关推荐


OpenClaw实战|从识图到公众号内容自动化,我跑通了完整链路
后端小肥肠2026/3/23

大家好,我是小肥肠。今天这篇文章,想跟大家分享一下我最近刚跑通两个skill:让 OpenClaw图像理解和 飞书 文章一键转存至公众号草稿箱。 1. 前言 最近我在慢慢做一件事:把之前在 Coze 里折腾过的插件和工作流,陆续迁到 OpenClaw + Skill 这一套上。上周末我主要搞定了两件事,都已经不是“纸上谈兵”,是真的跑起来了。 第一件:把图像理解插件迁移成 OpenClaw Skill 我把之前做的图像理解Coze插件,迁成了一个独立的 xfc-img-understand sk


墨梅博客 1.9.0 发布与 LeanCloud 停服应对 | 2026 年第 11 周草梅周报
草梅友仁2026/3/15

本文在草梅友仁的博客发布和更新,并在多个平台同步发布。如有更新,以博客上的版本为准。您也可以通过文末的 原文链接 查看最新版本。 前言 欢迎来到草梅周报!这是一个由草梅友仁基于 AI 整理的周报,旨在为您提供最新的博客更新、GitHub 动态、个人动态和其他周刊文章推荐等内容。 开源动态 本周墨梅博客的开发依旧在稳步进行中。 您可以前往 Demo 站试用:demo.momei.app/ 您可以通过邮箱 admin@example.com,密码 momei123456 登录演示用管理员账号


ai-agent工程师指南
哈里谢顿2026/3/7

一些基本概念 1 Zero-shot & Few-shot 是什么? 1. Zero-shot(零样本) 不给例子,直接让模型做。 不提供任何参考样例 只告诉模型任务是什么 完全靠模型本身能力去理解、推理 例子 把下面句子分类成积极 / 消极:这部电影太好看了! 这就是 zero-shot。 2. Few-shot(少样本 / 小样本) 给几个例子,再让模型做。 给 1~10 个左右的示例 告诉模型:我要你像这样输出 模型照着格式、逻辑去做 例子 分类:今天心情很好 → 积极分类


CSDN创作变现活动!社区镜像或使用视频教程分别单个最高得 80 元,收益上不封顶!
CSDN官方博客2026/2/27

CSDN AI 社区是聚焦 AI 技术产业落地的开发者服务平台(官方入口),核心为创作者搭建技术价值转化桥梁,AI社区涵盖: 镜像市场(社区镜像)、算力市场等模块。 本次推出镜像创作激励活动,以下是方案活动规则、参与要求及激励政策,保障创作者权益与活动有序开展。 一、活动总则 活动时间: 2026年1月1日 - 2026年2月28日 现金奖励: 1、按照官方指定镜像任务创作,单个社区镜像奖励 30-80元现金 ,创作越多可获得现金奖


深度解析 JWT:从 RFC 原理到 NestJS 实战与架构权衡
NEXT062026/2/18

1. 引言 HTTP 协议本质上是无状态(Stateless)的。在早期的单体应用时代,为了识别用户身份,我们通常依赖 Session-Cookie 机制:服务端在内存或数据库中存储 Session 数据,客户端浏览器通过 Cookie 携带 Session ID。 然而,随着微服务架构和分布式系统的兴起,这种有状态(Stateful)的机制暴露出了明显的弊端:Session 数据需要在集群节点间同步(Session Sticky 或 Session Replication),这极大地限制了系统


RTOS核心三剑客:任务、信号量与队列深度解析
牛逍遥2026/2/9

RTOS核心三剑客:任务、信号量与队列深度解析 一、裸机编程的瓶颈:为什么需要RTOS? 在嵌入式开发中,裸机程序通常采用**超级循环(Super Loop)**结构: void main() { while(1) { read_sensors();// 读取传感器 process_data();// 处理数据 update_display();// 刷新显示 handle_uart();// 串口通信 check_safety();// 安全检测 } } 裸机编程的致命缺陷: 阻塞操作导致响


Objective-C手机验证码短信接口调用流程:创建请求对象并设置报文体
2601_949146532026/2/1

在iOS原生开发中,基于Objective-C对接手机验证码短信接口是账号安全、用户验证场景的核心需求,但新手常因请求对象创建不规范、报文体参数编码错误、请求头配置缺失等问题,导致接口返回405(API ID错误)、407(内容含敏感字符)等异常。本文聚焦objective-c手机验证码短信接口的核心调用流程,拆解创建NSURLRequest请求对象、配置请求头、设置报文体的完整逻辑,提供可直接复用的实战代码,解决参数编码、状态码解析等痛点,帮助开发者高效完成接口对接。 一、Objective


没显卡也能玩!Ollama 本地大模型保姆级入门指南
字节逆旅2026/1/22

如果你想在自己电脑上跑 AI,又不希望数据被大厂拿走,Ollama 绝对是目前最香的选择。不用配复杂的 Python 环境,不用求爷爷告奶奶找 API Key,只要一键安装,就能实现“大模型自由”。不过我的电脑很早就有了python环境了,忘记啥时候安装的,虽然在python方面还是个菜鸟。 1. 怎么安装 直接去 Ollama 官网 下载。有1个多G,先有个心理准备。 第一步: 安装完后,它会躲在右下角任务栏。 第二步: 打开终端(CMD 或 PowerShell),输入下面的命令。这


一个致力于为 C# 程序员提供更佳的编码体验和效率的 Visual Studio 扩展插件
追逐时光者2026/1/14

前言 今天大姚给大家分享一个致力于为 C# 程序员提供更佳的编码体验和效率的 Visual Studio 扩展插件:Codist。 Codist 插件介绍 Codist 是一个使用 .NET 编写、开源免费的 Visual Studio 扩展插件,致力于为 C# 程序员提供更好的编程体验和生产效率。它不仅强化了语法高亮、快速信息提示、导航栏、滚动条和显示质量,还集成了自动版本号更新、括号自动补全、支持高级编辑功能的智能工具栏、代码分析等功能。 支持 Visual Studio 版本 Visu


2026:一名码农的“不靠谱”年度规划
苏渡苇2026/1/6

又到了一年一度列计划的时候,我对着屏幕敲下“2026年度目标”这几个字,感觉就像在代码里写下了一个暂时没有具体实现的接口——定义很美好,实现嘛,有待观察。 一、工作要干得出彩,还得有点新花样 说真的,每年我都告诉自己,今年一定要写出那种能让同事看了忍不住赞叹“妙啊”的代码。但实际情况往往是,我对着三年前自己写的代码陷入沉思:“这真是我写的吗?当时怎么想的?” 新点子倒是不缺,缺的是能让这些点子安全落地还不引起生产事故的魔法。我现在的原则是:每个炫酷的想法,都必须配套一个“搞砸了怎么办”的预案。

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客