Files
juzi/docs/SAE-Java-MVP-操作步骤.md
T
xsl f5c416dd9d feat(sae): add cloud-gateway adapters and forward mode (0.0.4)
SAE 上这一版只做云网关适配层:/api/taobao/* 字节级透传给 1me.xajuzi.com 上
现有的 H5 后端(旷视调用、评分、报告都留在那边),Java 不再重写测肤逻辑。

- TaobaoEnvelope:客户端要求的 data.ok + data.http_status 信封(HTTP 恒 200)
- TaobaoAuthController:challenge/session/me/logout(native 模式)
- TaobaoSessionService:一次性 challenge + 30 天 Bearer token,按 open_id 限流
  (网关后面所有请求同源 IP,按 IP 计数会变成全站共享 30 次/分钟)
- TaobaoForwardController:mode=forward 时透传,保留原始 query 与 body 字节
  (签名覆盖原始 body,重新序列化会让验签失败)
- TaobaoSignatureVerifier:缺省 sign_method 按 md5 校验
- 打包名固定为 taobao-mvp-backend-0.0.4-forward,SAE 不需要任何环境变量
- pom 版本 0.0.4;mvn test 11/11(新增 8 个用例)
- docs:更新 SAE 操作步骤,新增本次交接文档
2026-11-01 23:30:35 +08:00

17 KiB
Raw Blame History

淘宝小程序 + Java + SAE 最小 MVP 操作步骤

目标:先用一个最小页面,把 淘宝小程序 → 淘宝云网关(或本地直连)→ Java 后端 → 统一 envelope 返回 这条链路跑通。

本文不包含:真实测肤算法、Face++、账号体系、图片分片上传。这些等链路验证通过后,再按现有 Node 实现的接口契约迁到 Java。

当前时间:2026-10。淘宝开放平台在 2026-05 把聚石塔的部署运维迁到了 ACK/SAE,网上 2023 年以前的“容器部署平台”教程不要照抄。


0. 本次交付物

路径 作用
backend-java/ Spring Boot 3.5.6 + Java 17 的最小后端,含 ping/whoami/echo
backend-java/src/main/java/com/juzi/mvp/gateway/TaobaoSignatureVerifier.java 云网关签名校验,算法与现有 Node 实现一致
taobao/pages/mvp/ 淘宝小程序连通性页面,直接复用现有 utils/transport.js
taobao/config.js 新增 mvpLocal / mvpBaseUrl,不影响主应用原来的 18180 配置
taobao/app.json 注册 pages/mvp/mvp
tools/env-java.ps1 一键加载 JDK 17 + Maven 3.9.9
backend-java/README.md 后端速查
docs/SAE-Java-MVP-操作步骤.md 本文

现有 H5、Node 后端、淘宝主流程页面均未改动;只新增 MVP 页面和两个配置字段。


1. 环境安装

本机已有:

  • Node.js v22.23.2:C:\Program Files\nodejs
  • JDK 17:D:\juzi\tools\jdk17
  • Maven 3.9.9:D:\juzi\tools\maven\apache-maven-3.9.9

PowerShell 默认执行策略是 Restricted,直接运行 .ps1 或 npm.ps1 会被拦。每次新开窗口先执行:

Set-ExecutionPolicy -Scope Process Bypass
. D:\juzi\tools\env-java.ps1

然后确认:

java -version
mvn -version
node -v
npm.cmd -v

预期:

  • java version "17.x"
  • Apache Maven 3.9.9
  • v22.23.2
  • 10.9.x

如果 env-java.ps1 报 “JDK 17 not found”,检查 D:\juzi\tools\jdk17\<jdk目录>\bin\java.exe 是否存在;脚本会自动向下找一层目录。

不要用系统里的 JDK 25 来跑这个 MVP;SAE 运行时选 17,编译也用 17,避免 UnsupportedClassVersionError。


2. 后端本地启动

Set-ExecutionPolicy -Scope Process Bypass
. D:\juzi\tools\env-java.ps1
cd D:\juzi\backend-java
mvn -DskipTests package
java -jar target\taobao-mvp-backend-0.0.2.jar

第一次 mvn package 会下载 Spring Boot 依赖,耐心等几分钟。看到类似日志即成功:

Tomcat started on port 8080 (http)
Started MvpApplication in ...

想跑自动化测试(签名算法 + envelope + health):mvn test。

2.1 另开一个窗口验证

curl.exe http://127.0.0.1:8080/actuator/health
curl.exe -X POST -H "Content-Type: application/json" -d "{}" http://127.0.0.1:8080/api/taobao/ping
Invoke-RestMethod -Method Post -Uri http://127.0.0.1:8080/api/taobao/echo -ContentType 'application/json' -Body '{"hello":"world"}' | ConvertTo-Json -Depth 5

PowerShell 调原生 curl.exe 时,-d 里的双引号可能被吞掉(会看到 {hello:world} 解析失败);发 JSON 建议用 Invoke-RestMethod,或者把 body 写进文件后用 --data-binary "@body.json"。

预期 ping:

{
  "success": true,
  "data": {
    "ok": true,
    "pong": true,
    "server": "java",
    "time": "2026-10-30T...+08:00",
    "transport": "direct",
    "appKey": "",
    "openId": "",
    "env": "",
    "signVerified": false,
    "signMessage": "verify-sign=false, skipped (local/direct mode)"
  }
}

echo 预期能看到 body.hello = "world"。

所有 /api/taobao/** 返回的都是云网关要求的 envelope;/actuator/health 是给 SAE 健康检查用的普通 JSON,不是 envelope。

2.2 不装 IDE 也能跑的前端契约测试

cd D:\juzi
node taobao\scripts\mvp-local-check.cjs

这个脚本用 Node 模拟 my.request,加载真实的 taobao/utils/transport.js,直连 8080,验证 ping/echo/whoami 和 unwrap 解包。预期输出 PASS,其中 ping.server = "java"。如果这里都不过,先别开 IDE。


3. 前端本地联调(淘宝 IDE)

3.1 安装依赖

cd D:\juzi\taobao
npm.cmd ci

如果 npm.cmd 不在 PATH,用全路径:

& "C:\Program Files\nodejs\npm.cmd" ci

@tbmp/mp-cloud-sdk 已经是 1.5.10,与当前 npm 最新版一致。

3.2 IDE 导入与启动页

  1. 打开淘宝小程序开发者工具,导入 D:\juzi\taobao。
  2. 填入真实小程序 AppID(mini.project.json 里的 appid 也可以留空,以 IDE 设置为准)。
  3. 工具 → 构建 npm(把 node_modules 构建成小程序可用的包)。
  4. 本地 mvpLocal: true 时,启动页右上角会出现「SAE MVP 连通性」入口,点它即可进入;也可以把启动页临时设为 pages/mvp/mvp。
  5. 用桌面模拟器跑;手机上的 127.0.0.1 指向手机自己,连不到你电脑。

3.3 当前配置

taobao/config.js 新增了:

mvpLocal: true,
mvpBaseUrl: 'http://127.0.0.1:8080',

pages/mvp/mvp.js 在 onLoad 时如果 mvpLocal === true,会临时把 transport 改成 direct、baseUrl 改成 mvpBaseUrl,离开页面时恢复。这样不会破坏主应用原来指向 18180 的 Node 后端配置。

进入页面后会自动调用一次 /api/taobao/ping,也可以点三个按钮:

  • POST /api/taobao/ping
  • POST /api/taobao/whoami
  • POST /api/taobao/echo

预期页面显示 server: "java"、pong: true。

如果 IDE 拦截 localhost 请求,打开 IDE 的“不校验合法域名”/“开发环境不校验请求域名”开关(不同版本叫法不同)。桌面模拟器一般可以直接访问回环地址。

3.4 这一步验证了什么

  • 小程序的 utils/transport.js 能走 direct 分支;
  • my.request 能发 POST application/json;
  • transport.unwrap 能正确解包 {success,data};
  • Java 后端端口、路径、返回结构都对。

4. 云端链路(SAE + 聚石塔云应用)

4.1 先理解三层关系

淘宝小程序
  └─ @tbmp/mp-cloud-sdk
       └─ 淘宝云网关(校验 appkey/sign,注入 open_id/access_token)
            └─ 聚石塔云应用(应用/环境/流量接入)
                 └─ SAE(真正的 Java 容器,跑 JAR)
  • SAE 只是算力层,不是“建一个公网 URL 就能被小程序调用”。
  • 小程序要调通,SAE 应用必须挂在聚石塔云应用下,或者走空应用(不入塔)+ 域名白名单。
  • 2026-05-11 公告:原聚石塔“应用创建链路”2026-06-20 下线,部署运维迁到 ACK/SAE;聚石塔保留云应用管理、环境管理、流量接入。
  • 参考:迁移通知、新链路快速创建云应用、云服务产品概述。

4.2 构建 JAR

Set-ExecutionPolicy -Scope Process Bypass
. D:\juzi\tools\env-java.ps1
cd D:\juzi\backend-java
mvn -DskipTests clean package

产物:

D:\juzi\backend-java\target\taobao-mvp-backend-0.0.2.jar

4.3 SAE 创建应用

在 SAE 控制台“创建应用 → 代码包部署 → 设置代码包部署”里按下面选:

配置项 选择
技术栈语言 Java
代码包类型 JAR 包部署
应用运行环境 标准 Java 应用运行环境
Java 环境 Open JDK 17
文件上传方式 上传 JAR 包
启动命令 默认 java -jar
应用端口 8080
健康检查 HTTP GET /actuator/health,期望 200
实例数 2(至少 2,避免单点)
时区 Asia/Shanghai
地域/命名空间/VPC 用聚石塔创建云应用时分配的那套,不要自己新建默认命名空间

不要选:

  • WAR 包部署
  • apache-tomcat-*
  • EDAS-Container-*
  • Open JDK 25

原因:WAR/Tomcat 是给外置 Tomcat 的老项目;EDAS-Container 是 HSF/Pandora Boot 专用;Open JDK 25 与 Spring Boot 3.5 的兼容性没有 17 稳。

环境变量(SAE → 应用设置 → 环境变量):

TAOBAO_APP_KEY=你的AppKey
TAOBAO_APP_SECRET=你的AppSecret
TAOBAO_VERIFY_SIGN=true

TAOBAO_APP_SECRET 只能放服务端,绝不能进小程序代码或 config.js。

建议 JVM 参数(按实例规格调整,堆小于容器内存):

-Xms512m -Xmx1024m -Duser.timezone=Asia/Shanghai

4.3.1 更新代码包(重新上传 JAR)

应用创建之后,更新 JAR 的入口:

  1. SAE 应用 nnn → 右上角「部署应用」/「变更」→「代码包部署」→ 上传新 JAR → 确定 → 部署。
  2. 如果右上角没有,左侧「变更记录」→「创建变更」→ 代码包部署。
  3. 聚石塔资源视图偶尔不显示部署按钮,可直接用完整 SAE 控制台:
https://saenext.console.aliyun.com/cn-zhangjiakou/app-list/micro

选 my-namespace → nnn → 部署应用。

每次上传的 JAR 文件名/版本要不同,SAE 才会当成一个新版本。pom.xml 的 <version> 已改成 0.0.2,产物是:

taobao-mvp-backend-0.0.2.jar

SAE 部署页的「版本」可以填 0.0.2 或 20261101-2。不要重复上传同名同版本的包。

4.4 流量接入

  • 云应用走内网私网 SLB:聚石塔“流量接入”里绑定私网 SLB,后端端口 8080。
  • 不要给云应用开公网入口;公网只用于你自己调试。
  • 如果后端要调 TOP/奇门/外部 API,给 SAE 配 NAT 网关或 EIP,否则容器只入不出,调用会超时。
  • 数据库在 RDS 时,把 SAE 的网段/安全组加进 RDS 白名单。

4.5 聚石塔/开放平台关联

  1. 聚石塔控制台 → 云应用 → 新建云应用(按 2026-05 新链路向导)。
  2. 部署方式选 SAE;创建测试环境、正式环境。
  3. 在 SAE 里把 JAR 部署到对应应用/环境。
  4. 聚石塔 → 流量接入 → 绑定私网 SLB(测试/正式各一套,或共用一个正式 SLB)。
  5. 开放平台控制台 → 云托管 → 关联云应用 → 选择你的云应用和对应 SLB。
  6. 在“服务测试”里调用 POST /api/taobao/ping,确认返回 success: true。
  7. 在 taobao/config.js 里把 mvpLocal 改成 false,并配置:
transport: 'cloud',
baseUrl: 'https://你的HTTPS域名',
cloudAppId: '控制台拿到的 cloudAppId',
cloudEnv: 'test', // 先 test,验收后改 online
  1. 进入 pages/mvp/mvp,点 ping,看到 transport: "gateway"、signVerified: true 即通。

账号必须一致:创建云应用的聚石塔账号,要和开放平台小程序账号一致;子账号看不到云应用。小程序上线后默认云应用不能再改,选择时确认好。

4.6 空应用(不入塔)作为备选

如果这个 SAE 应用不在聚石塔,不能直接“关联云应用”。只能走空应用:

  1. 开放平台 → 云托管 → 云应用管理 → 新建空应用。
  2. 关联一个没有敏感数据权限的 AppKey。
  3. 设置域名白名单,提交审批(HTTPS、已备案域名)。
  4. 调用时 exts.domain 传你的域名;现有 transport.js 已经会传 domain: config.baseUrl。

注意:现有 transport.js 的 cloud 分支还要求 config.cloudAppId 非空。如果空应用控制台没有给 cloudAppId,需要先把这行校验放宽(或暂时先用聚石塔云应用)。

空应用只适合内容/工具/轻服务;电商交易、用户敏感数据类大概率不适合,还是得入塔。


5. 云网关接口契约(Java 后端必须遵守)

现有 Node 实现已经按这个契约写了,Java 迁移时照抄:

{
  "success": true,
  "data": {},
  "errorCode": "xxxx",
  "errorMessage": "xxxx"
}
  • 只支持 GET/POST;POST 必须 application/json。
  • 请求体 ≤128KB;超时默认 3s、最大 10s。
  • 平台会往 URL 追加 app_key、open_id、access_token、sign、env、mini_app_id 等系统参数;自定义参数不要重名。
  • 成功时小程序 SDK 只把 data 返回给页面;errorCode/errorMessage 在失败时返回。
  • 发布前把 cloudEnv 从 test 改成 online;默认云应用上线后不能改。
  • 图片/长任务不要塞进一个请求:现有实现是 64KiB 分片上传 + 异步任务 + 轮询。

参考:云应用调用。


6. 签名校验

Java 的 TaobaoSignatureVerifier 与现有 h5/lib/taobao-auth.js 算法一致:

  1. 取全部 query 参数,排除 sign 和空值,按 key 升序,拼成 key1value1key2value2...。
  2. 末尾追加原始 JSON body(不要重新序列化)。
  3. sign_method=md5:MD5(secret + content + secret);sign_method 为空:MD5(content + secret);hmac* 用 HMAC。
  4. 结果转大写十六进制,与 sign 比较。

本地 TAOBAO_VERIFY_SIGN=false,没有 app_key/sign,直接放行,返回 signVerified:false。

云端 TAOBAO_VERIFY_SIGN=true:

  • app_key 必须等于 TAOBAO_APP_KEY;
  • open_id 必须符合 [A-Za-z0-9_-]{4,256};
  • sign 必须是 32–64 位十六进制;
  • 重复 query 参数直接拒绝;
  • 校验失败返回 success:false, errorCode:"SIGN_INVALID"。

如果云端一直 SIGN_INVALID,按顺序查:

  1. SAE 环境变量是否真的注入(重启后生效)。
  2. TAOBAO_APP_KEY 是否和云应用/小程序一致。
  3. 网关用的 sign_method 与后端是否匹配。
  4. body 是否被反向代理/框架重新序列化(必须保留原始字节)。
  5. 是否有重复的 open_id/app_key 参数。

7. 常见问题

现象 排查
UnsupportedClassVersionError 编译 JDK 高于 SAE 运行时;统一用 17
404 路径不对;云应用 path 是否带 /api/taobao;WAR 的 context path
502/504 SAE 端口不是 8080、健康检查失败、SLB 后端端口不对
success:false + SIGN_INVALID 见第 6 节
cloud init failed IDE 未登录、AppID/cloudAppId 不匹配、cloudEnv 不对
请先配置淘宝云应用和 HTTPS 服务地址 transport:'cloud' 但 baseUrl 不是 HTTPS 或 cloudAppId 为空
直连接口仅用于本机联调 transport:'direct' 但 baseUrl 不是 localhost/127.0.0.1
Cannot find module '@tbmp/mp-cloud-sdk' npm.cmd ci 后,在 IDE 里执行“构建 npm”
手机真机请求失败 127.0.0.1 是手机自己;真机必须走云端 HTTPS
请求超过 10 秒 云网关最大 10s;改异步任务 + 轮询
返回体超过 128KB 分页/裁剪字段,不要把大图 base64 放进响应

7.1 淘宝 IDE 报 install miniapp extension fail: ... wmic ...

Windows 11 24H2 起默认移除了 wmic.exe,而淘宝开发者工具在安装小程序扩展时会执行:

wmic path win32_VideoController get caption

找不到 wmic 就报这个错。本机已经放了一个兼容 shim:

C:\Users\youmi\.local\bin\wmic.cmd

修复步骤:

  1. 完全退出淘宝开发者工具(任务管理器里不要留 淘宝开发者工具.exe)。
  2. 重新打开 IDE,再导入 D:\juzi\taobao。

如果 shim 丢了,重新运行:

powershell -ExecutionPolicy Bypass -File D:\juzi\tools\fix-taobao-ide-wmic.ps1

永久方案(需要管理员 PowerShell):

DISM /Online /Add-Capability /CapabilityName:WMIC~~~~

装完后 C:\Windows\System32\wmic.exe 会优先于 shim,shim 可以删除。如果 DISM 提示找不到这个能力,说明系统镜像没带 WMIC FoD,继续用 shim 即可。


8. 下一步(MVP 通过后)

  1. 把 h5/lib/taobao-routes.js 的接口逐个迁到 Java:
    • POST /api/taobao/challenge
    • POST /api/taobao/session
    • POST /api/taobao/me
    • POST /api/taobao/photo(64KiB 分片)
    • POST /api/taobao/skin-analyze(异步任务)
    • POST /api/taobao/analysis(轮询)
    • POST /api/taobao/reports
    • POST /api/taobao/logout
  2. 所有 /api/taobao/** 统一走签名校验 + envelope。
  3. 账号/历史/图片存到 RDS/OSS,不要放容器本地磁盘。
  4. 保留 H5 的 Node 路由不变,淘宝走 Java;两边共用同一套业务规则时,先以现有 Node 实现为契约。
  5. 接 SLS 日志、Actuator 健康检查、告警,再切正式流量。

9. 命令速查

# 每个新窗口
Set-ExecutionPolicy -Scope Process Bypass
. D:\juzi\tools\env-java.ps1

# 后端
cd D:\juzi\backend-java
mvn -DskipTests clean package
java -jar target\taobao-mvp-backend-0.0.2.jar

# 本地验证
curl.exe http://127.0.0.1:8080/actuator/health
curl.exe -X POST -H "Content-Type: application/json" -d "{}" http://127.0.0.1:8080/api/taobao/ping

# 前端依赖
cd D:\juzi\taobao
npm.cmd ci