Sammenlign to JSON-objekter med Gson

1. Oversigt

JSON er en strengrepræsentation af data. Vi ønsker muligvis at sammenligne disse data i vores algoritmer eller tests. Og selvom det er muligt at sammenligne strenge, der indeholder JSON, streng sammenligning er følsom over for forskelle i repræsentation, snarere end indhold.

For at overvinde dette og sammenligne JSON-data semantisk er vi nødt til at indlæse dataene i en struktur i hukommelsen, der ikke er påvirket af ting som hvidt rum eller rækkefølgen af ​​et objekts nøgler.

I denne korte vejledning løser vi dette ved hjælp af Gson, et JSON-serialiserings- / deserialiseringsbibliotek, der kan foretage en dyb sammenligning mellem JSON-objekter.

2. Semantisk identisk JSON i forskellige strenge

Lad os se nærmere på det problem, vi prøver at løse.

Antag, at vi har to strenge, der repræsenterer de samme JSON-data, men den ene har nogle ekstra mellemrum i slutningen af ​​den:

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

Selvom indholdet af JSON-objekterne er ens, vil sammenligning af ovenstående som strenge vise en forskel:

assertNotEquals (streng1, streng2);

Det samme ville ske, hvis rækkefølgen af ​​nøgler i et objekt var varieret, selvom JSON normalt ikke er følsom over for dette:

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

Dette er grunden til, at det er fordel for os at bruge et JSON-behandlingsbibliotek til at sammenligne JSON-data.

3. Maven-afhængighed

For at bruge Gson, lad os først tilføje Gson Maven-afhængighed:

 com.google.code.gson gson 2.8.6 

4. Parsing af JSON i Gson-objekter

Før vi dykker ned i sammenligning af objekter, skal vi se på, hvordan Gson repræsenterer JSON-data i Java.

Når vi arbejder med JSON i Java, skal vi først konvertere JSON-strengen til et Java-objekt. Gson giver JsonParser som parser kilde JSON til en JsonElement træ:

JsonParser parser = ny JsonParser (); String objectString = "{\" kunde \ ": {\" fuldnavn \ ": \" Emily Jenkins \ ", \" alder \ ": 27}}"; Streng arrayString = "[10, 20, 30]"; JsonElement json1 = parser.parse (objectString); JsonElement json2 = parser.parse (arrayString);

JsonElement er en abstrakt klasse, der repræsenterer et element i JSON. Det parse metode returnerer en implementering af JsonElement; enten en JsonObject, JsonArray, JsonPrimitive eller JsonNull:

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

Hver af disse underklasser (JsonObject, JsonArray, etc.) tilsidesætter Objekt. Ligestilling metode, der giver en effektiv dyb JSON-sammenligning.

5. Brugssager til Gson-sammenligning

5.1. Sammenlign to enkle JSON-objekter

Antag, at vi har to strenge, der repræsenterer enkle JSON-objekter, hvor rækkefølgen af ​​nøgler er forskellig:

Det første objekt har fulde navn tidligere end alder:

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

Den anden vender rækkefølgen:

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

Vi kan simpelthen analysere og sammenligne dem:

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

I dette tilfælde er JsonParser returnerer a JsonObject, hvis lige med implementering er ikkerækkefølsom.

5.2. Sammenlign to JSON-arrays

I tilfælde af JSON-arrays, JsonParser vil returnere en JsonArray.

Hvis vi har en matrix i en rækkefølge:

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

Vi kan sammenligne det med en anden i en anden rækkefølge:

[20, 10, 30]

I modsætning til JsonObject, JsonArray'S lige med metoden er rækkefølsom, så disse arrays er ikke ens, hvilket er semantisk korrekt:

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

5.3. Sammenlign to indlejrede JSON-objekter

Som vi så tidligere, JsonParser kan analysere den trælignende struktur af JSON. Hver JsonObject og JsonArray indeholder andet JsonElement objekter, som selv kan være af typen JsonObject eller JsonArray.

Når vi bruger lige med, sammenligner det alle medlemmer rekursivt, hvilket betyder indlejrede genstande er også sammenlignelige:

Hvis dette er tilfældet streng1:

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

Og det er denne JSON streng2:

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

Så kan vi stadig bruge lige med metode til at sammenligne dem:

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

6. Konklusion

I denne korte artikel har vi set på udfordringerne ved at sammenligne JSON som en Snor. Vi har set, hvordan Gson giver os mulighed for at analysere disse strenge i en objektstruktur, der understøtter sammenligning.

Som altid kan kildekoden til eksemplerne ovenfor findes på GitHub.