Spring Boot 调用DeepSeek API的详细教程

目录

本文将通过具体示例演示如何通过Spring Boot 2.7.2框架调用DeepSeek的API服务。我们将使用Java 11和最新的Spring Boot 2.7.2版本实现完整的集成流程。

前置准备

  1. 有效的DeepSeek API密钥(密钥注册地址)
  2. JDK 11或更高版本
  3. Maven 3.6.3
  4. Postman(用于API测试验证)
    详细可见官方DeepSeek API文档

步骤1:创建Spring Boot项目

通过Spring Initializr创建项目:

  • Project: Maven
  • Language: Java
  • Packaging: Jar
  • Java Version: 11
  • Dependencies :
    • Spring Web
    • Lombok
    • Jackson Databind
java 复制代码
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.15.3</version> <!-- 可替换为最新版本 -->
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
    <scope>provided</scope>
</dependency>

步骤2:配置API参数

application.yml中添加配置:

yaml 复制代码
deepseek:
  api:
    base-url: https://api.deepseek.com/v1
    chat-endpoint: /v1/chat/completions
    api-key: your_api_key_here

步骤3:创建请求/响应DTO

java 复制代码
// 请求体
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatRequest {
    private String model;
    private List<Message> messages;
    private double temperature;
    
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Message {
        private String role;
        private String content;
    }
}

// 响应体
@Data
public class ChatResponse {
    private String id;
    private String object;
    private long created;
    private List<Choice> choices;
    
    @Data
    public static class Choice {
        private Message message;
        private int index;
        private String finish_reason;
        
        @Data
        public static class Message {
            private String role;
            private String content;
        }
    }
}

步骤4:实现API客户端

java 复制代码
package com.tianwen.service.impl;

import com.tianwen.deepseekDTO.ChatRequest;
import com.tianwen.deepseekDTO.ChatResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;

import javax.annotation.PostConstruct;

@Service
public class DeepSeekLegacyClient {

    @Value("${deepseek.api.api-key}")
    private String apiKey;

    @Value("${deepseek.api.base-url}")
    private String baseUrl;

    private RestTemplate restTemplate;

    @Autowired
    private RestTemplateBuilder builder;

    @PostConstruct  // 确保依赖注入完成后执行
    public void init() {
        this.restTemplate = builder
                .rootUri(baseUrl)
                .defaultHeader("Authorization", "Bearer " + apiKey)
                .build();
    }

    public DeepSeekLegacyClient(RestTemplateBuilder builder) {
        this.restTemplate = builder
                .rootUri(baseUrl)
                .defaultHeader("Authorization", "Bearer " + apiKey)
                .build();
    }

    public ChatResponse chatCompletion(ChatRequest request) {
        String fullUrl = baseUrl + "/chat/completions";  // 手动拼接完整路径
        HttpEntity<ChatRequest> entity = new HttpEntity<>(request);
        ResponseEntity<ChatResponse> response = restTemplate.postForEntity(
                fullUrl,
                entity,
                ChatResponse.class
        );

        return response.getBody();
    }
}



@Configuration
public class WebClientConfig {
    
    @Value("${deepseek.api.base-url}")
    private String baseUrl;
    
    @Value("${deepseek.api.api-key}")
    private String apiKey;
    
    @Bean
    public WebClient webClient() {
        return WebClient.builder()
            .baseUrl(baseUrl)
            .defaultHeader("Authorization", "Bearer " + apiKey)
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .build();
    }
}

步骤5:创建控制器

java 复制代码
@RestController
@RequestMapping("/api/chat")
@RequiredArgsConstructor
public class ChatController {
    
    private final DeepSeekClient deepSeekClient;
    
    @PostMapping
    public ResponseEntity<ChatResponse> chat(@RequestBody ChatRequest request) {
        return ResponseEntity.ok(deepSeekClient.chatCompletion(request));
    }
}

步骤6:异常处理

全局异常处理器:

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    // 修改WebClient异常处理
    @ExceptionHandler(WebClientResponseException.class)
    public ResponseEntity<String> handleWebClientErrors(WebClientResponseException ex) {
        return ResponseEntity.status(ex.getRawStatusCode())
            .body("API Communication Error: " + ex.getResponseBodyAsString());
    }
}

步骤7:测试验证

单元测试示例

java 复制代码
@SpringBootTest
class DeepSeekClientTest {
    
    @Autowired
    private DeepSeekClient client;
    
    @Test
    void testChatCompletion() {
        ChatRequest request = ChatRequest.builder()
            .model("deepseek-chat")
            .temperature(0.7)
            .messages(List.of(
                new ChatRequest.Message("user", "你好,介绍一下你自己")
            ))
            .build();
        
        ChatResponse response = client.chatCompletion(request);
        assertNotNull(response);
        assertFalse(response.getChoices().isEmpty());
    }
}

Postman测试请求

json 复制代码
POST http://localhost:8080/api/chat
Headers:
Content-Type: application/json

Body:
{
  "messages": [
    {
      "content": "如何学习java编程?",
      "role": "user"
    }
  ],
  "model": "deepseek-chat",
  "temperature": 0.7
}

常见问题排查

  1. 401 Unauthorized

    • 检查API密钥有效性
    • 验证Authorization头部格式
  2. 序列化错误

    • 确认DTO字段命名与API文档一致
    • 检查Jackson注解配置
  3. 超时问题

    • 调整连接超时设置
    • 检查网络防火墙配置
  4. 速率限制

    • 实现令牌桶限流算法
    • 监控X-RateLimit-*响应头
  5. 402 Payment Required 错误

    • API账户余额耗尽
    • API密钥未绑定有效支付方式
    • 请求参数触发了计费规则
    • 模型调用超出免费额度
相关推荐
你的人类朋友几秒前
【Docker】说说卷挂载与绑定挂载
后端·docker·容器
间彧24 分钟前
在高并发场景下,如何平衡QPS和TPS的监控资源消耗?
后端
间彧26 分钟前
QPS和TPS的区别,在实际项目中,如何准确测量和监控QPS和TPS?
后端
zizisuo42 分钟前
解决在使用Lombok时maven install 找不到符号的问题
java·数据库·maven
间彧1 小时前
消息队列(RocketMQ、RabbitMQ、Kafka、ActiveMQ)对比与选型指南
后端·消息队列
笨蛋少年派1 小时前
JAVA基础语法
java·开发语言
Haooog1 小时前
654.最大二叉树(二叉树算法)
java·数据结构·算法·leetcode·二叉树
我真的是大笨蛋1 小时前
依赖倒置原则(DIP)
java·设计模式·性能优化·依赖倒置原则·设计规范
brzhang2 小时前
AI Agent 干不好活,不是它笨,告诉你一个残忍的现实,是你给他的工具太难用了
前端·后端·架构
东方芷兰2 小时前
JavaWeb 课堂笔记 —— 20 SpringBootWeb案例 配置文件
java·开发语言·笔记·算法·log4j·intellij-idea·lua