编辑 | blame | 历史 | 原始文档

功能测试报告_部署包打包与独立启动_2026-09-13

一、功能说明

用户需要把系统打包部署到另一台机器。本轮交付三件事:

1. 一键打包脚本 package-deploy.py(新增)

一条命令完成:前端构建 → 把 dist 内嵌进后端 jar(拷进 src/main/resources/static)→ mvn clean package → 清空 static(保持仓库干净)→ 组装部署目录 → 压缩 zip。

产物:
- 目录 deploy/traffic-audit-deploy-YYYYMMDD/
- 压缩包 traffic-audit-deploy-YYYYMMDD.zip(本次 69.9 MB / 246 个文件)

部署目录结构(沿用 8 月版包习惯):

backend/  jar(含内嵌前端)+ docs/ + application.yml + start-backend.cmd/.sh
frontend/ dist/ + nginx.conf.example        (仅 nginx 方案需要)
db/       init.sql + sql_city_bus.sql + sql_city_taxi.sql + sql_wyc.sql
README-部署说明.txt

2. 修复 JwtUtils:jwt.secret 非法 Base64 导致登录 500(根因修复)

  • 现象(本次烟测实测):把外置 application.yml 的 jwt.secret 填成中文串后,登录接口返回 500 {"code":500,"message":"20018"}。
  • 根因:jjwt 0.9.1 默认把 secret 当 Base64 解码,非法字符会在 DatatypeConverter.guessLength 抛
    ArrayIndexOutOfBoundsException,被 GlobalExceptionHandler 兜成 500。部署同事第一次改配置很容易踩。
  • 处置:JwtUtils 新增 secretKeyBytes()——能按 Base64 解码就用解码结果(与历史 token 兼容),否则按 UTF-8 字节处理并打 WARN。

3. 更正《打包部署说明》(docs/打包部署说明.md)

旧版(2026-08-27)有三处与现状不符,本次一并改正:

旧说明 实际情况 处理
「Redis 后端启动必需」 pom 无 redis 依赖,代码也未使用 改为「不需要 Redis」,并去掉外置配置里的 redis 段
「jar 已内置前端静态托管(file:./web/)」 jar 内无任何静态文件,也没有 static-locations 配置;旧包实际靠 nginx 改为「打包时把 dist 内嵌进 jar」,访问 8090 即可,无需 nginx
数据库只提 3 个脚本 现网还有 wyc_total_monthly / wyc_order_monthly 两张表 补 db/sql_wyc.sql,并补充 summary.template-dir 等配置与时序

二、测试环境

  • 开发机:后端 8090(start-dev.ps1,重启后 PID 变化)、前端 8080、MySQL 127.0.0.1:3308。
  • 部署包验证:把 deploy/traffic-audit-deploy-20260913/backend 拷到 _deploytest/,用 8091 端口独立启动
    (数据库用命令行参数覆盖为 3308,模拟「外置 yml + 命令行覆盖」两种改配置方式)。
  • 测试时间:2026-09-13;脚本:package-deploy.py、_deploy_smoke.py(结果 _deploytest_result.txt、_deploytest_backend.log)。

三、用例表

3.1 正向用例

编号 输入 预期 实际 结论
TC-1 python package-deploy.py --no-build 产出 zip,且无报错 traffic-audit-deploy-20260913.zip 69.9 MB / 246 文件 通过
TC-2 检查 jar 内容 含内嵌前端 jar 55.5 MB,BOOT-INF/classes/static/ 下 42 个文件,static/index.html 存在 通过
TC-3 检查部署目录结构 backend/frontend/db/README 齐全 backend(jar + docs + application.yml + 2 个启动脚本)、frontend/dist、db 4 个 sql、README 通过
TC-4 打包后源码目录 src/main/resources/static 应被清空 打包结束自动清空(仓库无污染) 通过
TC-5 从部署包独立启动(8091) 启动成功 日志出现 Started TrafficAuditApplication、Tomcat started on port(s): 8091 通过
TC-6 GET / 200 且返回页面 200,1828 字节,含 <div id="app"> 通过
TC-7 GET /js/app.*.js 200(静态资源可访问) 200,6253 字节 通过
TC-8 POST /api/auth/login(admin/123456) 200 且返回 token 200,{"code":200,"message":"success","data":{...,"token":"eyJ..."}} 通过
TC-9 带 token 导出《道路运输量汇总表》2026-08 200 且是合法 xlsx 200,950,783 字节,头部 PK(与开发机导出件同尺寸) 通过

3.2 负向用例

编号 输入 预期 实际 结论
TC-N1 修复前:--jwt.secret=这是一个中文密钥 暴露问题 登录 500,日志 ArrayIndexOutOfBoundsException: 20018 at JwtUtils.generateToken 已复现(问题成立)
TC-N2 修复后:同样传中文 secret 不因密钥格式崩,登录仍可用 登录 200 拿到 token;导出同样 200 / 950,783 字节;日志出现「jwt.secret 不是合法的 Base64 字符串…」WARN 通过
TC-N3 外置 application.yml 保留占位密码,用命令行 --spring.datasource.password 覆盖 命令行覆盖生效 启动成功并正常查库(登录 200) 通过
TC-N4 打包脚本重复执行(旧 staging 目录含只读文件) 能清理并重建 首轮报 PermissionError WinError 5,加 rmtree_force(先清只读属性)后正常 已修复

3.3 回归用例

编号 输入 预期 实际 结论
TC-R1 开发机重启后端(载入 JwtUtils 改动) 功能不回归 登录 200;导出 2026-08 → HTTP 200 / 950,783 字节(与部署包产物、9-13 归档件同尺寸) 通过
TC-R2 前端生产构建 构建成功 npm run build 成功,dist/index.html + css/js/fonts 齐全 通过

四、发现的问题与处置

  1. jwt.secret 非法 Base64 → 登录 500(烟测抓到):已按根因修复(Base64 优先、否则 UTF-8 兜底 + WARN),并在打包配置里给出可直接使用的 32 位十六进制示例值、在说明文档里写明取值规则。
  2. 打包脚本清理旧目录被只读文件挡住:源 docs 里有只读 xlsx,copy2 会把只读属性带过去,导致 Windows 下 rmtree 报「拒绝访问」→ 新增 rmtree_force() 先 chmod 再删。
  3. 旧《打包部署说明》三处不实(Redis 必需 / jar 已内置前端 / 缺 sql_wyc.sql):已全部更正,并补上部署后验证清单与常见问题。
  4. 说明:烟测脚本里「拿到 token」那一项打印为 False,是脚本把响应体截断到 120 字符后再判断字符串导致(截断后看不到 "token"),原始响应与后续带 token 的导出请求均成功(HTTP 200),程序本身无问题。

五、结论

  • 打包脚本一键可产出可直接部署的 zip;部署包在**脱离源码目录**、仅靠 jar + docs + 外置配置的前提下,独立启动、页面/静态资源/登录/导出全部通过,导出产物与开发机一致(950,783 字节)。
  • jwt.secret 的部署陷阱已根因修复,部署同事即使填了不规范的值也不会再出现「登录 500」而无从下手。
  • 部署说明已与当前代码对齐(不需要 Redis、不需要 nginx、4 个建表脚本、外置配置项齐全)。