# compare-tool **Repository Path**: git_zone/compare-tool ## Basic Information - **Project Name**: compare-tool - **Description**: 接口平迁对比工具 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-11 - **Last Updated**: 2026-03-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 接口平迁比对工具 ## 1. 项目简介 接口平迁比对工具用于对旧链路接口与新链路接口进行逐接口、逐请求的一致性验证,辅助研发和测试人员完成接口平迁验收。 本工具支持对同一请求同时调用原模式与新模式接口,并对返回结果进行严格 JSON 比对,输出精确到字段级的差异路径,同时将执行结果持久化存储,支持历史记录查询与详情回看。 本项目适用于以下场景: - 存量接口平迁验证 - 新旧接口结果一致性比对 - 灰度切换前的数据回归校验 - 研发联调阶段问题定位 - 测试阶段批次化验收留痕 --- ## 2. 功能特性 ### 2.1 单接口双发比对 对同一份请求参数,分别调用: - 原模式接口 - 新模式接口 确保比对基础一致。 ### 2.2 严格 JSON 比对 采用“全字段严格一致”原则,校验以下内容: - 字段是否缺失 - 字段是否新增 - 字段类型是否一致 - 字段值是否一致 - 数组长度是否一致 - 数组节点结构是否一致 ### 2.3 精确差异路径输出 差异结果可精确到字段级,例如: - `root.data.bean.productCode` - `root.data.beans[0].channelCode` - `root.data.object.total` ### 2.4 执行结果留痕 每次执行比对后,结果会保存到 SQLite 数据库,包括: - 请求参数 - 原模式响应 - 新模式响应 - 差异结果 - 执行时间 - 执行人 - 批次号 - 执行耗时 ### 2.5 历史记录查询 支持前端页面查询历史执行记录,查看某次执行的完整详情。 ### 2.6 内置前端页面 项目启动后可直接通过浏览器访问,无需单独部署前端。 --- ## 3. 技术栈 - Spring Boot 2.7.x - MyBatis-Plus 3.5.x - SQLite - Jackson - Lombok - HTML + 原生 JavaScript --- ## 4. 项目结构 ```text compare-tool ├── pom.xml └── src └── main ├── java │ └── com/cmos/comparetool │ ├── config │ ├── controller │ ├── dto │ ├── entity │ ├── mapper │ ├── service │ └── CompareToolApplication.java ├── resources │ ├── application.yml │ ├── schema.sql │ └── static │ └── index.html └── assembly ├── package.xml ├── bin │ └── app.sh └── empty └── .keep ```` --- ## 5. 运行环境 ### 5.1 本地开发环境 * JDK 8 及以上 * Maven 3.6 及以上 * IntelliJ IDEA(推荐) ### 5.2 Linux 部署环境 * Linux x86_64 * JDK 8 及以上 * unzip 命令可用 --- ## 6. 本地启动说明 ### 6.1 拉取代码并进入项目目录 ```bash cd compare-tool ``` ### 6.2 编译启动 ```bash mvn clean spring-boot:run ``` 或者: ```bash mvn clean package java -jar target/compare-tool.jar ``` ### 6.3 浏览器访问 ```text http://localhost:18888/ ``` --- ## 7. SQLite 说明 本项目使用 SQLite 作为本地嵌入式数据库,无需额外部署数据库服务。 ### 7.1 本地运行时 默认会根据 `application.yml` 中配置的路径生成 `.db` 文件。 例如: ```yaml spring: datasource: driver-class-name: org.sqlite.JDBC url: jdbc:sqlite:compare-tool.db ``` 则数据库文件通常生成在项目启动目录下。 ### 7.2 Linux 脚本启动时 启动脚本会将 SQLite 数据库文件放在: ```text ${APP_HOME}/data/compare-tool.db ``` 即解压目录下的 `data/` 目录中。 ### 7.3 注意事项 SQLite 通常可以自动创建数据库文件,但不一定自动创建父目录,因此部署脚本中已自动创建 `data/` 目录。 --- ## 8. 前端页面说明 首页地址: ```text http://localhost:18888/ ``` 页面支持以下能力: * 填写接口编码、接口名称、分类 * 配置原模式地址、新模式地址 * 输入请求头 JSON * 输入请求体 JSON * 执行单次比对 * 查看差异明细 * 查看原模式响应 * 查看新模式响应 * 查看执行请求 * 查询历史记录 * 查看历史详情 --- ## 9. 核心接口说明 ### 9.1 执行比对接口 **请求方式** ```text POST /api/compare/execute ``` **请求示例** ```json { "batchNo": "BATCH_20260310_001", "executeBy": "tester", "interfaceMeta": { "interfaceCode": "C_GOODS_DETAIL_001", "interfaceName": "商品详情查询接口", "category": "商品详情类", "requestMethod": "POST", "oldUrl": "http://localhost:8081/api/goods/detail", "newUrl": "http://localhost:8082/api/goods/detail" }, "headers": { "token": "test-token", "appId": "h5" }, "requestBody": { "productCode": "P10001", "channelCode": "CH001" } } ``` **返回示例** ```json { "passFlag": false, "batchNo": "BATCH_20260310_001", "interfaceCode": "C_GOODS_DETAIL_001", "interfaceName": "商品详情查询接口", "durationMs": 186, "diffCount": 2, "diffItems": [ { "diffType": "MISSING_FIELD", "path": "root.data.bean.productCode", "oldValue": "\"P10001\"", "newValue": null, "message": "新模式缺失字段" }, { "diffType": "VALUE_MISMATCH", "path": "root.data.beans[0].channelCode", "oldValue": "CH001", "newValue": "CH002", "message": "字段值不一致" } ], "oldResponse": "{...}", "newResponse": "{...}" } ``` --- ### 9.2 分页查询历史记录 **请求方式** ```text GET /api/compare/history ``` **示例** ```text /api/compare/history?pageNo=1&pageSize=10 /api/compare/history?batchNo=BATCH_20260310_001&passFlag=0&pageNo=1&pageSize=10 ``` --- ### 9.3 查询历史详情 **请求方式** ```text GET /api/compare/history/{id} ``` **示例** ```text /api/compare/history/1 ``` --- ## 10. 差异类型说明 当前工具支持输出以下差异类型: | 差异类型 | 说明 | | --------------------- | ------- | | `MISSING_FIELD` | 新模式缺失字段 | | `EXTRA_FIELD` | 新模式新增字段 | | `TYPE_MISMATCH` | 字段类型不一致 | | `VALUE_MISMATCH` | 字段值不一致 | | `ARRAY_SIZE_MISMATCH` | 数组长度不一致 | --- ## 11. 数据库表说明 ### 11.1 表名 ```text t_compare_record ``` ### 11.2 主要字段 | 字段名 | 说明 | | ----------------- | ----- | | `id` | 主键 | | `batch_no` | 批次号 | | `interface_code` | 接口编码 | | `interface_name` | 接口名称 | | `category` | 接口分类 | | `request_method` | 请求方式 | | `old_url` | 原模式地址 | | `new_url` | 新模式地址 | | `request_headers` | 请求头 | | `request_body` | 请求体 | | `old_response` | 原模式响应 | | `new_response` | 新模式响应 | | `diff_result` | 差异结果 | | `pass_flag` | 是否通过 | | `execute_by` | 执行人 | | `execute_time` | 执行时间 | | `duration_ms` | 执行耗时 | | `remark` | 备注 | --- ## 12. 打包说明 ### 12.1 执行打包 ```bash mvn clean package ``` ### 12.2 打包产物 执行成功后,会在 `target/` 目录下生成: * `compare-tool.jar` * `compare-tool-YYYYMMddHHmmss.zip` 例如: ```text compare-tool-20260311153045.zip ``` --- ## 13. 压缩包目录结构 zip 包解压后目录结构如下: ```text compare-tool ├── bin │ ├── app.sh │ └── compare-tool.jar ├── data └── logs ``` 说明: * `bin/`:存放启动脚本和 jar 包 * `data/`:存放 SQLite 数据库文件 * `logs/`:存放运行日志 --- ## 14. Linux 部署说明 ### 14.1 上传压缩包 将生成的 zip 包上传到 Linux 服务器任意目录,例如: ```bash scp target/compare-tool-20260311153045.zip user@host:/home/user/ ``` ### 14.2 解压 ```bash unzip compare-tool-20260311153045.zip ``` ### 14.3 启动服务 ```bash cd compare-tool/bin sh app.sh start ``` ### 14.4 常用命令 启动: ```bash sh app.sh start ``` 停止: ```bash sh app.sh stop ``` 重启: ```bash sh app.sh restart ``` 查看状态: ```bash sh app.sh status ``` 查看日志: ```bash sh app.sh logs ``` --- ## 15. 启动脚本说明 启动脚本会自动完成以下工作: * 自动识别解压根目录 * 自动创建 `data/` 目录 * 自动创建 `logs/` 目录 * 自动将 SQLite 数据库文件放到 `data/` * 自动将日志输出到 `logs/console.out` 因此该压缩包可直接复制到 Linux 主机任意目录使用,无需修改脚本中的固定路径。 --- ## 16. 开发注意事项 ### 16.1 页面访问方式 建议通过 Spring Boot 服务访问页面: ```text http://localhost:18888/ ``` 不要直接使用 IDEA 的静态预览端口访问,否则相对路径接口请求可能会错误地发送到 IDE 预览服务端口。 ### 16.2 SQLite 初始化 若 `schema.sql` 中使用的是: ```sql CREATE TABLE IF NOT EXISTS t_compare_record ( id INTEGER PRIMARY KEY AUTOINCREMENT, batch_no TEXT NOT NULL, interface_code TEXT NOT NULL, interface_name TEXT NOT NULL, category TEXT, request_method TEXT NOT NULL, old_url TEXT NOT NULL, new_url TEXT NOT NULL, request_headers TEXT, request_body TEXT, old_response TEXT, new_response TEXT, diff_result TEXT, pass_flag INTEGER NOT NULL, execute_by TEXT, execute_time TEXT NOT NULL, duration_ms INTEGER, remark TEXT ); -- 表名:t_compare_record -- 表含义: -- 接口平迁比对结果记录表。 -- 用于保存每次执行接口比对后的留痕数据,包括请求参数、原模式响应、新模式响应、 -- 差异结果、执行人、执行时间、耗时等信息,支撑历史记录查询、问题排查与回归验证。 CREATE TABLE IF NOT EXISTS t_compare_record ( -- 主键ID -- SQLite 自增主键,用于唯一标识一条比对记录 id INTEGER PRIMARY KEY AUTOINCREMENT, -- 批次号 -- 用于标识同一轮或同一批次的比对任务,便于按批次归档和查询 batch_no TEXT NOT NULL, -- 接口编码 -- 用于唯一标识某一个被比对的接口,例如:C_GOODS_DETAIL_001 interface_code TEXT NOT NULL, -- 接口名称 -- 接口的中文名称或业务名称,便于页面展示和人工识别 interface_name TEXT NOT NULL, -- 接口分类 -- 接口所属业务分类,例如:商品详情类、商品列表类、渠道类等 category TEXT, -- 请求方式 -- 接口调用方式,例如:GET、POST request_method TEXT NOT NULL, -- 原模式地址 -- 原有链路的接口地址,用于记录比对时调用的旧接口 old_url TEXT NOT NULL, -- 新模式地址 -- 新链路或适配服务接口地址,用于记录比对时调用的新接口 new_url TEXT NOT NULL, -- 请求头 -- 调用接口时使用的请求头,通常以 JSON 字符串形式保存 request_headers TEXT, -- 请求体 -- 调用接口时使用的请求报文,通常以 JSON 字符串形式保存 request_body TEXT, -- 原模式响应 -- 原模式接口返回的完整响应报文,通常以 JSON 字符串形式保存 old_response TEXT, -- 新模式响应 -- 新模式接口返回的完整响应报文,通常以 JSON 字符串形式保存 new_response TEXT, -- 差异结果 -- 原模式与新模式响应比对后的差异明细,通常以 JSON 字符串形式保存 diff_result TEXT, -- 是否通过 -- 比对结果标识: -- 1:通过(无差异) -- 0:失败(存在差异) pass_flag INTEGER NOT NULL, -- 执行人 -- 记录本次比对的执行人员 execute_by TEXT, -- 执行时间 -- 本次比对任务的执行时间,建议格式:yyyy-MM-dd HH:mm:ss execute_time TEXT NOT NULL, -- 执行耗时 -- 本次比对从发起到完成的耗时,单位毫秒 duration_ms INTEGER, -- 备注 -- 预留扩展字段,用于记录附加说明、异常备注、人工结论等 remark TEXT ); ``` 则不会清空已有数据。 若脚本中存在 `DROP TABLE`、`DELETE FROM` 等语句,则可能导致数据丢失。 ### 16.3 历史记录 每次执行比对都会落库,若历史记录较多,可后续扩展清理策略或归档方案。 --- ## 17. 后续可扩展方向 当前版本为最小可运行版本,后续可扩展: * 接口清单管理 * 批量执行比对 * 报表统计 * Excel 导出 * 历史记录删除 * 历史记录重试 * 登录鉴权 * 任务调度执行 * Flyway/Liquibase 数据库版本管理 --- ## 18. 常见问题 ### 18.1 SQLite 启动时报 unable to open database file 通常原因: * 数据库父目录不存在 * 启动目录与预期不一致 * 数据库路径不可写 建议优先: * 使用绝对路径 * 或通过脚本自动创建 `data/` 目录 * 或将数据库文件放在应用根目录 ### 18.2 页面接口请求返回 404 若页面是通过 IDEA 预览端口打开的,相对路径请求会发到 IDEA 端口,而不是 Spring Boot 服务端口。 建议直接访问: ```text http://localhost:18888/ ``` ### 18.3 历史记录接口飘红 如果 `CompareController` 中引用的以下类不存在,需要补齐 DTO: * `CompareHistoryDetailResponse` * `CompareHistoryItemResponse` * `CompareHistoryQueryRequest` * `PageResponse` --- ## 19. 作者说明 本工具为接口平迁验证场景设计,当前版本聚焦于: * 单接口严格比对 * 历史记录留痕 * 本地可运行 * Linux 可直接解压部署 后续可根据项目实际需求继续扩展。