6.8 KiB
后端中文提示与 UTF-8 响应实施计划
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 所有 API 对外提示使用中文,并以 UTF-8 JSON 返回,避免 Swagger 和前端出现乱码。
Architecture: 通过 ApiResponse 统一成功提示,通过 Spring Security 的异常写入器统一鉴权提示,通过业务服务中文化可回传的校验信息。应用配置与响应写入器共同确保 UTF-8;错误码保持不变。
Tech Stack: Java 8、Spring Boot 2.7、Spring Security、Springdoc OpenAPI、JUnit 5、MockMvc。
Global Constraints
- 保持现有
ErrorCode枚举值不变。 - 所有面向前端的
message必须为中文。 - JSON 响应必须使用 UTF-8。
- 保留业务校验的具体中文原因;框架参数校验使用统一中文提示。
Task 1: 统一响应和安全异常提示
Files:
- Modify:
src/main/java/com/yau/digitalrmb/shared/api/ApiResponse.java - Modify:
src/main/java/com/yau/digitalrmb/security/config/SecurityConfig.java - Modify:
src/main/resources/application.yml - Test:
src/test/java/com/yau/digitalrmb/security/SecurityConfigTest.java
Interfaces:
-
Produces: 成功响应的
message为“操作成功”;401、403 响应分别为“未登录或登录已失效”“无访问权限”。 -
Produces: 安全异常响应头为
application/json;charset=UTF-8。 -
Step 1: 写失败测试
mockMvc.perform(get("/api/v1/commercial-banks/issuance/inventory"))
.andExpect(status().isUnauthorized())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().encoding(StandardCharsets.UTF_8))
.andExpect(jsonPath("$.message").value("未登录或登录已失效"));
- Step 2: 运行失败测试
Run: mvn -B -Dtest=SecurityConfigTest test
Expected: FAIL,当前消息为 UNAUTHORIZED 或响应编码不是 UTF-8。
- Step 3: 最小实现
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.getWriter().write(... "未登录或登录已失效" ...);
并将 ApiResponse.success 的消息改为“操作成功”,在 application.yml 添加:
server:
servlet:
encoding:
charset: UTF-8
enabled: true
force: true
- Step 4: 运行测试验证通过
Run: mvn -B -Dtest=SecurityConfigTest test
Expected: PASS。
- Step 5: 提交
git add src/main/java/com/yau/digitalrmb/shared/api/ApiResponse.java src/main/java/com/yau/digitalrmb/security/config/SecurityConfig.java src/main/resources/application.yml src/test/java/com/yau/digitalrmb/security/SecurityConfigTest.java
git commit -m "fix: return Chinese security messages in UTF-8"
Task 2: 中文化发行模块对外业务提示
Files:
- Modify:
src/main/java/com/yau/digitalrmb/issuance/application/service/DenominationPlanService.java - Modify:
src/main/java/com/yau/digitalrmb/issuance/application/service/CommercialBankIssuanceApplicationService.java - Modify:
src/main/java/com/yau/digitalrmb/issuance/application/service/CentralBankIssuanceQueryService.java - Modify:
src/main/java/com/yau/digitalrmb/issuance/interfaces/rest/CommercialBankIssuanceController.java - Modify:
src/main/java/com/yau/digitalrmb/security/interfaces/AuthController.java - Test:
src/test/java/com/yau/digitalrmb/issuance/interfaces/rest/IssuanceControllerTest.java
Interfaces:
-
Produces: 面额总额不一致时
VALIDATION_ERROR消息为“各面额小计之和必须等于申请总金额”。 -
Produces: 当前用户审计声明缺失或非法时返回中文未授权提示。
-
Step 1: 写失败测试
mockMvc.perform(post("/api/v1/commercial-banks/issuance/denomination-plan/validate")
.with(issuanceJwt()).contentType(MediaType.APPLICATION_JSON)
.content(invalidPlanJson))
.andExpect(jsonPath("$.code").value("VALIDATION_ERROR"))
.andExpect(jsonPath("$.message").value("各面额小计之和必须等于申请总金额"));
- Step 2: 运行失败测试
Run: mvn -B -Dtest=IssuanceControllerTest test
Expected: FAIL,当前消息为 denomination total must equal totalAmount。
- Step 3: 最小实现
将所有会经 BusinessException 或校验转换返回前端的英文文本替换为对应中文,包括申请不存在、申请 ID 为空、库存配置不存在、JWT 缺失 userId 或 preferred_username、金额和面额规则。
- Step 4: 运行测试验证通过
Run: mvn -B -Dtest=IssuanceControllerTest test
Expected: PASS。
- Step 5: 提交
git add src/main/java/com/yau/digitalrmb/issuance src/main/java/com/yau/digitalrmb/security/interfaces/AuthController.java src/test/java/com/yau/digitalrmb/issuance/interfaces/rest/IssuanceControllerTest.java
git commit -m "fix: translate issuance API messages to Chinese"
Task 3: 统一全局校验和验证
Files:
- Modify:
src/main/java/com/yau/digitalrmb/shared/web/GlobalExceptionHandler.java - Modify:
src/main/java/com/yau/digitalrmb/platformintegration/application/PlatformTokenVerifier.java - Test:
src/test/java/com/yau/digitalrmb/shared/GlobalExceptionHandlerTest.java
Interfaces:
-
Produces: 框架参数校验统一返回“请求参数校验失败”。
-
Produces: 无效平台令牌返回“平台登录凭据无效”。
-
Step 1: 写失败测试
mockMvc.perform(post("/api/v1/auth/login").contentType(MediaType.APPLICATION_JSON).content("{}"))
.andExpect(jsonPath("$.code").value("VALIDATION_ERROR"))
.andExpect(jsonPath("$.message").value("请求参数校验失败"));
- Step 2: 运行失败测试
Run: mvn -B -Dtest=GlobalExceptionHandlerTest test
Expected: FAIL,当前返回框架英文校验文本。
- Step 3: 最小实现
return ApiResponse.failure(ErrorCode.VALIDATION_ERROR, "请求参数校验失败", traceId());
并把平台令牌异常内部消息改为中文,避免任何异常链的英文文本进入 API 响应。
- Step 4: 执行完整验证
Run: mvn -B test
Expected: 全部测试通过;新增中文/UTF-8 断言通过。
- Step 5: 重启与人工验证
Run: mvn -B package -DskipTests,重启本地 8081 后端;在 Swagger 调用面额校验接口,确认响应体中文且响应头为 UTF-8。
- Step 6: 提交
git add src/main/java/com/yau/digitalrmb/shared/web/GlobalExceptionHandler.java src/main/java/com/yau/digitalrmb/platformintegration/application/PlatformTokenVerifier.java src/test/java/com/yau/digitalrmb/shared/GlobalExceptionHandlerTest.java
git commit -m "fix: standardize Chinese validation messages"