比较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);
有更好的方法吗?
答案 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());
}