Spring Boot 调用泛微 E9 Token 认证 + 创建流程完整教程
本文基于 Spring Boot 项目结构,完整串联 APPID 注册 → Token 认证 → userid 加密 → 调用流程创建接口 的全过程,适合作为
- 企业内部标准示例工程
- 对接泛微 E9 的统一技术模板
- 二次开发 / 联调排障参考
一、整体架构说明(Spring Boot 视角)
E9-workflow-springboot/
├── pom.xml
├── src/main/java
│ └── com/company/e9
│ ├── E9Application.java
│ ├── config
│ │ └── E9Properties.java
│ ├── security
│ │ ├── RsaUtil.java
│ │ └── TokenClient.java
│ ├── workflow
│ │ ├── WorkflowClient.java
│ │ └── WorkflowRequestBuilder.java
│ └── controller
│ └── TestController.java
└── src/main/resources
└── application.yml
职责划分原则:
config:OA 地址、appid、userid 等配置security:RSA、注册、token 获取workflow:流程请求体构建与提交流程controller:对外测试入口(可选)
二、基础依赖(pom.xml)
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- hutool:RSA + HTTP -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies>
三、统一配置(application.yml)
yaml
e9:
base-url: http://xx.xx.xx.xx:8081
appid: EEAA5436-7577-4BE0-8C6C-89E9D88805EA
userid: XXXXX
token-expire: 1800
java
@ConfigurationProperties(prefix = "e9")
@Component
@Data
public class E9Properties {
private String baseUrl;
private String appid;
private String userid;
private Integer tokenExpire;
}
四、Token 认证全过程(核心)
4.1 第一步:注册(只调用一次)
java
public void registIfNeeded() {
if (serverPublicKey != null && serverSecret != null) {
return;
}
RSA rsa = new RSA();
localPrivateKey = rsa.getPrivateKeyBase64();
localPublicKey = rsa.getPublicKeyBase64();
String resp = HttpRequest.post(baseUrl + "/api/ec/dev/auth/regist")
.header("appid", appid)
.header("cpk", localPublicKey)
.disableCookie()
.execute().body();
JSONObject json = JSON.parseObject(resp);
serverPublicKey = json.getString("spk");
serverSecret = json.getString("secrit");
}
⚠️ 注意:
- 该步骤只能执行一次
serverPublicKey / serverSecret必须持久化(DB / 配置中心)
4.2 第二步:获取 Token
java
public String fetchToken() {
registIfNeeded();
RSA rsa = new RSA(null, serverPublicKey);
String encryptSecret = rsa.encryptBase64(serverSecret, KeyType.PublicKey);
String resp = HttpRequest.post(baseUrl + "/api/ec/dev/auth/applytoken")
.header("appid", appid)
.header("secret", encryptSecret)
.header("time", tokenExpire.toString())
.disableCookie()
.execute().body();
return JSON.parseObject(resp).getString("token");
}
4.3 第三步:userid 加密
java
public String encryptUserid() {
RSA rsa = new RSA(null, serverPublicKey);
return rsa.encryptBase64(userid, KeyType.PublicKey);
}
五、流程创建(WorkflowService / REST)
5.1 构建流程请求体
java
public JSONObject buildRequest() {
JSONObject main = new JSONObject();
main.put("field1", "测试标题");
main.put("field2", "2026-01-01");
JSONArray details = new JSONArray();
JSONObject row = new JSONObject();
row.put("detail_field1", "明细A");
row.put("detail_field2", "100");
details.add(row);
JSONObject req = new JSONObject();
req.put("mainData", main);
req.put("detailData", details);
return req;
}
5.2 调用流程创建接口
java
public String submitWorkflow(JSONObject body) {
String token = tokenClient.fetchToken();
return HttpRequest.post(baseUrl + "/api/workflow/create")
.header("appid", appid)
.header("token", token)
.header("userid", tokenClient.encryptUserid())
.header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
.disableCookie()
.body(body.toJSONString())
.execute().body();
}
六、返回结果判定
json
{
"code": 0,
"status": true,
"workflowid": "215021"
}
判定规则:
code == 0 && status == true→ 成功- 否则记录错误日志并回滚
七、常见问题(Spring Boot 场景)
| 问题 | 解决方案 |
|---|---|
| 解密失败 | 检查是否重复 regist、jar 冲突 |
| userid 不生效 | 禁止 Cookie |
| token 很快过期 | 本地缓存 + DB 兜底 |
| 500 错误 | 检查 KB 版本 / session 失效 |
八、最佳实践总结
- regist 永远只执行一次
- token 单例缓存 + 自动刷新
- RSA / Token 与业务代码解耦
- 所有请求统一 disableCookie
- 先 Postman,再 Spring Boot
✅ 本文档可直接作为 Spring Boot + 泛微 E9 接口认证与流程创建的标准模板
九、可直接运行的 Demo 项目说明(补充)
9.1 项目结构(完整)
E9-workflow-springboot-demo/
├── pom.xml
├── README.md
├── src/main/java/com/company/e9
│ ├── E9Application.java
│ ├── config
│ │ └── E9Properties.java
│ ├── security
│ │ ├── RsaUtil.java
│ │ └── TokenClient.java
│ ├── workflow
│ │ ├── WorkflowClient.java
│ │ └── WorkflowRequestBuilder.java
│ └── controller
│ └── WorkflowTestController.java
└── src/main/resources
└── application.yml
9.2 启动类
java
@SpringBootApplication
@EnableConfigurationProperties(E9Properties.class)
public class E9Application {
public static void main(String[] args) {
SpringApplication.run(E9Application.class, args);
}
}
9.3 Controller(一键提交流程)
java
@RestController
@RequestMapping("/test/workflow")
@RequiredArgsConstructor
public class WorkflowTestController {
private final WorkflowClient workflowClient;
private final WorkflowRequestBuilder requestBuilder;
@PostMapping("/submit")
public String submit() {
return workflowClient.submitWorkflow(
requestBuilder.buildDemoRequest()
);
}
}
访问地址:
POST http://localhost:8080/test/workflow/submit
9.4 WorkflowClient(核心提交流程)
java
@Component
@RequiredArgsConstructor
public class WorkflowClient {
private final TokenClient tokenClient;
private final E9Properties props;
public String submitWorkflow(JSONObject body) {
String token = tokenClient.fetchToken();
return HttpRequest.post(props.getBaseUrl() + "/api/workflow/create")
.header("appid", props.getAppid())
.header("token", token)
.header("userid", tokenClient.encryptUserid())
.header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
.disableCookie()
.body(body.toJSONString())
.execute().body();
}
}
9.5 WorkflowRequestBuilder(示例表单数据)
java
@Component
public class WorkflowRequestBuilder {
public JSONObject buildDemoRequest() {
JSONObject main = new JSONObject();
main.put("title", "SpringBoot 提交流程测试");
main.put("apply_date", "2026-01-22");
JSONArray details = new JSONArray();
JSONObject row = new JSONObject();
row.put("fee_type", "差旅费");
row.put("amount", "1000");
details.add(row);
JSONObject req = new JSONObject();
req.put("mainData", main);
req.put("detailData", details);
return req;
}
}
9.6 TokenClient(完整示例)
java
@Component
@RequiredArgsConstructor
public class TokenClient {
private final E9Properties props;
private String serverPublicKey;
private String serverSecret;
private String token;
public synchronized String fetchToken() {
if (StrUtil.isNotBlank(token)) {
return token;
}
registIfNeeded();
RSA rsa = new RSA(null, serverPublicKey);
String encryptSecret = rsa.encryptBase64(serverSecret, KeyType.PublicKey);
String resp = HttpRequest.post(props.getBaseUrl() + "/api/ec/dev/auth/applytoken")
.header("appid", props.getAppid())
.header("secret", encryptSecret)
.header("time", props.getTokenExpire().toString())
.disableCookie()
.execute().body();
token = JSON.parseObject(resp).getString("token");
return token;
}
private void registIfNeeded() {
if (serverPublicKey != null && serverSecret != null) {
return;
}
RSA rsa = new RSA();
String publicKey = rsa.getPublicKeyBase64();
String resp = HttpRequest.post(props.getBaseUrl() + "/api/ec/dev/auth/regist")
.header("appid", props.getAppid())
.header("cpk", publicKey)
.disableCookie()
.execute().body();
JSONObject json = JSON.parseObject(resp);
serverPublicKey = json.getString("spk");
serverSecret = json.getString("secrit");
}
public String encryptUserid() {
RSA rsa = new RSA(null, serverPublicKey);
return rsa.encryptBase64(props.getUserid(), KeyType.PublicKey);
}
}
9.7 使用方式总结
- 修改
application.yml中 OA 地址、appid、userid - 启动 Spring Boot
- 调用
/test/workflow/submit - OA 中查看流程是否创建成功
✅ 至此,你已拥有一套 可直接运行的 Spring Boot + 泛微 E9 Token 认证 + 提交流程 Demo 项目