? Spring Boot 集成金蝶 API 演示:登錄 / 注銷 + Cookie 保存
本文將通過 Spring Boot 完整實現一套金蝶接口集成模型,包括:
- ? 普通登錄
- ? AppSecret 登錄
- ? 注銷
- ? Cookie 保存與復用
📅 項目結構
src/
├── controller/
│ └── KingdeeController.java // API 接口
├── service/
│ ├── KingdeeService.java // 登錄/注銷邏輯
├── component/
│ └── KingdeeSessionManager.java // Cookie 管理
├── resources/
│ └── static/pages/kingdee.html // 前端測試頁
? 1. Cookie 保存組件 KingdeeSessionManager
package org.example.component;import org.springframework.stereotype.Component;import java.util.List;/*** ==================================================* This class KingdeeSessionManager is responsible for [功能描述].** @author Darker* @version 1.0* ==================================================*/@Component
public class KingdeeSessionManager {private String cookie;public void saveFromHeaders(List<String> cookies) {if (cookies != null && !cookies.isEmpty()) {// 可擴展支持多個 Cookie,但這里我們只取第一個this.cookie = cookies.get(0);}}public String getCookie() {return this.cookie;}public boolean hasCookie() {return cookie != null && !cookie.isEmpty();}public void clear() {this.cookie = null;}
}
? 2. 金蝶服務層 KingdeeService
package org.example.service;import org.example.component.KingdeeSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;import java.util.HashMap;
import java.util.Map;/*** ==================================================* This class KingdeeService is responsible for 金蝶 API 服務.** @author Darker* @version 2.0* ==================================================*/
@Service
public class KingdeeService {private static final String BASE_URL = "https://your.kingdee.server/K3Cloud";@Autowiredprivate KingdeeSessionManager sessionManager;private ResponseEntity<String> postWithOptionalCookie(String url, Map<String, Object> payload, boolean withCookie) {RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);if (withCookie && sessionManager.hasCookie()) {headers.add("Cookie", sessionManager.getCookie());}HttpEntity<Map<String, Object>> request = new HttpEntity<>(payload, headers);return restTemplate.postForEntity(url, request, String.class);}/*** 普通登錄*/public String login() {String url = BASE_URL + "/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc";Map<String, Object> payload = new HashMap<>();payload.put("parameters", new Object[]{"你的數據中心 ID", "你的用戶名", "你的密碼", 2052});ResponseEntity<String> response = postWithOptionalCookie(url, payload, false);// 記錄 CookiesessionManager.saveFromHeaders(response.getHeaders().get(HttpHeaders.SET_COOKIE));return response.getBody();}/*** AppSecret 登錄*/public String loginByAppSecret() {String url = BASE_URL + "/Kingdee.BOS.WebApi.ServicesStub.AuthService.LoginByAppSecret.common.kdsvc";Map<String, Object> payload = new HashMap<>();payload.put("parameters", new Object[]{"你的數據中心 ID", // 數據中心 ID"你的用戶名", // 用戶名"你的 AppID", // AppID"你的 AppSecret", // AppSecret2052});ResponseEntity<String> response = postWithOptionalCookie(url, payload, false);sessionManager.saveFromHeaders(response.getHeaders().get(HttpHeaders.SET_COOKIE));return response.getBody();}/*** 注銷:需要攜帶 Cookie*/public String logout() {String url = BASE_URL + "/Kingdee.BOS.WebApi.ServicesStub.AuthService.Logout.common.kdsvc";Map<String, Object> payload = new HashMap<>();payload.put("parameters", new Object[]{});ResponseEntity<String> response = postWithOptionalCookie(url, payload, true);// 如果注銷成功(返回 true),則清除本地 cookieif ("true".equalsIgnoreCase(response.getBody().trim())) {sessionManager.clear();}return response.getBody();}
}
? 3. Controller 接口 KingdeeController
package org.example.controller;import org.example.service.KingdeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.util.UriComponentsBuilder;/*** ==================================================* This class KingdeeController is responsible for [功能描述].** @author Darker* @version 1.0* ==================================================*/@RestController
@RequestMapping("/kingdee")
public class KingdeeController {@Autowiredprivate KingdeeService kingdeeService;@GetMapping("/login")public ResponseEntity<?> login() {try {String result = kingdeeService.login();return ResponseEntity.ok(result);} catch (Exception e) {return ResponseEntity.internalServerError().body("登錄失敗:" + e.getMessage());}}@GetMapping("/logout")public ResponseEntity<?> logout() {try {String result = kingdeeService.logout();return ResponseEntity.ok(result);} catch (Exception e) {return ResponseEntity.internalServerError().body("注銷失敗:" + e.getMessage());}}@GetMapping("/login-app-secret")public ResponseEntity<?> loginByAppSecret() {try {String result = kingdeeService.loginByAppSecret();return ResponseEntity.ok(result);} catch (Exception e) {return ResponseEntity.internalServerError().body("AppSecret 登錄失敗:" + e.getMessage());}}
}
? 4. 前端測試頁 kingdee.html
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>金蝶 API 測試</title><script>async function callApi(endpoint) {const res = await fetch(`/kingdee/${endpoint}`);const text = await res.text();document.getElementById('result').innerText = `[${endpoint}]:\n` + text;}</script>
</head>
<body><h2>金蝶 API 測試</h2><button onclick="callApi('login')">普通登錄</button><button onclick="callApi('login-app-secret')">AppSecret 登錄</button><button onclick="callApi('logout')">注銷</button><pre id="result"></pre>
</body>
</html>
?? Cookie 保存說明
- 登錄成功后,金蝶服務器會通過
Set-Cookie
頭返回一個會話ID - 后續操作(注銷 / 探量 / 單據傳遞)必須附帶 Cookie
- 本文中通過
KingdeeSessionManager
自動管理 Cookie,無需手動處理
🔗 金蝶 API 官方開發文檔
官方開放平臺:
- 【K3Cloud Web API】總覽:https://open.kingdee.com
- 登錄接口說明:https://open.kingdee.com/doc/view?doc_id=1055
- App ID / Secret 說明:https://open.kingdee.com/doc/view?doc_id=1297
- 提交單據示例:https://open.kingdee.com/doc/view?doc_id=1061
🔧 擴展方向
- ? 增加
callKingdeeService(String serviceName, Object[] parameters)
通用調用方法 - ? 支持查詢單據 / 提交審核 / 操作單據
- 📄 將登錄狀態持久化到 Redis