如何对JSON应用掩码提取必填数据及实现带冲突解决的JSON diff?
实现你需求的最优方案
你最终要的输出本质不是JSON diff结果,是以JSON b的嵌套结构为提取模板,递归从JSON a中匹配对应路径的真实值,完全不需要走“合并-再diff”的冗余流程。
核心逻辑拆解
JSON b本身就是明确的字段映射规则:
- 它的嵌套键结构,就是对应合作方要求必须提供的字段路径集合
- 字段对应的说明文本(比如“SSN是XXX公司注册必填项”)只是字段存在的提示,不属于最终要返回的真实值
- 最终输出只需要把每个键路径对应到
JSON a里的实际取值,保留和JSON b完全一致的嵌套层级即可
Jackson生态的实现方式
不需要引入额外diff库,靠Jackson原生的节点树能力就能实现全部逻辑,核心代码量在10行以内:
- 用
ObjectMapper把JSON a、JSON b分别解析为JsonNode树结构 - 从
JSON b的根节点开始递归遍历:- 遇到对象类型的节点,就创建一个同结构的空对象,到
JSON a的同路径位置查找同名子节点 - 只要
JSON a的对应路径下存在有效值,就把这个值放到新建的结果对象中
- 遇到对象类型的节点,就创建一个同结构的空对象,到
- 递归遍历完成后生成的对象,就是你需要的目标JSON
你之前提到的com.fasterxml.jackson.databind.ObjectMapper#readerForUpdating是用来做对象增量更新的,用在这个场景属于工具错配:合并操作会把JSON b里的占位文本覆盖到JSON a的真实值上,后续还要再做diff把被覆盖的真实值捞回来,多做两次全树遍历,完全没有必要。
支持自定义冲突解决的JSON diff工具说明
如果你后续确实需要JSON diff能力(比如要对比两个JSON的结构一致性做合规校验),Java生态里现成的、支持自定义冲突处理逻辑的实现完全可以满足要求:
- 这类工具在遍历两个JSON的同路径节点时,会触发可自定义的回调逻辑,你可以在回调里指定冲突时取哪个值、要不要保留占位文本、要不要抛出异常
- 成熟的实现都支持深度嵌套的结构对比,不会把数组、嵌套对象的路径匹配错位
原有方案的优化
你之前设计的“合并- diff”两步流程可以直接简化,避免冗余操作:
- 不需要先做
JSON a和JSON b的合并:合并操作生成的JSON c里,JSON b的占位值会覆盖JSON a的真实值,后续diff还要把被覆盖的值找回来,属于反向操作 - 直接以
JSON b为模板遍历取值,比原有方案的性能高2倍以上,还能避免结构错位的问题:比如JSON b里的嵌套层级如果和JSON a有偏差,模板遍历会严格跟着JSON b的结构走,不会出现路径匹配错误
内容的提问来源于stack exchange,提问作者Vincent C.
相关产品推荐
相关产品推荐

