【问题标题】:Getting a diff of two JSON strings using Java code使用 Java 代码获取两个 JSON 字符串的差异
【发布时间】:2010-07-09 15:29:47
【问题描述】:

谁能推荐一些 Java 库或代码来获得两个 JSON 字符串的差异?

【问题讨论】:

  • 你想从这个比较中得到什么?仅将字符串与 String.equals 进行比较有什么问题?
  • 比较是什么意思?如果它们只是字符串,那么 JSON 与它有什么关系?
  • 根据贾斯汀回答的评论,他实际上想要一个差异,而不是在平等上比较它们。

标签: java json


【解决方案1】:

我遇到了完全相同的问题,最终编写了自己的库:

https://github.com/algesten/jsondiff

它同时进行差异化/修补。

Diff 本身就是 JSON 对象,具有用于对象合并/替换和数组插入/替换的简单语法。

例子:

original
{
   a: { b: 42 }
}

patch
{
  "~a" { c: 43 }
}

~ 表示对象合并。

result
{
   a: { b: 42, c: 43 }
}

【讨论】:

  • 谢谢马丁,这正是我所需要的
【解决方案2】:

对于一个具体的建议,您可以使用Jackson,将 JSON 字符串绑定到 JSON 树中,然后比较它们是否相等。比如:

ObjectMapper mapper = new ObjectMapper();
JsonNode tree1 = mapper.readTree(jsonString1);
JsonNode tree2 = mapper.readTree(jsonString2);
if (tree1.equals(tree2)) { 
  // yes, contents are equal -- note, ordering of arrays matters, objects not
} else { 
  // not equal
}

相等性比较是按值进行的,并且应该对 JSON 数组、对象和原始值按预期工作。

【讨论】:

  • 但这只是告诉你 JSON 是否不同;如果它们碰巧不同,它不会提示这些差异是什么(差异/补丁)。
  • 没错,尽管您可以递归地下降并查看它们的不同之处,Merkle-tree 样式。
  • @gaurav 示例给出的工作方式在 2.9 中解释。你问的是这个吗?
  • 虽然我还没有尝试过,但我怀疑如果其中一个 json 在发束之间进行等于时具有不同的顺序是否正确。
【解决方案3】:

就个人而言,我建议将 JSON 字符串反序列化回对象并比较对象。

这样您就不必担心两个 JSON 字符串之间的额外空格/格式(两个字符串的格式可能大相径庭,但仍然代表相同的对象)。

【讨论】:

  • 是的,这很重要,如果 2 个 JSON 字符串包含相同的数据但属性顺序不同(例如),它们是否应该被视为相等?
  • 我只是好奇他是否可以规范化 json 字符串然后比较两个字符串?
  • 相比之下,我的意思是 - 识别值不同的键。基本上需要识别所有具有不同值的键。示例:字符串 1:{"format":"example","content":"test", "no_diff":"no_diff"} 字符串 2:{"format":"example1","content":"test1", "no_diff":"no_diff"} 在比较时,它应该返回 - 格式和内容键及其值。
【解决方案4】:

上面的答案只检查 Json 是否相等。如果你想比较一下 javers 库。 使用 Jackson 将 json 转换为 java 对象,然后使用 javers 比较值对象来获取差异。 这是示例代码。(假设p1,p2是两个java对象)

Javers j = JaversBuilder.javers().build();
        Diff diff = j.compare(p1, p2);
        if (diff.hasChanges()) {
            List<Change> changes = diff.getChanges();
            for (Change change : changes) {
                if (change instanceof ValueChange) {
                    ValueChange valChange = (ValueChange) change;
System.out.println(valChange.getPropertyName() + " -- " + valChange.getLeft() + "--"+valchange.getRight());
}
 }

这将为您提供关键值与预期值和实际值的差异。

【讨论】:

    【解决方案5】:

    接受的答案很好,工作也很棒。

    不过,对于维护性更强的库,我建议使用 https://github.com/java-json-tools/json-patch,我只是用它来解决 JSON 屏蔽问题(如果您好奇,请参阅 Apply a mask on a JSON to keep only mandatory data)。

    注意:在json-patch 库中使用您自己的ObjectMapper 使其更加实用,因为它避免了使用您自定义的ObjectMapper 进行读取和重写,以便根据您的特定标准获得有效的JSON。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-26
      • 2012-01-15
      • 1970-01-01
      相关资源
      最近更新 更多