【问题标题】:Comparing two JSONs比较两个 JSON
【发布时间】:2011-08-20 01:07:21
【问题描述】:

在 Java 中比较两个 JSON 字符串的最佳方法是什么?我希望能够只打印出键/值对的差异。

我正在使用 gson 库将其转换为地图并进行断言,但它同时显示了两个 JSON:

Type type = new TypeToken<Map<String, String>>() {}.getType();
Gson gson = new Gson();
Map<String, String> mapExpected = gson.fromJson(expectedJson, type);
Map<String, String> mapResponse = gson.fromJson(jsonResponse, type);
Assert.assertEquals(mapExpected, mapResponse);

有没有更好的方法来做到这一点?

【问题讨论】:

  • 计算[设置差异][1]。 [1]:stackoverflow.com/questions/1723168/…
  • @mcandre,你的链接是关于 JS 的,他用 java 提问
  • 这个概念仍然适用。将 JSON 数据转换为集合,然后显示差异 (-)。
  • 我同意这个基本想法。恕我直言,该帖子仍然不适用,因为 JSON 结构是地图而不是集合,需要中间通道来进行转换。

标签: java json gson


【解决方案1】:

如果你只是想比较简单的相等,Jackson 会很容易;以防万一这可能会有所帮助:

JsonNode tree1 = objectMapper.readTree(json1);
JsonNode tree2 = objectMapper.readTree(json2);
if (!tree1.equals(tree2)) { // handle diffing
}

现在;由于所有 JsonNode 对象都正确实现了相等性检查(因此键的顺序无关紧要等),您可以使用它进行递归差异以查看内容的不同之处和方式。对于ObjectNodes,您可以获得键名,删除相同的 (tree1.getFieldNames().removeAll(tree2.getFieldNames()) 等等。

【讨论】:

    【解决方案2】:

    这很棘手,但可以做到。

    我将实现一个包含 String(键和值)的 Pair 类,以及对应的 equals() 和 hashcode();

    然后将 Map A 中的所有元素作为 Pair 放入一个 Set (setA),并将 Map B 中的所有元素放入另一个 Set (setB)

    然后计算

     Set<Pair> setA_B = setA.removeAll(setB);
     Set<Pair> setB_A = setB.removeAll(setA);
     Set<Pair> result = setA_B.addAll(setB_A);
    

    result 中只有不匹配的元素。如果所有元素都匹配(两个原始映射相同),则 result 为空。

    【讨论】:

    • 感谢 SJuan76 的指点。它有效,我使用了 AbstractMap 的 SimpleEntry for Pair。
    【解决方案3】:

    使用 SJuan76 的解决方案,我能够得到键值对的差异。

        Type type = new TypeToken<Map<String, String>>() {}.getType();
        Gson gson = new Gson();
        Map<String, String> mapExpected = gson.fromJson(expectedJson, type);
        Map<String, String> mapResponse = gson.fromJson(jsonResponse, type);
        Set<SimpleEntry<String,String>> expectedSet = new HashSet<SimpleEntry<String, String>>();
        Set<SimpleEntry<String, String>> tmpExpectedSet = new HashSet<SimpleEntry<String, String>>();
        Set<SimpleEntry<String, String>> responseSet = new HashSet<SimpleEntry<String, String>>();
    
        for (String key : mapExpected.keySet()) {
            expectedSet.add(new SimpleEntry<String, String>(key, mapExpected.get(key)));
            tmpExpectedSet.add(new SimpleEntry<String, String>(key, mapExpected.get(key)));
        }
    
        for (String key : mapResponse.keySet())
            responseSet.add((new SimpleEntry<String, String>(key, mapResponse.get(key))));
    
        expectedSet.removeAll(responseSet);
        responseSet.removeAll(tmpExpectedSet);
        expectedSet.addAll(responseSet);
    
        if (!expectedSet.isEmpty()) {
            for (SimpleEntry<String, String> diff : expectedSet)
                log.error(diff.getKey() + ":" + diff.getValue());
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-26
      • 2020-07-22
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多