2011-08-20 145 views
2

在Java中比較兩個JSON字符串的最佳方式是什麼?我想只能打印出鍵/值對中的差異。比較兩個JSON

我使用GSON庫將其轉換爲一個地圖,做斷言,但它同時顯示JSONs:

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

計算[差集] [1]。 [1] :http://stackoverflow.com/questions/1723168/what-is-the-fastest-or-most-elegant-way-to-compute-a-set-difference-using-javascr/1723220#1723220 – mcandre

+0

@mcandre,你的鏈接是關於JS,他在java中請求 – SJuan76

+0

這個概念仍然適用。將JSON數據轉換爲集合,然後顯示差異('-')。 – mcandre

回答

2

這是棘手的,但它可以做到。我會實現一個Pair類,該類既包含String(key和value),也包含它的equals()和hashcode();

然後把從所有元素映像A如對在一個組(setA)和從地圖B在另一組(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爲空。

+0

感謝SJuan76,作爲指針。作品,我使用了AbstractMap的SimpleEntry for Pair。 – ypa

2

使用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()); 
    } 
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())等。