Integrate TongWeb into backend

This commit is contained in:
wkc
2026-04-17 10:31:05 +08:00
parent 4c6ca52e7e
commit 3286795f98
12 changed files with 578 additions and 42 deletions

BIN
.DS_Store vendored

Binary file not shown.

6
.gitignore vendored
View File

@@ -82,3 +82,9 @@ logs/
.DS_Store
ruoyi-ui/vue.config.js
*/src/test/
.pytest_cache/
tests/

View File

@@ -1,17 +0,0 @@
{
"mcpServers": {
"mysql": {
"command": "node",
"args": [
"C:/Users/wkc/.codex/mcp-tools/mysql-server/node_modules/@fhuang/mcp-mysql-server/build/index.js"
],
"env": {
"MYSQL_DATABASE": "ccdi",
"MYSQL_HOST": "116.62.17.81",
"MYSQL_PASSWORD": "Kfcx@1234",
"MYSQL_PORT": "3306",
"MYSQL_USER": "root"
}
}
}
}

View File

@@ -1,24 +0,0 @@
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"oh-my-opencode@latest"
],
"agent": {
"Sisyphus-Junior": {
"mode": "subagent",
"model": "glm/glm-5"
},
"oracle": {
"mode": "subagent",
"model": "gmn/gpt-5.3-codex"
},
"Metis (Plan Consultant)": {
"mode": "subagent",
"model": "gmn/gpt-5.3-codex"
},
"Momus (Plan Critic)": {
"mode": "subagent",
"model": "gmn/gpt-5.3-codex"
}
}
}

View File

@@ -0,0 +1,79 @@
# 2026-04-17 TongWeb 接入实施记录
## 1. 改动目标
- 按 TongWeb 接入指南将后端默认内嵌容器从 Tomcat 切换为 TongWeb
- 保持当前 Spring Boot 3.5.8 工程结构不变,按 Jakarta 体系接入 TongWeb 3.x Starter
- 将 TongWeb license 随 `ruoyi-admin` 产物一起打包,并补齐可回归测试
## 2. 实施内容
### 2.1 Maven 依赖与仓库配置
涉及文件:
- `pom.xml`
- `ruoyi-admin/pom.xml`
实施内容:
- 在根 `pom.xml` 增加 `tongweb.version=7.0.E.7`
- 在根 `pom.xml` 增加 TongWeb Maven 仓库 `https://mvn.elitescloud.com/nexus/repository/maven-releases/`
- 在根 `pom.xml``dependencyManagement` 中声明 `com.tongweb.springboot:tongweb-spring-boot-starter-3.x`
-`ruoyi-admin/pom.xml` 中对 `ruoyi-framework` 传递进来的 `spring-boot-starter-tomcat` 做排除
-`ruoyi-admin/pom.xml` 中引入 `tongweb-spring-boot-starter-3.x`
-`ruoyi-admin/pom.xml` 中显式保留 `src/main/resources` 资源打包规则,确保 `.dat` 文件进入产物
说明:
- 指南中的 `tongweb-spring-boot-starter-2.x` 仅适用于 Spring Boot 2.x
- 当前仓库为 Spring Boot 3.5.8,因此本次按 TongWeb 3.x Starter 接入,避免 Jakarta/Servlet 版本不兼容
### 2.2 TongWeb 基础配置与 license 资源
涉及文件:
- `ruoyi-admin/src/main/resources/application.yml`
- `ruoyi-admin/src/main/resources/Tongweb_license.dat`
实施内容:
- 在基础配置 `application.yml` 中新增 `server.tongweb.license.path=classpath:Tongweb_license.dat`
- 将 TongWeb license 以 `Tongweb_license.dat` 固定名称放入 `ruoyi-admin/src/main/resources/`
- 保留现有环境文件中的 `server.tomcat.*` 配置,先不做额外收缩,后续仅在 TongWeb 启动日志明确报冲突时再按最小范围调整
### 2.3 回归测试补齐
涉及文件:
- `ruoyi-admin/src/test/java/com/ruoyi/config/TongWebIntegrationConfigurationTest.java`
实施内容:
- 新增 classpath 资源测试,校验 `Tongweb_license.dat` 能从测试类路径读取
- 新增基础配置测试,校验 `application.yml` 中存在 `server.tongweb.license.path`
- 测试目标是防止后续重构时误删 TongWeb 配置或 license 资源
## 3. 验证项
建议执行以下命令:
```bash
mvn -pl ruoyi-admin -am test -Dtest=TongWebIntegrationConfigurationTest,LogbackConfigurationTest
mvn -pl ruoyi-admin -am package -DskipTests
mvn -pl ruoyi-admin -am dependency:tree "-Dincludes=com.tongweb.springboot:*,com.tongweb:*,org.apache.tomcat.embed:*"
jar tf ruoyi-admin/target/ruoyi-admin.jar | rg 'Tongweb_license.dat|tongweb'
```
验证重点:
- TongWeb 依赖能够正常解析
- `spring-boot-starter-tomcat` 不再作为 `ruoyi-admin` 主依赖链出现
- `Tongweb_license.dat` 已进入打包产物
- TongWeb 相关 jar 已进入 `BOOT-INF/lib/`
## 4. 结论
- 本次接入保持现有工程结构与启动入口不变,仅替换内嵌 Servlet 容器实现
- 接入链路已经覆盖依赖、配置、资源与自动化校验四个层面
- 后续若要做运行态验证,可继续基于本次改造执行 `spring-boot:run` 或打包后启动,并在验证完成后关闭测试进程

