Travailler avec des valeurs primitives dans Gson

Travailler avec des valeurs primitives dans Gson

1. Overview

Dans ce tutoriel, nous allons àlearn how to serialize and deserialize primitive values with Gson. Google a développé la bibliothèque Gson pour sérialiser et désérialiser JSON. De plus, nous allons en apprendre davantage sur certaines bizarreries spécifiques de la bibliothèque Gson lorsqu'il s'agit de traiter les primitives.

D'autre part, si nous devons travailler avec des tableaux, des collections, des objets imbriqués ou toute autre personnalisation, nous avons des tutoriels supplémentaires surserializing with Gson etdeserializing with Gson.

2. Dépendance Maven

Pour travailler avec Gson, nous devons ajouter la dépendanceGson au pom:


    com.google.code.gson
    gson
    2.8.5

3. Sérialisation des types primitifs

La sérialisation avec Gson est assez simple. Nous utiliserons le modèle suivant comme exemple:

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;
}

Commençons par initialiser une instance avec des valeurs de test:

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';

Ensuite, nous pouvons le sérialiser:

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

Enfin, nous pouvons voir le résultat sérialisé:

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

Nous devrions noter quelques détails de notre exemple. Pour commencer, la valeur d'octet n'est pas sérialisée sous la forme d'une chaîne de bits comme dans le modèle. En plus de cela, il n'y a pas de distinction entre court, int et long. En outre, il n'y a pas de distinction entre float et double.

Une autre chose à noter est qu'une chaîne représente la valeur du caractère.

En fait, ces trois dernières choses n'ont rien à voir avec Gson, mais c'est la façon dont JSON est défini.

3.1. Sérialisation de valeurs à virgule flottante spéciales

Java a des constantesFloat.POSITIVE_INFINITY etNEGATIVE_INFINITY pour représenter l'infini. Gson ne peut pas sérialiser ces valeurs spéciales:

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);

Essayer de le faire soulève unIllegalArgumentException.

Tenter de sérialiserNaN déclenche également unIllegalArgumentException car cette valeur n'est pas autorisée par la spécification JSON.

Pour la même raison, essayer de sérialiserDouble.POSITIVE_INFINITY, NEGATIVE_INFINITY ouNaN lance également unIllegalArgumentException.

4. Désérialisation des types primitifs

Voyons maintenant comment nous désérialiserions la chaîne JSON obtenue dans l'exemple précédent.

La désérialisation est aussi simple que la sérialisation:

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

Enfin, nous pouvons vérifier que le modèle contient les valeurs souhaitées:

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. Désérialisation des valeurs de chaîne

Lorsqu'une valeur valide est placée dans une chaîne, Gson l'analyse et la gère comme prévu:

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);

Il est à noter que les valeurs de chaîne ne peuvent pas être désérialisées en types booléens.

4.2. Désérialisation Valeurs de chaîne vides

D'un autre côté, essayons de désérialiser le JSON suivant avec des chaînes vides:

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

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

Cela déclenche unJsonSyntaxException car les chaînes vides ne sont pas attendues lors de la désérialisation des primitives.

4.3. Désérialisation des valeurs nulles

Si vous essayez de désérialiser un champ avec la valeurnull, Gson ignorera ce champ. Par exemple, avec la classe suivante:

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 ignore les champs nuls:

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. Désérialisation des valeurs qui débordent

C'est un cas très intéressant que Gson gère inopinément. Essayer de désérialiser:

{"value": 300}

Avec le modèle:

class ByteExample {
    public byte value;
}

En conséquence, l'objet a une valeur de 44. It is handled poorly because in these cases an exception could be raised instead. Cela empêcherait des erreurs indétectables de se propager dans l'application.

4.5. Désérialisation des nombres à virgule flottante

Ensuite, essayons de désérialiser le JSON suivant en un objetByteExample:

{"value": 2.3}

Gson fait ici ce qu'il faut et lève unJsonSyntaxException dont le sous-type est unNumberFormatException. Peu importe le type discret que nous utilisons (byte,short,int  oulong), nous obtenons le même résultat.

Si la valeur se termine par “.0”, Gson désérialisera le nombre comme prévu.

4.6. Désérialisation des valeurs booléennes numériques

Parfois, un booléen est codifié comme 0 ou 1 au lieu de «vrai» ou «faux». Gson ne permet pas cela par défaut. Par exemple, si nous essayons de désérialiser:

{"value": 1}

dans le modèle:

class BooleanExample {
    public boolean value;
}

Gson lève unJsonSyntaxException avec un sous-type d'exception deIllegalStateException. This is in contrast with the NumberFormatException raised when numbers didn’t match. Si nous voulions changer cela, nous pourrions utiliser uncustom deserializer.

4.7. Désérialisation des caractères Unicode

Il est à noter que la désérialisation des caractères Unicode ne nécessite aucune configuration supplémentaire.

Par exemple, le JSON:

{"value": "\u00AE"}

Donnera le caractère ®.

5. Conclusion

Comme nous l'avons vu, Gson fournit un moyen simple de travailler avec les types primitifs JSON et Java. Il faut tenir compte de certains comportements inattendus, même lorsqu'il s'agit de types primitifs simples.

L'implémentation complète de cet article se trouve dansthe GitHub project - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.