Usporedite dva JSON objekta s Gson

1. Pregled

JSON je niz podataka. Možda ćemo htjeti usporediti ove podatke u našim algoritmima ili testovima. Iako je moguće usporediti nizove koji sadrže JSON, usporedba nizova osjetljiva je na razlike u zastupljenosti, a ne sadržaj.

Da bismo to prevladali i semantički usporedili JSON podatke, podatke moramo učitati u strukturu u memoriji na koju ne utječu stvari poput razmaka ili redoslijed ključeva objekta.

U ovom kratkom vodiču to ćemo riješiti pomoću Gson, JSON biblioteke za serializaciju \ deserializaciju koja može izvršiti duboku usporedbu između JSON objekata.

2. Semantički identičan JSON u različitim žicama

Pogledajmo pobliže problem koji pokušavamo riješiti.

Pretpostavimo da imamo dva niza koji predstavljaju iste JSON podatke, ali jedan od njih ima nekoliko dodatnih prostora na kraju:

Niz string1 = "{\" punoime \ ": \" Emily Jenkins \ ", \" dob \ ": 27}"; Niz string2 = "{\" punoime \ ": \" Emily Jenkins \ ", \" dob \ ": 27}";

Iako je sadržaj JSON objekata jednak, usporedba gore navedenog kao niza pokazat će razliku:

assertNotEquals (string1, string2);

Isto bi se dogodilo da se redoslijed ključeva u objektu mijenja, iako JSON obično nije osjetljiv na ovo:

Niz string1 = "{\" punoime \ ": \" Emily Jenkins \ ", \" dob \ ": 27}"; Niz string2 = "{\" dob \ ": 27, \" punoime \ ": \" Emily Jenkins \ "}"; assertNotEquals (string1, string2);

Zbog toga bi nam koristilo korištenje knjižnice obrade JSON za usporedbu JSON podataka.

3. Ovisnost Mavena

Da bismo koristili Gson, dodajmo prvo ovisnost Gson Maven:

 com.google.code.gson gson 2.8.6 

4. Raščlanjivanje JSON-a na Gson objekte

Prije nego što krenemo u usporedbu objekata, pogledajmo kako Gson predstavlja JSON podatke u Javi.

Kada radimo s JSON-om na Javi, prvo moramo pretvoriti JSON String u Java objekt. Gson pruža JsonParser koji raščlanjuje izvor JSON na JsonElement stablo:

JsonParser parser = novi JsonParser (); String objectString = "{\" kupac \ ": {\" puno ime \ ": \" Emily Jenkins \ ", \" dob \ ": 27}}"; Niz arrayString = "[10, 20, 30]"; JsonElement json1 = parser.parse (objectString); JsonElement json2 = parser.parse (arrayString);

JsonElement je apstraktna klasa koja predstavlja element JSON-a. The raščlaniti metoda vraća implementaciju JsonElement; bilo a JsonObject, JsonArray, JsonPrimitive ili JsonNull:

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

Svaka od tih potklasa (JsonObject, JsonArray, itd.) nadjačava Objekt.jednak metoda koja pruža učinkovitu dubinsku JSON usporedbu.

5. Slučajevi upotrebe Gsona za usporedbu

5.1. Usporedite dva jednostavna JSON objekta

Pretpostavimo da imamo dva niza koji predstavljaju jednostavne JSON objekte, a redoslijed tipki je drugačiji:

Prvi objekt ima puno ime ranije od dob:

{"kupac": {"id": 44521, "puno ime": "Emily Jenkins", "dob": 27}}

Drugi obrće redoslijed:

{"kupac": {"id": 44521, "dob": 27, "puno ime": "Emily Jenkins"}}

Jednostavno ih možemo raščlaniti i usporediti:

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

U ovom slučaju, JsonParser vraća a JsonObject, čiji jednako provedba nijeosjetljiv na redoslijed.

5.2. Usporedite dva JSON niza

U slučaju JSON nizova, JsonParser vratit će a JsonArray.

Ako imamo jedan niz u jednom redoslijedu:

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

Možemo ga usporediti s drugim u drugačijem redoslijedu:

[20, 10, 30]

Za razliku od JsonObject, JsonArray‘S jednako metoda ovisi o redoslijedu, pa ti nizovi nisu jednaki, što je semantički ispravno:

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

5.3. Usporedite dva ugniježđena JSON objekta

Kao što smo vidjeli ranije, JsonParser može raščlaniti strukturu JSON-a sličnu stablu. Svaki JsonObject i JsonArray sadrže drugo JsonElement predmeti, koji i sami mogu biti tipa JsonObject ili JsonArray.

Kad koristimo jednako, uspoređuje sve članove rekurzivno, što znači ugniježđeni objekti također su usporedivi:

Ako je ovo niz1:

{"kupac": {"id": "44521", "puno ime": "Emily Jenkins", "dob": 27, "potrošnja_info": {"fav_product": "Koks-kolu", "last_buy": "2012-04 -23 "}}}

A ovaj JSON jest niz2:

{"kupac": {"puno ime": "Emily Jenkins", "id": "44521", "dob": 27, "potrošnja_info": {"last_buy": "2012-04-23", "fav_product": "Koksa"}}}

Tada još uvijek možemo koristiti jednako metoda za njihovu usporedbu:

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

6. Zaključak

U ovom kratkom članku pogledali smo izazove uspoređivanja JSON-a kao a Niz. Vidjeli smo kako nam Gson omogućuje raščlanjivanje tih nizova u strukturu objekta koja podržava usporedbu.

Kao i uvijek, izvorni kod gore navedenih primjera može se naći na GitHubu.