Vergleichen Sie zwei JSON-Objekte mit Gson

1. Übersicht

JSON ist eine Zeichenfolgendarstellung von Daten. Möglicherweise möchten wir diese Daten in unseren Algorithmen oder Tests vergleichen. Obwohl es möglich ist, Zeichenfolgen zu vergleichen, die JSON enthalten, reagiert der Zeichenfolgenvergleich eher auf Unterschiede in der Darstellung als auf den Inhalt.

Um dies zu überwinden und JSON-Daten semantisch zu vergleichen, müssen wir die Daten in eine Struktur im Speicher laden, die nicht durch Leerzeichen oder die Reihenfolge der Schlüssel eines Objekts beeinflusst wird.

In diesem kurzen Tutorial lösen wir dieses Problem mit Gson, einer JSON-Serialisierungs- / Deserialisierungsbibliothek, die einen umfassenden Vergleich zwischen JSON-Objekten durchführen kann.

2. Semantisch identischer JSON in verschiedenen Strings

Schauen wir uns das Problem, das wir zu lösen versuchen, genauer an.

Angenommen, wir haben zwei Zeichenfolgen, die dieselben JSON-Daten darstellen, aber eine davon hat am Ende einige zusätzliche Leerzeichen:

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

Obwohl der Inhalt der JSON-Objekte gleich ist, zeigt der Vergleich der oben genannten Zeichenfolgen einen Unterschied:

assertNotEquals(string1, string2);

Dasselbe würde passieren, wenn die Reihenfolge der Schlüssel in einem Objekt geändert würde, obwohl JSON normalerweise nicht darauf reagiert:

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

Aus diesem Grund würden wir von der Verwendung einer JSON-Verarbeitungsbibliothek zum Vergleichen von JSON-Daten profitieren.

3. Maven-Abhängigkeit

Um Gson zu verwenden, fügen wir zunächst die Gson Maven-Abhängigkeit hinzu:

 com.google.code.gson gson 2.8.6 

4. Analysieren von JSON in Gson-Objekte

Bevor wir uns mit dem Vergleichen von Objekten befassen, schauen wir uns an, wie Gson JSON-Daten in Java darstellt.

Wenn Sie mit JSON in Java arbeiten, müssen Sie zuerst den JSON-String in ein Java-Objekt konvertieren. Gson stellt JsonParser zur Verfügung, der Quell-JSON in einen JsonElement- Baum analysiert :

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 ist eine abstrakte Klasse, die ein Element von JSON darstellt. Die Parse - Methode liefert eine Implementierung von JsonElement ; entweder ein JsonObject, JsonArray, JsonPrimitive oder JsonNull:

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

Jede dieser Unterklassen ( JsonObject, JsonArray usw.) überschreibt die Object.equals- Methode und bietet einen effektiven tiefen JSON-Vergleich.

5. Anwendungsfälle für den Gson-Vergleich

5.1. Vergleichen Sie zwei einfache JSON-Objekte

Angenommen, wir haben zwei Zeichenfolgen, die einfache JSON-Objekte darstellen, wobei die Reihenfolge der Schlüssel unterschiedlich ist:

Das erste Objekt hat fullname früher als Alter :

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

Der zweite kehrt die Reihenfolge um:

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

Wir können sie einfach analysieren und vergleichen:

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

In diesem Fall gibt der JsonParser ein JsonObject zurück , dessen gleichwertige Implementierung nicht auftragsabhängig ist .

5.2. Vergleichen Sie zwei JSON-Arrays

Bei JSON-Arrays gibt JsonParser ein JsonArray zurück.

Wenn wir ein Array in einer Reihenfolge haben:

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

Wir können es in einer anderen Reihenfolge mit einem anderen vergleichen:

[20, 10, 30]

Im Gegensatz zu JsonObject ist die Equals- Methode von JsonArray auftragsabhängig , sodass diese Arrays nicht gleich sind, was semantisch korrekt ist:

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

5.3. Vergleichen Sie zwei verschachtelte JSON-Objekte

Wie wir bereits gesehen haben, kann JsonParser die baumartige Struktur von JSON analysieren. Jedes JsonObject und JsonArray enthält andere JsonElement- Objekte, die selbst vom Typ JsonObject oder JsonArray sein können .

Wenn wir gleich verwenden , werden alle Elemente rekursiv verglichen, was bedeutet, dass auch verschachtelte Objekte vergleichbar sind:

Wenn dies string1 ist :

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

Und dieser JSON ist string2 :

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

Dann können wir sie immer noch mit der Methode equals vergleichen:

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

6. Fazit

In diesem kurzen Artikel haben wir uns mit den Herausforderungen des Vergleichs von JSON als String befasst . Wir haben gesehen, wie Gson es uns ermöglicht, diese Zeichenfolgen in eine Objektstruktur zu analysieren, die den Vergleich unterstützt.

Wie immer finden Sie den Quellcode der obigen Beispiele auf GitHub.