Confronta due oggetti JSON con Jackson

1. Panoramica

In questo articolo, daremo uno sguardo al confronto di due oggetti JSON utilizzando Jackson: una libreria di elaborazione JSON per Java.

2. Dipendenza da Maven

Innanzitutto, aggiungiamo la dipendenza jackson-databind Maven:

 com.fasterxml.jackson.core jackson-databind 2.11.1  

3. Utilizzo di Jackson per confrontare due oggetti JSON

Useremo la classe ObjectMapper per leggere un oggetto come JsonNode.

Creiamo un ObjectMapper :

ObjectMapper mapper = new ObjectMapper();

3.1. Confronta due semplici oggetti JSON

Cominciamo utilizzando il metodo JsonNode.equals . Il metodo equals () esegue un confronto completo (profondo).

Supponiamo di avere una stringa JSON definita come variabile s1 :

{ "employee": { "id": "1212", "fullName": "John Miles", "age": 34 } }

E vogliamo confrontarlo con un altro JSON, s2 :

{ "employee": { "id": "1212", "age": 34, "fullName": "John Miles" } }

Leggiamo il JSON di input come JsonNode e confrontiamo:

assertEquals(mapper.readTree(s1), mapper.readTree(s2));

È importante notare che anche se l'ordine degli attributi nelle variabili JSON di input s1 e s2 non è lo stesso, il metodo equals () ignora l'ordine e li tratta come uguali.

3.2. Confronta due oggetti JSON con un elemento nidificato

Successivamente, vedremo come confrontare due oggetti JSON con elementi nidificati.

Cominciamo con un JSON definito come variabile s1 :

{ "employee": { "id": "1212", "fullName":"John Miles", "age": 34, "contact": { "email": "[email protected]", "phone": "9999999999" } } }

Come possiamo vedere, il JSON contiene un contatto elemento nidificato . Vogliamo confrontarlo con un altro JSON definito da s2 :

{ "employee": { "id": "1212", "age": 34, "fullName": "John Miles", "contact": { "email": "[email protected]", "phone": "9999999999" } } }

Leggiamo il JSON di input come JsonNode e confrontiamo:

assertEquals(mapper.readTree(s1), mapper.readTree(s2)); 

Ancora una volta, dovremmo notare che equals () può anche confrontare due oggetti JSON di input con elementi nidificati.

3.3. Confronta due oggetti JSON contenenti un elemento elenco

Allo stesso modo, possiamo anche confrontare due oggetti JSON che contengono un elemento di elenco.

Consideriamo questo JSON definito come s1 :

{ "employee": { "id": "1212", "fullName": "John Miles", "age": 34, "skills": ["Java", "C++", "Python"] } }

Lo stiamo confrontando con un altro JSON s2 :

{ "employee": { "id": "1212", "age": 34, "fullName": "John Miles", "skills": ["Java", "C++", "Python"] } }

Leggiamo il JSON di input come JsonNode e confrontiamo:

assertEquals(mapper.readTree(s1), mapper.readTree(s2));

È importante sapere che due elementi dell'elenco vengono confrontati come uguali solo se hanno gli stessi valori nello stesso identico ordine.

4. Confronta due oggetti JSON con un comparatore personalizzato

JsonNode.equals funziona abbastanza bene nella maggior parte dei casi. Jackson fornisce anche JsonNode.equals (comparator, JsonNode) per configurare un oggetto Java C omparator personalizzato . Comprendiamo come utilizzare un comparatore personalizzato .

4.1. Comparatore personalizzato per confrontare valori numerici

Comprendiamo come utilizzare un comparatore personalizzato per confrontare due elementi JSON con valori numerici.

Useremo questo JSON come input s1 :

{ "name": "John", "score": 5.0 }

Facciamo un confronto con un altro JSON definito come s2 :

{ "name": "John", "score": 5 }

Dobbiamo osservare che i valori del punteggio dell'attributo negli input s1 e s2 non sono gli stessi.

Leggiamo il JSON di input come JsonNode e confrontiamo:

JsonNode actualObj1 = mapper.readTree(s1); JsonNode actualObj2 = mapper.readTree(s2); assertNotEquals(actualObj1, actualObj2);

Come possiamo notare, i due oggetti non sono uguali. Il metodo standard equals () considera i valori 5.0 e 5 diversi.

Tuttavia, possiamo utilizzare un comparatore personalizzato per confrontare i valori 5 e 5.0 e trattarli come uguali .

Creiamo prima un comparatore per confrontare due oggetti NumericNode :

public class NumericNodeComparator implements Comparator { @Override public int compare(JsonNode o1, JsonNode o2) { if (o1.equals(o2)){ return 0; } if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)){ Double d1 = ((NumericNode) o1).asDouble(); Double d2 = ((NumericNode) o2).asDouble(); if (d1.compareTo(d2) == 0) { return 0; } } return 1; } }

Successivamente, vediamo come utilizzare questo comparatore :

NumericNodeComparator cmp = new NumericNodeComparator(); assertTrue(actualObj1.equals(cmp, actualObj2));

4.2. Comparatore personalizzato per confrontare i valori di testo

Vediamo un altro esempio di un comparatore personalizzato per un confronto senza distinzione tra maiuscole e minuscole di due valori JSON.

We'll use this JSON as input s1:

{ "name": "john", "score": 5 }

Let's compare with another JSON defined as s2:

{ "name": "JOHN", "score": 5 }

As we can see the attribute name is lowercase in input s1 and uppercase in s2.

Let's first create a Comparator to compare two TextNode objects:

public class TextNodeComparator implements Comparator { @Override public int compare(JsonNode o1, JsonNode o2) { if (o1.equals(o2)) { return 0; } if ((o1 instanceof TextNode) && (o2 instanceof TextNode)) { String s1 = ((TextNode) o1).asText(); String s2 = ((TextNode) o2).asText(); if (s1.equalsIgnoreCase(s2)) { return 0; } } return 1; } }

Let's see how to compare s1 and s2 using TextNodeComparator:

JsonNode actualObj1 = mapper.readTree(s1); JsonNode actualObj2 = mapper.readTree(s2); TextNodeComparator cmp = new TextNodeComparator(); assertNotEquals(actualObj1, actualObj2); assertTrue(actualObj1.equals(cmp, actualObj2));

Finally, we can see using a custom comparator object while comparing two JSON objects can be very useful when the input JSON element value is not exactly the same but we still want to treat them as equal.

5. Conclusion

In questo breve tutorial, abbiamo visto come utilizzare Jackson per confrontare due oggetti JSON e utilizzare un comparatore personalizzato .

Ovviamente, come sempre, il codice sorgente completo di tutti gli esempi discussi qui può essere trovato su GitHub.