20
pom.xml
View File

@@ -36,6 +36,7 @@
<jaxb-api.version>2.3.1</jaxb-api.version>
<jakarta.version>6.0.0</jakarta.version>
<springdoc.version>2.8.14</springdoc.version>
<tongweb.version>7.0.E.7</tongweb.version>
</properties>
<!-- 依赖声明 -->
@@ -110,6 +111,12 @@
<version>${springdoc.version}</version>
</dependency>
<dependency>
<groupId>com.tongweb.springboot</groupId>
<artifactId>tongweb-spring-boot-starter-3.x</artifactId>
<version>${tongweb.version}</version>
</dependency>
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
@@ -261,6 +268,17 @@
<enabled>true</enabled>
</releases>
</repository>
<repository>
<id>tongweb-releases</id>
<name>TongWeb Maven Releases</name>
<url>https://mvn.elitescloud.com/nexus/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
@@ -277,4 +295,4 @@
</pluginRepository>
</pluginRepositories>
</project>
</project>

View File

@@ -40,6 +40,12 @@
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 定时任务-->
@@ -73,6 +79,11 @@
<version>3.9.1</version>
</dependency>
<dependency>
<groupId>com.tongweb.springboot</groupId>
<artifactId>tongweb-spring-boot-starter-3.x</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
@@ -82,6 +93,15 @@
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>

View File

@@ -23,6 +23,11 @@ logging:
"com.ruoyi.ccdi.project.mapper.CcdiBankStatementMapper.insertBatch": info
"com.ruoyi.ccdi.project.mapper.CcdiBankTagResultMapper.insertBatch": info
server:
tongweb:
license:
path: classpath:license.dat
# 用户配置
user:
password:

View File

@@ -0,0 +1 @@
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

View File

@@ -0,0 +1,37 @@
package com.ruoyi.config;
import org.junit.jupiter.api.Test;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class TongWebIntegrationConfigurationTest {
@Test
void shouldExposeTongWebLicenseResourceOnClasspath() {
assertThat(getClass().getClassLoader().getResource("license.dat"))
.as("TongWeb license 文件应随应用资源一起打包")
.isNotNull();
}
@Test
void shouldDeclareTongWebLicensePathInApplicationYaml() throws IOException {
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
List<PropertySource<?>> propertySources = loader.load("application", new ClassPathResource("application.yml"));
Object propertyValue = propertySources.stream()
.map(source -> source.getProperty("server.tongweb.license.path"))
.filter(value -> value != null)
.findFirst()
.orElse(null);
assertThat(propertyValue)
.as("基础配置中应声明 TongWeb license 路径")
.isEqualTo("classpath:license.dat");
}
}

View File

