Spring Boot 实战:接入 DeepSeek API 实现问卷文本优化
本文结合 Spring Boot 项目,介绍如何接入 DeepSeek API,自动优化问卷文本,并给出完整示例代码及详细注释。
一、项目目标
目标是实现一个 REST 接口,将原始问卷文本提交给 DeepSeek API,然后返回优化后的文本给前端。
接口示例:
POST /api/test/refine
Content-Type: application/json{"questionnaire": "这是原始问卷文本..."
}
返回示例:
"这是优化后的问卷文本,语法更规范,表达更专业。"
二、Maven 依赖配置
项目使用 Unirest 发送 HTTP 请求,Maven 依赖如下:
<dependency><groupId>com.konghq</groupId><artifactId>unirest-java</artifactId><version>3.14.1</version> <!-- 请使用最新版本 -->
</dependency>
三、配置 DeepSeek
1. application.yml
使用 Spring Boot 的配置文件绑定 API Key 和其他参数:
deepseek:api-key: ${DEEPSEEK_APIKEY} # 从环境变量读取,避免泄露model: deepseek-chattimeout: 30000
💡 建议使用环境变量存储敏感信息,如
DEEPSEEK_APIKEY
,防止泄露到版本库。
2. 配置类绑定
通过 @ConfigurationProperties
批量绑定配置,并提供 Getter/Setter:
@Configuration
@ConfigurationProperties(prefix = "deepseek") // 绑定 deepseek 前缀的配置
public class DeepSeekConfig {/** API 密钥(必须配置,不能为空) */private String apiKey;/** API 地址(默认值:DeepSeek 官方聊天接口) */private String apiUrl = "https://api.deepseek.com/chat/completions";/** 模型名称(默认值:deepseek-chat) */private String model = "deepseek-chat";/** 超时时间(单位:毫秒,默认30秒) */private int timeout = 30000;// Getter & Setterpublic String getApiKey() { return apiKey; }public void setApiKey(String apiKey) { this.apiKey = apiKey; }public String getApiUrl() { return apiUrl; }public void setApiUrl(String apiUrl) { this.apiUrl = apiUrl; }public String getModel() { return model; }public void setModel(String model) { this.model = model; }public int getTimeout() { return timeout; }public void setTimeout(int timeout) { this.timeout = timeout; }
}
✅ 注意:必须提供 Setter 方法,否则 Spring Boot 无法注入配置值。
四、实现 DeepSeek 服务
封装 DeepSeek 请求逻辑,提供问卷文本优化方法:
@Service
public class DeepseekService {private final DeepSeekConfig config;// 构造函数注入配置类public DeepseekService(DeepSeekConfig config) {this.config = config;// 初始化 Unirest 超时设置Unirest.config().socketTimeout(60_000) // 读取超时 60 秒.connectTimeout(10_000); // 连接超时 10 秒}/*** 优化问卷文本* @param content 原始问卷文本* @return 优化后的文本或错误信息*/public String refineQuestionnaire(String content) {try {// 构建 DeepSeek 消息列表JSONArray messages = new JSONArray();// 系统角色提示:告诉 AI 我们的优化目标messages.put(new JSONObject().put("role", "system").put("content", "你是一个专业的问卷优化助手,任务是优化文本的语法和表达,使其更专业、清晰。"));// 用户原始内容messages.put(new JSONObject().put("role", "user").put("content", "这是原始问卷内容:\n" + content + "\n请输出优化后的版本,不要说其他话。"));// 构建请求体 JSONJSONObject requestBody = new JSONObject().put("model", config.getModel()).put("messages", messages).put("frequency_penalty", 0).put("max_tokens", 2048).put("presence_penalty", 0).put("response_format", new JSONObject().put("type", "text")).put("stream", false).put("temperature", 0.7).put("top_p", 1);// 发送 POST 请求到 DeepSeek APIHttpResponse<String> response = Unirest.post(config.getApiUrl()).header("Authorization", "Bearer " + config.getApiKey()) // 授权.header("Content-Type", "application/json") // JSON 请求.body(requestBody.toString()) // 请求体.asString();// 处理响应if (response.getStatus() == 200) {JSONObject responseBody = new JSONObject(response.getBody());JSONArray choices = responseBody.getJSONArray("choices");if (choices.length() > 0) {// 返回优化后的文本return choices.getJSONObject(0).getJSONObject("message").getString("content");}return "优化失败:未获取到有效内容";} else {// 打印当前 API Key 方便调试System.out.println("当前API Key: [" + config.getApiKey() + "]");return "优化失败:状态码 " + response.getStatus() + ",错误信息:" + response.getBody();}} catch (Exception e) {return "优化出错:" + e.getMessage();}}// 应用关闭时释放资源public void shutdown() {Unirest.shutDown();}
}
五、Controller 接口暴露
提供 REST 接口,前端直接调用:
@RestController
@RequestMapping("/api/test")
public class TestController {@Autowiredprivate DeepseekService deepseekService;/*** POST /api/test/refine* @param content 原始问卷文本* @return 优化后的文本*/@PostMapping("/refine")public String testRefinement(@RequestBody String content) {// 调用 DeepSeek 服务优化文本return deepseekService.refineQuestionnaire(content);}
}
前端只需 POST 原始问卷文本,即可获得优化后的版本。
六、接入注意事项
- API Key 安全:建议放在环境变量中,通过
${DEEPSEEK_APIKEY}
引用; - 配置注入生效:确保
DeepSeekConfig
提供 Getter/Setter,并放在 Spring 扫描路径下; - 调试 401/404 错误:
- 401 → 检查 API Key 是否正确、是否被环境变量覆盖;
- 404 → 检查 API URL 是否正确;
- Unirest 超时配置:避免请求长时间阻塞;
- 关闭资源:
DeepseekService.shutdown()
在应用关闭时释放资源。