Gson Deserialization Cookbook

In diesem Kochbuch untersuchen wir die verschiedenen Möglichkeiten, JSON mithilfe der beliebten Gson-Bibliothek in Java-Objekte zu entfernen.

1. Deserialisieren Sie JSON in ein einzelnes Basisobjekt

Fangen wir einfach an - wir werden einen einfachen JSON für ein Java-Objekt entfernen - Foo :

public class Foo { public int intValue; public String stringValue; // + standard equals and hashCode implementations }

Und die Lösung:

@Test public void whenDeserializingToSimpleObject_thenCorrect() { String json = "{"intValue":1,"stringValue":"one"}"; Foo targetObject = new Gson().fromJson(json, Foo.class); assertEquals(targetObject.intValue, 1); assertEquals(targetObject.stringValue, "one"); }

2. Deserialisieren Sie JSON in ein generisches Objekt

Weiter - definieren wir ein Objekt mithilfe von Generika:

public class GenericFoo { public T theValue; }

Und entfernen Sie einige Json in diese Art von Objekt:

@Test public void whenDeserializingToGenericObject_thenCorrect() { Type typeToken = new TypeToken
    
     () { }.getType(); String json = "{"theValue":1}"; GenericFoo targetObject = new Gson().fromJson(json, typeToken); assertEquals(targetObject.theValue, new Integer(1)); }
    

3. Deserialisieren Sie JSON mit zusätzlichen unbekannten Feldern für das Objekt

Als nächstes deserialisieren wir einen komplexen JSON, der zusätzliche, unbekannte Felder enthält :

@Test public void givenJsonHasExtraValues_whenDeserializing_thenCorrect() { String json = "{"intValue":1,"stringValue":"one","extraString":"two","extraFloat":2.2}"; Foo targetObject = new Gson().fromJson(json, Foo.class); assertEquals(targetObject.intValue, 1); assertEquals(targetObject.stringValue, "one"); }

Wie Sie sehen können, ignoriert Gson die unbekannten Felder und stimmt einfach mit den Feldern überein, die es kann.

4. Deserialisieren Sie JSON mit nicht übereinstimmenden Feldnamen für das Objekt

Nun wollen wir sehen, wie Gson mit einer JSON-Zeichenfolge umgeht, die Felder enthält, die einfach nicht mit den Feldern unseres Foo- Objekts übereinstimmen :

@Test public void givenJsonHasNonMatchingFields_whenDeserializingWithCustomDeserializer_thenCorrect() { String json = "{"valueInt":7,"valueString":"seven"}"; GsonBuilder gsonBldr = new GsonBuilder(); gsonBldr.registerTypeAdapter(Foo.class, new FooDeserializerFromJsonWithDifferentFields()); Foo targetObject = gsonBldr.create().fromJson(json, Foo.class); assertEquals(targetObject.intValue, 7); assertEquals(targetObject.stringValue, "seven"); }

Beachten Sie, dass wir einen benutzerdefinierten Deserializer registriert haben. Dadurch konnten die Felder aus der JSON-Zeichenfolge korrekt analysiert und unserem Foo zugeordnet werden :

public class FooDeserializerFromJsonWithDifferentFields implements JsonDeserializer { @Override public Foo deserialize (JsonElement jElement, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jObject = jElement.getAsJsonObject(); int intValue = jObject.get("valueInt").getAsInt(); String stringValue = jObject.get("valueString").getAsString(); return new Foo(intValue, stringValue); } }

5. Deserialisieren Sie das JSON-Array in ein Java-Array von Objekten

Als Nächstes deserialisieren wir ein JSON-Array in ein Java-Array von Foo- Objekten:

@Test public void givenJsonArrayOfFoos_whenDeserializingToArray_thenCorrect() { String json = "[{"intValue":1,"stringValue":"one"}," + "{"intValue":2,"stringValue":"two"}]"; Foo[] targetArray = new GsonBuilder().create().fromJson(json, Foo[].class); assertThat(Lists.newArrayList(targetArray), hasItem(new Foo(1, "one"))); assertThat(Lists.newArrayList(targetArray), hasItem(new Foo(2, "two"))); assertThat(Lists.newArrayList(targetArray), not(hasItem(new Foo(1, "two")))); }

6. Deserialisieren Sie das JSON-Array in die Java-Sammlung

Als nächstes ein JSON-Array direkt in eine Java-Sammlung :

@Test public void givenJsonArrayOfFoos_whenDeserializingCollection_thenCorrect() { String json = "[{"intValue":1,"stringValue":"one"},{"intValue":2,"stringValue":"two"}]"; Type targetClassType = new TypeToken
    
     () { }.getType(); Collection targetCollection = new Gson().fromJson(json, targetClassType); assertThat(targetCollection, instanceOf(ArrayList.class)); }
    

7. Deserialisieren Sie JSON in verschachtelte Objekte

Als nächstes definieren wir unser verschachteltes Objekt - FooWithInner :

public class FooWithInner { public int intValue; public String stringValue; public InnerFoo innerFoo; public class InnerFoo { public String name; } }

Und so können Sie eine Eingabe mit diesem verschachtelten Objekt deserialisieren:

@Test public void whenDeserializingToNestedObjects_thenCorrect() { String json = "{\"intValue\":1,\"stringValue\":\"one\",\"innerFoo\":{\"name\":\"inner\"}}"; FooWithInner targetObject = new Gson().fromJson(json, FooWithInner.class); assertEquals(targetObject.intValue, 1); assertEquals(targetObject.stringValue, "one"); assertEquals(targetObject.innerFoo.name, "inner"); }

8. Deserialisieren Sie JSON mit dem benutzerdefinierten Konstruktor

Lassen Sie uns abschließend sehen, wie Sie mithilfe von InstanceCreator die Verwendung eines bestimmten Konstruktors während der Deserialisierung anstelle des Standardkonstruktors - kein Argumentkonstruktor - erzwingen :

public class FooInstanceCreator implements InstanceCreator { @Override public Foo createInstance(Type type) { return new Foo("sample"); } }

Und so verwenden Sie unseren FooInstanceCreator bei der Deserialisierung:

@Test public void whenDeserializingUsingInstanceCreator_thenCorrect() { String json = "{\"intValue\":1}"; GsonBuilder gsonBldr = new GsonBuilder(); gsonBldr.registerTypeAdapter(Foo.class, new FooInstanceCreator()); Foo targetObject = gsonBldr.create().fromJson(json, Foo.class); assertEquals(targetObject.intValue, 1); assertEquals(targetObject.stringValue, "sample"); }

Beachten Sie, dass Foo.stringValue anstelle von null gleich sample ist, da wir den folgenden Konstruktor verwendet haben:

public Foo(String stringValue) { this.stringValue = stringValue; }

9. Fazit

Dieser Artikel zeigt, wie Sie die Gson-Bibliothek nutzen können, um JSON-Eingaben zu analysieren. Dabei werden die häufigsten Anwendungsfälle für einzelne und mehrere Objekte behandelt.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie in meinem Github-Projekt - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.