Mit primitiven Werten in Gson arbeiten

Arbeiten mit primitiven Werten in Gson

1. Overview

In diesem Tutorial gehen wir zulearn how to serialize and deserialize primitive values with Gson. Google hat die Gson-Bibliothek entwickelt, um JSON zu serialisieren und zu deserialisieren. Darüber hinaus werden wir einige spezifische Besonderheiten der Gson-Bibliothek im Umgang mit Grundelementen kennenlernen.

Wenn wir dagegen mit Arrays, Sammlungen, verschachtelten Objekten oder anderen Anpassungen arbeiten müssen, haben wir zusätzliche Tutorials zuserializing with Gson unddeserializing with Gson.

2. Maven-Abhängigkeit

Um mit Gson arbeiten zu können, müssen wir die Abhängigkeit vonGsonzum pom hinzufügen:


    com.google.code.gson
    gson
    2.8.5

3. Primitive Typen serialisieren

Das Serialisieren mit Gson ist ziemlich einfach. Wir verwenden das folgende Modell als Beispiel:

public class PrimitiveBundle {
    public byte byteValue;
    public short shortValue;
    public int intValue;
    public long longValue;
    public float floatValue;
    public double doubleValue;
    public boolean booleanValue;
    public char charValue;
}

Initialisieren wir zunächst eine Instanz mit einigen Testwerten:

PrimitiveBundle primitiveBundle = new PrimitiveBundle();
primitiveBundle.byteValue = (byte) 0x00001111;
primitiveBundle.shortValue = (short) 3;
primitiveBundle.intValue = 3;
primitiveBundle.longValue = 3;
primitiveBundle.floatValue = 3.5f;
primitiveBundle.doubleValue = 3.5;
primitiveBundle.booleanValue = true;
primitiveBundle.charValue = 'a';

Als nächstes können wir es serialisieren:

Gson gson = new Gson();
String json = gson.toJson(primitiveBundle);

Schließlich können wir das serialisierte Ergebnis sehen:

{
   "byteValue":17,
   "shortValue":3,
   "intValue":3,
   "longValue":3,
   "floatValue":3.5,
   "doubleValue":3.5,
   "booleanValue":true,
   "charValue":"a"
}

Wir sollten einige Details aus unserem Beispiel beachten. Für den Anfang wird der Bytewert nicht wie im Modell als Bitfolge serialisiert. Darüber hinaus gibt es keinen Unterschied zwischen short, int und long. Es gibt auch keinen Unterschied zwischen Float und Double.

Zu beachten ist auch, dass eine Zeichenfolge den Zeichenwert darstellt.

Eigentlich haben diese letzten drei Dinge nichts mit Gson zu tun, aber so wird JSON definiert.

3.1. Serialisierung spezieller Gleitkommawerte

Java hat die KonstantenFloat.POSITIVE_INFINITY undNEGATIVE_INFINITY, um die Unendlichkeit darzustellen. Gson kann diese speziellen Werte nicht serialisieren:

public class InfinityValuesExample {
    public float negativeInfinity;
    public float positiveInfinity;
}
InfinityValuesExample model = new InfinityValuesExample();
model.negativeInfinity = Float.NEGATIVE_INFINITY;
model.positiveInfinity = Float.POSITIVE_INFINITY;

Gson gson = new Gson();
gson.toJson(model);

Der Versuch, dies zu tun, erhöht einIllegalArgumentException.

Beim Versuch,NaN zu serialisieren, wird auchIllegalArgumentException ausgelöst, da dieser Wert in der JSON-Spezifikation nicht zulässig ist.

Aus dem gleichen Grund wird beim Versuch,Double.POSITIVE_INFINITY, NEGATIVE_INFINITY oderNaN zu serialisieren, auchIllegalArgumentException. ausgelöst

4. Primitive Typen deserialisieren

Schauen wir uns nun an, wie wir die im vorherigen Beispiel erhaltene JSON-Zeichenfolge deserialisieren würden.

Die Deserialisierung ist so einfach wie die Serialisierung:

Gson gson = new Gson();
PrimitiveBundle model = gson.fromJson(json, PrimitiveBundle.class);

Schließlich können wir überprüfen, ob das Modell die gewünschten Werte enthält:

assertEquals(17, model.byteValue);
assertEquals(3, model.shortValue);
assertEquals(3, model.intValue);
assertEquals(3, model.longValue);
assertEquals(3.5, model.floatValue, 0.0001);
assertEquals(3.5, model.doubleValue, 0.0001);
assertTrue(model.booleanValue);
assertEquals('a', model.charValue);

4.1. String-Werte deserialisieren

Wenn ein gültiger Wert in einen String eingefügt wird, analysiert Gson ihn und behandelt ihn erwartungsgemäß:

String json = "{\"byteValue\": \"15\", \"shortValue\": \"15\", "
  + "\"intValue\": \"15\", \"longValue\": \"15\", \"floatValue\": \"15.0\""
  + ", \"doubleValue\": \"15.0\"}";

Gson gson = new Gson();
PrimitiveBundleInitialized model = gson.fromJson(json, PrimitiveBundleInitialized.class);
assertEquals(15, model.byteValue);
assertEquals(15, model.shortValue);
assertEquals(15, model.intValue);
assertEquals(15, model.longValue);
assertEquals(15, model.floatValue, 0.0001);
assertEquals(15, model.doubleValue, 0.0001);

Es ist erwähnenswert, dass Zeichenfolgenwerte nicht in boolesche Typen deserialisiert werden können.

4.2. Deserialisieren Leere Zeichenfolgenwerte

Versuchen wir andererseits, den folgenden JSON mit leeren Zeichenfolgen zu deserialisieren:

String json = "{\"byteValue\": \"\", \"shortValue\": \"\", "
  + "\"intValue\": \"\", \"longValue\": \"\", \"floatValue\": \"\""
  + ", \"doubleValue\": \"\"}";

Gson gson = new Gson();
gson.fromJson(json, PrimitiveBundleInitialized.class);

Dies erhöht einJsonSyntaxException, da beim Deserialisieren von Primitiven. keine leeren Zeichenfolgen erwartet werden

4.3. Nullwerte deserialisieren

Der Versuch, ein Feld mit dem Wertnull zu deserialisieren, führt dazu, dass Gson dieses Feld ignoriert. Zum Beispiel mit der folgenden Klasse:

public class PrimitiveBundleInitialized {
    public byte byteValue = (byte) 1;
    public short shortValue = (short) 1;
    public int intValue = 1;
    public long longValue = 1L;
    public float floatValue = 1.0f;
    public double doubleValue = 1;
}

Gson ignoriert die Nullfelder:

String json = "{\"byteValue\": null, \"shortValue\": null, "
  + "\"intValue\": null, \"longValue\": null, \"floatValue\": null"
  + ", \"doubleValue\": null}";

Gson gson = new Gson();
PrimitiveBundleInitialized model = gson.fromJson(json, PrimitiveBundleInitialized.class);

assertEquals(1, model.byteValue);
assertEquals(1, model.shortValue);
assertEquals(1, model.intValue);
assertEquals(1, model.longValue);
assertEquals(1, model.floatValue, 0.0001);
assertEquals(1, model.doubleValue, 0.0001);

4.4. Überlaufende Werte deserialisieren

Dies ist ein sehr interessanter Fall, den Gson unerwartet behandelt. Versuchen zu deserialisieren:

{"value": 300}

Mit dem Modell:

class ByteExample {
    public byte value;
}

Als Ergebnis hat das Objekt einen Wert von 44. It is handled poorly because in these cases an exception could be raised instead. Dies würde verhindern, dass sich nicht erkennbare Fehler in der Anwendung ausbreiten.

4.5. Gleitkommazahlen deserialisieren

Versuchen wir als Nächstes, den folgenden JSON in einByteExample-Objekt zu deserialisieren:

{"value": 2.3}

Gson macht hier das Richtige und erhöht einJsonSyntaxException, dessen Subtyp einNumberFormatException ist. Es spielt keine Rolle, welchen diskreten Typ wir verwenden (byte,short,int oderlong), wir erhalten das gleiche Ergebnis.

Wenn der Wert auf ".0" endet, deserialisiert Gson die Nummer wie erwartet.

4.6. Deserialisieren numerischer boolescher Werte

Manchmal wird ein Boolescher Wert als 0 oder 1 anstelle von "wahr" oder "falsch" kodiert. Gson lässt dies standardmäßig nicht zu. Zum Beispiel, wenn wir versuchen, zu deserialisieren:

{"value": 1}

in das Modell:

class BooleanExample {
    public boolean value;
}

Gson erhöht einJsonSyntaxException mit einem Ausnahmesubtyp vonIllegalStateException. This is in contrast with the NumberFormatException raised when numbers didn’t match. Wenn wir das ändern wollten, könnten wircustom deserializer verwenden.

4.7. Deserialisieren von Unicode-Zeichen

Es ist anzumerken, dass für die Deserialisierung von Unicode-Zeichen keine zusätzliche Konfiguration erforderlich ist.

Zum Beispiel das JSON:

{"value": "\u00AE"}

Ergibt das Zeichen ®.

5. Fazit

Wie wir gesehen haben, bietet Gson eine einfache Möglichkeit, mit primitiven JSON- und Java-Typen zu arbeiten. Es gibt einige unerwartete Verhaltensweisen, die beachtet werden müssen, selbst wenn es sich um einfache primitive Typen handelt.

Die vollständige Implementierung dieses Artikels finden Sie inthe GitHub project - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.