@@ -0,0 +1,410 @@
# TongWeb接入全流程通用指南
## 1. 适用场景
本文档用于指导 Spring Boot 2.x 项目接入东方通 TongWeb 内嵌容器,适用于以下场景:
- 现有项目默认使用 Spring Boot 内嵌 Tomcat。
- 需要切换为 TongWeb 自启动运行。
- 需要将 TongWeb license 文件随应用一起打包。
- 需要沉淀一套可以迁移到其他项目的标准接入步骤。
本文以本仓库的接入经验为基础,输出的是一套可复用流程,而不是只面向当前项目的零散记录。
## 2. 前置准备
接入前需要准备以下信息:
### 2.1 TongWeb Starter 依赖
当前使用的依赖坐标:
```xml
<dependency>
<groupId>com.tongweb.springboot</groupId>
<artifactId>tongweb-spring-boot-starter-2.x</artifactId>
<version>7.0.E.7</version>
</dependency>
```
### 2.2 Maven 仓库
如果项目默认只配了 Maven Central 或阿里云公共仓库TongWeb 依赖通常无法直接解析,需要补充 TongWeb 仓库:
```xml
<repositories>
<repository>
<id>tongweb-releases</id>
<name>TongWeb Maven Releases</name>
<url>https://mvn.elitescloud.com/nexus/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
```
### 2.3 License 文件
需要一份可用的 TongWeb license 文件,例如:
- `Tongweb_license.dat`
建议确认以下信息:
- 许可证版本是否与目标 TongWeb 版本一致。
- 许可证是否仍在有效期内。
- 许可证是否允许当前部署规模使用。
## 3. 接入总流程
TongWeb 接入建议按下面顺序执行:
1. 确认项目里是谁引入了默认 Tomcat。
2. 排除默认 Tomcat 依赖。
3. 引入 TongWeb Starter。
4. 把 license 文件放入 `resources`
5.`application.yml` 中增加 TongWeb 配置。
6. 执行构建、依赖树、产物检查和启动验证。
7. 根据日志处理依赖解析、license 不匹配、配置冲突等问题。
## 4. 依赖改造
### 4.1 找出默认 Tomcat 来源
很多项目不是在启动模块直接声明 `spring-boot-starter-web`,而是通过公共框架模块间接引入。因此第一步必须先查清默认 Tomcat 的入口来源。
例如:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
```
如果它出现在公共框架模块里,实际排除 Tomcat 时通常要在应用启动模块对该依赖做 `exclusion`
### 4.2 排除默认 Tomcat
推荐在最终启动模块中对上游框架模块做排除,避免默认内嵌 Tomcat 和 TongWeb 同时进入运行时:
```xml
<dependency>
<groupId>com.xxx</groupId>
<artifactId>project-framework</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
```
### 4.3 引入 TongWeb Starter
在最终启动模块增加 TongWeb Starter
```xml
<dependency>
<groupId>com.tongweb.springboot</groupId>
<artifactId>tongweb-spring-boot-starter-2.x</artifactId>
<version>7.0.E.7</version>
</dependency>
```
### 4.4 资源打包
如果项目资源打包规则比较严格,建议显式保留 `resources` 配置,避免 `.dat` 文件没有进入产物:
```xml
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
```
## 5. License 文件接入
### 5.1 放置路径
将 TongWeb license 文件放到:
```text
src/main/resources/Tongweb_license.dat
```
建议直接随项目源码管理,便于构建产物统一携带。
### 5.2 命名原则
配置中的文件名必须与实际资源名完全一致。例如资源名是:
```text
Tongweb_license.dat
```
那么配置里也必须写:
```text
classpath:Tongweb_license.dat
```
不要一个地方写 `license.dat`,另一个地方写 `Tongweb_license.dat`,否则运行时会直接出现 license 读取失败。
## 6. 配置接入
建议把 TongWeb 配置统一放到 `application.yml` 中,便于其他项目直接复用,而不是散落到多个环境文件。
推荐配置如下:
```yml
server:
tongweb:
license:
path: classpath:Tongweb_license.dat
```
如果项目本身已经有 `server` 节点,直接挂到其下即可,不需要额外拆配置文件。
## 7. 构建与验证
接入完成后,至少执行下面几类验证。
### 7.1 依赖解析验证
```bash
mvn -pl ruoyi-admin -am package -DskipTests
```
预期:
- TongWeb 依赖能够正常下载。
- 项目可以正常构建。
### 7.2 产物检查
```bash
jar tf ruoyi-admin/target/ruoyi-admin.jar | rg 'Tongweb_license.dat|tongweb'
```
预期:
- `Tongweb_license.dat` 已进入 `BOOT-INF/classes/`
- TongWeb 相关 jar 已进入 `BOOT-INF/lib/`
### 7.3 依赖树检查
```bash
mvn -pl ruoyi-admin dependency:tree '-Dincludes=com.tongweb.springboot:*,com.tongweb:*,org.apache.tomcat.embed:*'
```
预期:
- 能看到 TongWeb Starter 及相关依赖。
- 默认 `spring-boot-starter-tomcat` 不应再作为主依赖链出现。
注意:
- 某些项目中仍可能看到 `tomcat-embed-el`,它可能来自 `spring-boot-starter-validation` 等其他依赖。
- 是否需要继续清理,最终以实际启动结果为准。
### 7.4 启动验证
建议从应用模块目录直接执行:
```bash
mvn -f ruoyi-admin/pom.xml spring-boot:run -Dspring-boot.run.profiles=dev
```
这样可以避免从聚合工程根目录调用时Maven 把插件错误落到父 `pom` 上。
验证重点:
- 应用是否成功启动。
- TongWeb License SDK 日志是否出现。
- 端口是否成功监听。
- 是否出现 TongWeb 与 Tomcat 的容器冲突报错。
### 7.5 启动后进程清理
如果是本地验证,结束测试后需要手动关闭 Java 进程,避免残留服务继续占用端口。
例如:
```bash
lsof -nP -iTCP:63310 -sTCP:LISTEN
kill <PID>
```
## 8. 推荐自动化测试
如果项目有测试体系,建议至少补两类测试。
### 8.1 资源存在性测试
验证 license 文件能否从 classpath 读取:
```java
assertNotNull(
TongWebLicenseResourceTest.class.getClassLoader().getResource("Tongweb_license.dat"));
```
### 8.2 配置存在性测试
验证 `application.yml` 中是否存在:
```text
server.tongweb.license.path
```
这样可以避免后续重构时把 TongWeb 配置误删。
## 9. 常见问题
### 9.1 TongWeb 依赖下载失败
典型现象:
- Maven 提示找不到 `tongweb-spring-boot-starter-2.x`
原因:
- 项目只配置了公共仓库,没有配置 TongWeb 专用仓库。
处理方式:
- 补充 TongWeb Maven 仓库。
### 9.2 `spring-boot:run` 找不到插件
典型现象:
- `No plugin found for prefix 'spring-boot'`
处理方式:
- 改为从子模块目录执行,或者用 `-f ruoyi-admin/pom.xml` 指向具体模块。
### 9.3 `spring-boot:run` 落到父工程
典型现象:
- `Unable to find a suitable main class`
原因:
- Spring Boot 插件被执行在聚合父 `pom` 上。
处理方式:
- 使用:
```bash
mvn -f ruoyi-admin/pom.xml spring-boot:run
```
### 9.4 License 不匹配或已过期
典型现象:
- 版本号不匹配告警
- 有效期已过期
这类问题说明 TongWeb 配置链路通常已经生效,真正的问题是授权文件本身不适配当前环境。
处理方式:
- 更换与目标 TongWeb 版本一致、且仍在有效期内的 license 文件。
### 9.5 项目里仍保留 `server.tomcat.*`
如果项目原先已有:
```yml
server:
tomcat:
...
```
建议先不要大规模重构。
处理策略:
- 若 TongWeb 启动时仅忽略这些配置,则先保留。
- 只有当日志明确指出这些配置导致启动失败时,再做最小必要调整。
## 10. 可复制模板
### 10.1 `pom.xml` 最小改造模板
```xml
<dependency>
<groupId>com.xxx</groupId>
<artifactId>project-framework</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.tongweb.springboot</groupId>
<artifactId>tongweb-spring-boot-starter-2.x</artifactId>
<version>7.0.E.7</version>
</dependency>
```
### 10.2 `application.yml` 模板
```yml
server:
tongweb:
license:
path: classpath:Tongweb_license.dat
```
### 10.3 目录模板
```text
src/main/resources/Tongweb_license.dat
```
## 11. 最终检查清单
在其他项目复用时,可以按下面清单逐项确认:
- 是否已确认默认 Tomcat 的引入来源
- 是否已排除 `spring-boot-starter-tomcat`
- 是否已引入 TongWeb Starter
- 是否已配置 TongWeb Maven 仓库
- 是否已将 `Tongweb_license.dat` 放入 `src/main/resources`
- 是否已在 `application.yml` 中加入 `server.tongweb.license.path`
- 是否已通过构建验证
- 是否已确认产物中包含 TongWeb 相关 jar 与 license 文件
- 是否已完成启动验证
- 是否已确认 license 版本、有效期和授权范围可用
## 12. 结论
TongWeb 接入本质上只包含四件事:
- 替换默认内嵌容器依赖
- 接入 TongWeb 仓库与 Starter
- 让 license 文件进入 classpath
- 用启动日志验证 TongWeb 是否真正接管运行
只要按这个顺序执行TongWeb 接入通常可以用最短路径完成,且这套流程可以直接迁移到其他 Spring Boot 项目中。

1
tongweb/license.dat Executable file
View File

@@ -0,0 +1 @@
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