在Java中比较2个JSON文件的最佳方法

时间:2011-06-29 20:34:41

标签: java json comparison

您如何建议接近此任务?

我认为挑战在于智能地呈现差异信息。在我重新发明轮子之前,是否有一种可接受的方法来处理这种比较?

10 个答案:

答案 0 :(得分:14)

我推荐zjsonpatch库,它根据RFC 6902(JSON Patch)显示diff信息。你可以和Jackson一起使用:

JsonNode beforeNode = jacksonObjectMapper.readTree(beforeJsonString);
JsonNode afterNode = jacksonObjectMapper.readTree(afterJsonString);
JsonNode patch = JsonDiff.asJson(beforeNode, afterNode);
String diffs = patch.toString();

这个库优于fge-json-patch(在另一个答案中提到),因为它可以检测从数组中插入/删除的项目。 Fge-json-patch无法处理(如果一个项目被插入到数组的中间,它会认为该项目和之后的每个项目都被更改,因为它们都被移动了一个)。

答案 1 :(得分:8)

这只涉及平等,而不是差异。


杰克逊。

ObjectMapper mapper = new ObjectMapper();

JsonNode tree1 = mapper.readTree(jsonInput1);
JsonNode tree2 = mapper.readTree(jsonInput2);

boolean areTheyEqual = tree1.equals(tree2);

来自the JavaDoc for JsonNode.equals

  

节点对象的等同性定义为完全(深)值相等。这意味着可以通过比较根节点的相等性来比较完整的JSON树是否相等。

答案 2 :(得分:8)

我已经使用JSONAssert做了很好的经验。

import org.junit.Test;
import org.apache.commons.io.FileUtils;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;

... 
@Test
public void myTest() {
  String expectedJson = FileUtils.readFileToString("/expectedFile");
  String actualJson = FileUtils.readFileToString("/actualFile");
  JSONAssert.assertEquals(expectedJson, actualJson, JSONCompareMode.STRICT);
}
... 

答案 3 :(得分:4)

我遇到了类似的问题,最后编写了我自己的库:

https://github.com/algesten/jsondiff

它同时进行差异/修补。

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

示例:

original
{
   a: { b: 42 }
}

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

~表示对象合并。

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

答案 4 :(得分:3)

比较json字符串的最简单方法是使用JSONAssert库中的JSONCompare。优点是,它不仅限于结构,如果您愿意,可以比较值:

JSONCompareResult result = 
     JSONCompare.compareJSON(json1, json2, JSONCompareMode.STRICT);
System.out.println(result.toString());

将输出如下内容:

Expected: VALUE1
     got: VALUE2
 ; field1.field2

答案 5 :(得分:2)

您可以尝试XStream's architecture, handling of JSON mappings

另外,请看一下这篇文章:Comparing two XML files & generating a third with XMLDiff in C#。它在C#中,但逻辑是相同的。

答案 6 :(得分:1)

JSON-LIB

我要做的是使用json-lib解析json数据。这将生成常规的java对象,您可以使用equals方法进行比较。这只有效,但假设来自json-lib的人正确实现了equals方法,但你可以轻松测试。

答案 7 :(得分:0)

锶。这是我的java代码解决方案,通过我的应用程序;

try {           
                // Getting The Array "Courses" from json1 & json2   
                Courses1 =json1.getJSONArray(TAG_COURSES1);
                Courses2 = json2.getJSONArray(TAG_COURSES);

                //LOOP FOR JSON1
                for(int i = 0; i < Courses1.length(); i++){
                    //LOOP FOR JSON2
                    for(int ii = 0; ii < Courses2.length(); ii++){
                        JSONObject courses1 = Courses1.getJSONObject(i);
                        JSONObject courses2 = Courses2.getJSONObject(ii);

                        // Storing each json1 item in variable
                        int courseID1 = courses1.getInt(TAG_COURSEID1);
                        Log.e("COURSEID2:", Integer.toString(courseID1));
                        String Rating1 = courses1.getString(TAG_RATING1);
                        int Status1 = courses1.getInt(TAG_STATUS1);
                        Log.e("Status1:", Integer.toString(Status1));      //Put the actual value for Status1 in log.             

                        // Storing each json2 item in variable
                        int courseID2 = courses2.getInt(TAG_COURSEID);
                        Log.e("COURSEID2:", Integer.toString(courseID));   //Put the actual value for CourseID in log
                        String Title2 = courses2.getString(TAG_TITLE);                      
                        String instructor2 = courses2.getString(TAG_INSTRUCTOR);
                        String length2 = courses2.getString(TAG_LENGTH);
                        String rating2 = courses2.getString(TAG_RATING);
                        String subject2 = courses2.getString(TAG_SUBJECT);
                        String description2 = courses2.getString(TAG_DESCRIPTION);

                        //Status1 = 5 from json1; Incomplete, Status1 =-1 Complete 
                        if(Status1 == 5 && courseID2 == courseID1){                                  

                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();         
                        //Storing the elements if condition is true.
                        map.put(TAG_COURSEID, Integer.toString(courseID2)); //pend for compare
                        map.put(TAG_TITLE, Title2);
                        map.put(TAG_INSTRUCTOR, instructor2);
                        map.put(TAG_LENGTH, length2);
                        map.put(TAG_RATING, rating2);
                        map.put(TAG_SUBJECT, subject2); //show it
                        map.put(TAG_DESCRIPTION, description2);

                        //adding HashList to ArrayList
                        contactList.add(map);
                        }//if
                    }//for2 (json2)
                } //for1 (json1)                
            }//Try

希望这有助于其他人,当然,只要把你的价值观和条件,以及那种观点,在这种情况下;列表视图上的Hashmap。

答案 8 :(得分:0)

对于已经使用杰克逊的人,我建议使用json-patch

final JsonNode patchNode = JsonDiff.asJson(firstNode, secondNode);
System.out.println("Diff=" + m.writeValueAsString(patchNode));

答案 9 :(得分:0)

如果要比较两个忽略元素/对象顺序的JSON,请查看此library是否对您有帮助。

用法:

List<Diff> diff = new DnjsonDiff().getDiff(String left, String right)
Left =[{"name":"Bob","businessKey":"4444"},{"name":"John","businessKey":"5555"}]
Right = [{"name":"Bob","businessKey":"6666"},{"name":"John", "businessKey":"4444"}]

Diff:

[
    {
        "op": "replace",
        "configuredValue": "John",
        "intendedValue": "Bob",
        "businessKey": "4444"
    },
    {
        "op": "remove",
        "configuredValue": null,
        "intendedValue": "{\"name\":\"John\",\"businessKey\":\"5555\"}",
        "businessKey": "5555"
    },
    {
        "op": "add",
        "configuredValue": "{\"name\":\"Bob\",\"businessKey\":\"6666\"}",
        "intendedValue": null,
        "businessKey": "null"
    }
]