Лучший способ сравнить 2 файла JSON в Java - PullRequest
15 голосов
/ 30 июня 2011

Как бы вы посоветовали решить эту задачу?

Задача, как я вижу, заключается в интеллектуальном представлении информации о различиях.Прежде чем я изобрету колесо, есть ли приемлемый подход, как такое сравнение должно быть обработано?

Ответы [ 9 ]

14 голосов
/ 26 июня 2015

Я рекомендую библиотеку zjsonpatch , которая представляет информацию о различиях в соответствии с RFC 6902 (JSON Patch).Вы можете использовать его с Джексоном:

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 не может справиться с этим (если элемент вставлен в середину массива, он будет думать, что этот элемент и каждый элемент после этого были изменены, поскольку все они сдвинуты на единицу).

8 голосов
/ 02 ноября 2015

У меня хороший опыт работы с 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);
}
... 
8 голосов
/ 30 июня 2011

Это касается только равенства, а не различий.


С Джексоном.

ObjectMapper mapper = new ObjectMapper();

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

boolean areTheyEqual = tree1.equals(tree2);

С JavaDoc для JsonNode.equals :

Равенство для узловых объектов определяется как полное (глубокое) равенство значений. Это означает, что можно сравнивать полные деревья JSON на равенство, сравнивая равенство корневых узлов.

4 голосов
/ 28 сентября 2016

Самый простой способ сравнить строки json - это использовать JSONCompare из JSONAssert библиотеки. Преимущество в том, что оно не ограничено только структурой и может сравнивать значения, если вы хотите:

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

, который выдаст что-то вроде:

Expected: VALUE1
     got: VALUE2
 ; field1.field2
4 голосов
/ 05 ноября 2011

У меня была похожая проблема, и я написал свою собственную библиотеку:

https://github.com/algesten/jsondiff

Делает оба изменения / исправления.

Различия сами являются объектами JSON и имеют простой синтаксис для слияния / замены объектов и вставки / замены массивов.

Пример:

original
{
   a: { b: 42 }
}

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

~ указывает на слияние объектов.

result
{
   a: { b: 42, c: 43 }
}
2 голосов
/ 30 июня 2011

Вы можете попробовать архитектуру XStream, обработку отображений JSON

Также посмотрите на этот пост: Сравнение двух файлов XML и создание третьего с XMLDiff в C #.Это в C #, но логика та же.

1 голос
/ 30 июня 2011

json-lib

Что бы я сделал, это проанализировал данные json, используя json-lib .В результате получатся обычные объекты Java, которые вы можете сравнить с помощью методов equals.Это справедливо только в том случае, если при условии, что ребята из json-lib правильно реализовали метод equals, но это легко проверить.

0 голосов
/ 09 октября 2014

Для людей, которые уже используют Джексон , я рекомендую json-patch

final JsonNode patchNode = JsonDiff.asJson(firstNode, secondNode);
System.out.println("Diff=" + m.writeValueAsString(patchNode));
0 голосов
/ 06 мая 2012

SR.это мое решение для 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 поверх списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...