Сравнете два JSON обекта с Gson

1. Общ преглед

JSON е низово представяне на данни. Може да пожелаем да сравним тези данни в нашите алгоритми или тестове. И въпреки че е възможно да се сравняват низове, съдържащи JSON, сравнението на низове е чувствително към разликите в представянето , а не към съдържанието.

За да преодолеем това и да сравним JSON данните семантично, трябва да заредим данните в структура в паметта, която не е засегната от неща като празно пространство или от реда на ключовете на обекта.

В този кратък урок ще разрешим това с помощта на Gson, библиотека за сериализация \ десериализация на JSON, която може да направи дълбоко сравнение между JSON обектите.

2. Семантично идентичен JSON в различни низове

Нека разгледаме по-отблизо проблема, който се опитваме да разрешим.

Да приемем, че имаме два низа, представляващи едни и същи JSON данни, но един от тях има допълнителни интервали в края им:

String string1 = "{\"fullName\": \"Emily Jenkins\", \"age\": 27 }"; String string2 = "{\"fullName\": \"Emily Jenkins\", \"age\": 27}";

Въпреки че съдържанието на JSON обектите е равно, сравняването на горното като низове ще покаже разлика:

assertNotEquals(string1, string2);

Същото би се случило, ако редът на ключовете в даден обект беше различен, въпреки че JSON обикновено не е чувствителен към това:

String string1 = "{\"fullName\": \"Emily Jenkins\", \"age\": 27}"; String string2 = "{\"age\": 27, \"fullName\": \"Emily Jenkins\"}"; assertNotEquals(string1, string2);

Ето защо бихме се възползвали от използването на JSON обработваща библиотека за сравняване на JSON данни.

3. Зависимост на Maven

За да използваме Gson, нека първо добавим зависимостта Gson Maven:

 com.google.code.gson gson 2.8.6 

4. Анализиране на JSON в Gson Objects

Преди да се впуснем в сравнението на обекти, нека да разгледаме как Gson представя JSON данни в Java.

Когато работим с JSON в Java, първо трябва да преобразуваме JSON String в Java обект. Gson предоставя JsonParser, който анализира източника JSON в дърво на JsonElement :

JsonParser parser = new JsonParser(); String objectString = "{\"customer\": {\"fullName\": \"Emily Jenkins\", \"age\": 27 }}"; String arrayString = "[10, 20, 30]"; JsonElement json1 = parser.parse(objectString); JsonElement json2 = parser.parse(arrayString);

JsonElement е абстрактен клас, представляващ елемент на JSON. Методът на разбор връща изпълнение на JsonElement ; или JsonObject, JsonArray, JsonPrimitive или JsonNull:

assertTrue(json1.isJsonObject()); assertTrue(json2.isJsonArray());

Всеки от тези подкласове ( JsonObject, JsonArray и др.) Заменя метода Object.equals , осигурявайки ефективно дълбоко JSON сравнение.

5. Случаи за използване на Gson Сравнение

5.1. Сравнете два прости JSON обекта

Да предположим, че имаме два низа, представляващи прости JSON обекти, където редът на ключовете е различен:

Първият обект има fullName по-рано от възрастта :

{ "customer": { "id": 44521, "fullName": "Emily Jenkins", "age": 27 } }

Вторият обръща реда:

{ "customer": { "id": 44521, "age": 27, "fullName": "Emily Jenkins" } }

Можем просто да ги анализираме и сравним:

assertEquals(parser.parse(string1), parser.parse(string2));

В този случай JsonParser връща JsonObject , чието равно изпълнение не е чувствително към реда .

5.2. Сравнете два JSON масива

В случай на масиви JSON, JsonParser ще върне JsonArray.

Ако имаме един масив в един ред:

[10, 20, 30]
assertTrue(parser.parse(string1).isJsonArray());

Можем да го сравним с друг в различен ред:

[20, 10, 30]

За разлика от JSON обектите , JsonArray е равни метод е, за чувствителни , така че тези масиви не са равни, което е семантично правилен:

assertNotEquals(parser.parse(string1), parser.parse(string2));

5.3. Сравнете два вложени JSON обекта

Както видяхме по-рано, JsonParser може да анализира дървовидната структура на JSON. Всеки JsonObject и JsonArray съдържат други JsonElement обекти, които сами могат да бъдат от типа JsonObject или JsonArray .

Когато използваме equals , той сравнява всички членове рекурсивно, което означава, че вложени обекти също са сравними:

Ако това е string1 :

{ "customer": { "id": "44521", "fullName": "Emily Jenkins", "age": 27, "consumption_info": { "fav_product": "Coke", "last_buy": "2012-04-23" } } }

И този JSON е string2 :

{ "customer": { "fullName": "Emily Jenkins", "id": "44521", "age": 27, "consumption_info": { "last_buy": "2012-04-23", "fav_product": "Coke" } } }

Тогава все още можем да използваме метода equals , за да ги сравним:

assertEquals(parser.parse(string1), parser.parse(string2));

6. Заключение

В тази кратка статия разгледахме предизвикателствата при сравняването на JSON като низ . Видяхме как Gson ни позволява да анализираме тези низове в обектна структура, която поддържа сравнение.

Както винаги, изходният код на примерите по-горе може да бъде намерен в GitHub.