比较两个JSON

时间:2011-08-20 01:07:22

标签: java json gson

比较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);

有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

如果你只想比较简单的平等,Jackson会让事情变得简单;以防这可能有助于它:

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

现在;因为所有JsonNode对象都正确地实现了相等性检查(因此键的排序无关紧要等),您可以使用它来进行递归式扩散,以查看内容的不同之处和方式。对于ObjectNode,您可以获取密钥名称,删除相同的名称(tree1.getFieldNames()。removeAll(tree2.getFieldNames())等等。

答案 1 :(得分:2)

这很棘手,但可以做到。

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

然后将 Map A 中的所有元素作为一对(setA)中的对,将 Map B 中的所有元素放在另一个集合中{{1} })

然后计算

setB

Set<Pair> setA_B = setA.removeAll(setB); Set<Pair> setB_A = setB.removeAll(setA); Set<Pair> result = setA_B.addAll(setB_A); 中,只有不匹配的元素。如果所有元素都匹配(两个原始地图都相等),则result为空。

答案 2 :(得分:2)

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

    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());
    }