目录
本文将通过具体示例演示如何通过Spring Boot 2.7.2框架调用DeepSeek的API服务。我们将使用Java 11和最新的Spring Boot 2.7.2版本实现完整的集成流程。
前置准备
- 有效的DeepSeek API密钥(密钥注册地址)
- JDK 11或更高版本
- Maven 3.6.3
- Postman(用于API测试验证)
详细可见官方DeepSeek API文档
步骤1:创建Spring Boot项目
通过Spring Initializr创建项目:
- Project: Maven
- Language: Java
- Packaging: Jar
- Java Version: 11
- Dependencies:
- Spring Web
- Lombok
- Jackson Databind
<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
中添加配置:
deepseek:
api:
base-url: https://api.deepseek.com/v1
chat-endpoint: /v1/chat/completions
api-key: your_api_key_here
步骤3:创建请求/响应DTO
// 请求体
@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客户端
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:创建控制器
@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:异常处理
全局异常处理器:
@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:测试验证
单元测试示例
@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测试请求
POST http://localhost:8080/api/chat
Headers:
Content-Type: application/json
Body:
{
"messages": [
{
"content": "如何学习java编程?",
"role": "user"
}
],
"model": "deepseek-chat",
"temperature": 0.7
}
常见问题排查
401 Unauthorized
- 检查API密钥有效性
- 验证Authorization头部格式
序列化错误
- 确认DTO字段命名与API文档一致
- 检查Jackson注解配置
超时问题
- 调整连接超时设置
- 检查网络防火墙配置
速率限制
- 实现令牌桶限流算法
- 监控X-RateLimit-*响应头
402 Payment Required 错误
- API账户余额耗尽
- API密钥未绑定有效支付方式
- 请求参数触发了计费规则
- 模型调用超出免费额度