NOTE移动端工程

业务哨兵值不是空值:修复过度规范化导致的流程阻塞

本文结论

一个合法业务哨兵值被客户端转为空串后,同时破坏展示、必填校验和请求传递;最小修复是只规范化真正的空值。

一个手持终端拣货流程从后端收到了目标字段,但当该字段使用约定的星号哨兵值时,页面不显示目标,暂存和确认按钮也无法通过必填校验。

普通目标值一直正常,因此最初看起来像是接口偶发缺字段。沿着响应、页面状态和提交参数逐层检查后,问题被定位到客户端的一段“规范化”逻辑。

证据

后端响应中存在字面星号,数据模型也允许字符串原样保存。客户端在把字段写入页面状态前,却主动将星号转换成空串。

这个转换影响的不只是显示文本。同一个规范化结果还被用于:

  • 商品卡片和确认弹窗回填;
  • 目标字段的必填判断;
  • 暂存及确认请求的目标参数。

因此一个看似只为界面清理而写的条件,同时切断了展示、校验和提交三条链路。

根因

星号在该业务契约中不是“未知”或“缺失”,而是一个有效的特殊目标值。客户端把通用的空值观念套到了领域哨兵值上,导致合法数据在进入业务状态前丢失。

这也是问题只出现在特殊值上的原因:普通字符串不会命中错误分支,真正的 null 和空串则本来就应该保持为空。

最小修复

修复只改变规范化边界:

  • null 和空字符串继续按空值处理;
  • 契约定义的星号及普通字符串保持原样。

现有页面和请求链路无需重写。值被保留下来后,卡片与弹窗可以显示它,必填校验可以识别它,请求也会按原值传递。

修改没有放宽序列号、打包区域或其他流程校验,也没有改变后端接口和请求模型。相同问题存在于一份独立维护的客户端副本中,因此使用同样的最小变更同步处理。

验证

主项目的修改完成本地提交并通过 Android Java 编译。独立副本通过差异检查,确认只有目标规范化条件发生变化,并使用其兼容 JDK 完成编译。

回归边界包括三类输入:

  • 星号能够显示并原样进入请求;
  • 普通目标值行为不变;
  • null 和空串仍然无法绕过必填校验。

这些检查证明修复保留的是一个明确的合法值,而不是取消输入约束。

经验与限制

数据规范化必须服从领域契约。去空格、统一大小写或替换特殊字符看似无害,但只要结果同时参与展示、校验和提交,任何信息损失都会被放大。

哨兵值只有在接口契约明确规定时才应保留。不能因为某个星号是合法值,就把所有特殊字符都视为有效输入。更稳妥的做法是集中定义允许的领域值,并为普通值、哨兵值和真正空值分别建立回归测试。

遇到类似系统问题?

先说明系统,再说明症状

如果需要生产排障、DevOps 交付或物流系统集成协作,请提供当前表现、预期结果、受影响环境、可用日志或数据样例,以及发布限制。我会从现有证据开始判断。

通过邮件开始