本文将通过 Spring Boot 完整实现一套金蝶接口集成模型,包括:
src/
├── controller/
│ └── KingdeeController.java // API 接口
├── service/
│ ├── KingdeeService.java // 登录/注销逻辑
├── component/
│ └── KingdeeSessionManager.java // Cookie 管理
├── resources/
│ └── static/pages/kingdee.html // 前端测试页
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;
}
}
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";
@Autowired
private 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);
// 记录 Cookie
sessionManager.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", // AppSecret
2052
});
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),则清除本地 cookie
if ("true".equalsIgnoreCase(response.getBody().trim())) {
sessionManager.clear();
}
return response.getBody();
}
}
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 {
@Autowired
private 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());
}
}
}
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>
Set-Cookie
头返回一个会话IDKingdeeSessionManager
自动管理 Cookie,无需手动处理官方开放平台:
callKingdeeService(String serviceName, Object[] parameters)
通用调用方法