GSON est une bibliothèque Java utilisée pour implémenter la conversion mutuelle entre les objets JSON et Java. GSON est un projet open source hébergé sur https://github.com/google/gson.
La classe principale de GSON est GSON. Vous pouvez également utiliser la classe GSONBuilder pour définir certaines options lors de la création d'objets GSON.
Les objets GSON n'enregistrent aucun état lors du traitement de JSON, afin que les utilisateurs puissent facilement effectuer plusieurs sérialisations, désérialisation et autres opérations sur le même objet GSON.
Exemple: utilisation de base
// serializationgson gson = new gson (); gson.tojson (1); // ==> imprime 1GSON.Tojson ("ABCD"); // ==> imprime "ABCD" gson.tojson (new Long (10)); // ==> imprime 10Int [] valeurs = {1}; gson.tojson (valeurs); // ==> imprime [1] // DeserializationInt One = gson.fromjson ("1", int.class); Integer One = GSON.Fromjson ("1", Integer.class); Long One = GSON.Fromjson ("1", Long.class); Boolean F = gson.fromjson ("false", boolean.class); String str = gson.fromjson ("/" ABC / "", String.class); String anotherstr = gson.fromjson ("[/" ABC / "]", String.class); // SerializationBagofPritives; gson.tojson (obj); // ==> json est {"value1": 1, "value2": "ABC"}Exemple: conversion entre un objet et un JSON
Définissez la classe BagofPrimitives:
classe BagofPrimitives {private int Value1 = 1; Valeur de chaîne privée2 = "ABC"; Private Transient int Value3 = 3; BagofPrimitives () {// NO-ARGS Constructeur}}Sérialisé à JSON:
// serializationbagofPrimitives obj = new BagofPrimitives (); gson gson = new gson (); string json = gson.tojson (obj); // ==> json est {"value1": 1, "value2": "ABC"}Ne sérialisez pas les objets contenant des références circulaires, sinon une récursivité infinie se produira.
Désérialisation:
// DeserializationbagofPrimitives obj2 = gson.fromjson (json, bagofPrimitives.class); // ==> obj2 est comme obj
Quelques détails lors du traitement des objets:
Gestion des classes imbriquées (y compris les classes intérieures)
GSON peut facilement sérialiser les classes imbriquées et désérialiser les classes imbriquées statiques. GSON ne peut pas désérialiser automatiquement les classes intérieures pures car le constructeur sans paramètre de la classe intérieure doit se référer à l'objet qui le contenant (c'est-à-dire les instances de la classe extérieure). Pour désérialiser une classe statique, vous pouvez soit statiquement la classe intérieure ou fournir un créateur d'instance personnalisé. Voici un exemple:
classe publique A {public String a; classe b {String public b; public b () {// no args constructeur pour b}}}La classe B ci-dessus ne peut pas être sérialisée par GSON. Étant donné que la classe B est une classe intérieure (non statique), GSON ne peut pas non plus désérialiser {"B": "ABC"} en une instance de la classe B. Si B est déclaré de classe B statique, alors GSON peut désérialiser la chaîne.
Une autre solution consiste à écrire un créateur d'instance pour b:
classe publique InstanCreatorForb implémente InstanCreator <b> {final privé a a; public instancecreatorforb (a a) {this.a = a; } public ab CreateInstance (type type) {return a.new b (); }}Cette méthode est possible, mais n'est pas recommandée. (Le traducteur a dit qu'il ne comprenait pas ce créateur d'instance et ne savait pas comment l'utiliser)
Exemple: tableau
Gson gson = new gson (); int [] ints = {1, 2, 3, 4, 5}; String [] Strings = {"ABC", "Def", "ghi"}; // serializationgson.tojson (ints); ==> imprime [1,2,3,4,5] gson.tojson (chaînes); ==> imprime ["ABC", "DEF", "GHI"] // DeserializationInt [] ints2 = gson.fromjson ("[1,2,3,4,5]", int []. Class); ==> INTS2 sera identique à INTSGSON prend également en charge les tableaux multidimensionnels avec des types de données complexes.
Exemple: collection
Gson gson = new GSON (); collection <Integer> ints = lists.immutableList (1,2,3,4,5); // serializationsString JSON = gson.tojson (ints); // ==> JSON est [1,2,3,4,5] // DeserializationType CollectionType = new TypeToken <Collection <Integer >> () {}. GetType (); Collection <Integer> ints2 = gson.fromjson (JSON, CollectionType); // INTS2 est le même comme IntsLimites lors du traitement des collections:
Sérialiser / désérialiser les génériques
Lorsque vous utilisez TOJSON (OBJ), GSON appelle obj.getClass () pour obtenir des informations sur le terrain pour une utilisation dans la sérialisation. De même, l'objet MyClass.class peut être passé sous forme de paramètre à la méthode Fromjson (json, myclass.class), qui peut être utilisée lorsque l'objet n'est pas générique. Cependant, lorsque l'objet est un objet de type générique, les informations de type générique seront perdues en raison du mécanisme d'effacement de type en Java. L'exemple suivant illustre ceci:
classe foo <T> {t valeur;} gson gson = new gson (); foo <bar> foo = new foo <bar> (); gson.tojson (foo); // ne peut pas sérialiser foo.value correctementgson.fromjson (json, foo.getClass ()); // ne désérialise pas foo.value comme barreLe code ci-dessus interprète la valeur en tant que type de barre, car GSON appelle foo.getClass () pour obtenir les informations de la classe, mais cette méthode renvoie une classe primitive, à savoir foo.class. Cela signifie que GSON ne peut pas savoir qu'il s'agit d'un objet de type Foo <bar>.
Pour résoudre ce problème, vous pouvez spécifier le type paramétré correct pour vos génériques. Vous pouvez utiliser la classe TypeToken pour faire:
Type FootyTy = new TypeToken <foo <bar>> () {} .getType (); gson.tojson (foo, jouet); gson.fromjson (json, gypet);FEOTYTY définit en fait une classe intérieure anonyme, qui contient une méthode getType () qui peut renvoyer tous les types paramétrés.
Sérialiser / désérialiser une collection d'objets de tout type
Parfois, le JSON transformé contient des types mixtes, tels que:
['Hello', 5, {nom: 'salutations', source: 'invité'}]L'ensemble correspondant doit être:
Collection Collection = New ArrayList (); Collection.Add ("Hello"); Collection.Add (5); Collection.Add (nouvel événement ("salutations", "invité"));La classe d'événements est définie comme suit:
Class Event {Private String Name; source de chaîne privée; événement privé (nom de chaîne, source de chaîne) {this.name = name; this.source = source; }}Avec GSON, vous n'avez rien de spécial pour sérialiser la collection: Tojson (collection) publiera des résultats satisfaisants.
Cependant, la désérialisation à Fromjson (JSON, Collection.class) n'est pas possible, car GSON ne peut pas correspondre au contenu de JSON avec le type. GSON vous oblige à fournir une version commune du type de collection Fromjson. Vous avez trois choix:
Solution 1: Utilisez l'API de l'analyseur GSON (analyser de flux de bas niveau ou analyser DOM JSONParser) pour analyser les éléments du tableau, puis utiliser gson.fromjson () pour traiter chaque élément de tableau. Ceci est la solution préférée.
Schéma 2: Enregistrez un adaptateur de type pour la collection.classe à cartographier les éléments dans le tableau à l'objet approprié. L'inconvénient de cette méthode est qu'il provoquera des inconvénients lorsqu'ils traitent d'autres types de collecte.
Schéma 3: Enregistrez un adaptateur de type pour MyCollectionMemberType et utilisez la collection <MyCollectionMemberType> dans Fromjson. Cette méthode n'est possible que si le tableau ressemble à un élément de haut niveau ou si vous pouvez modifier le type de champ en collection <myCollectionMemberType>.
Sérialiseur / désérialiseur intégré
GSON fournit un sérialiseur / désérialiseur pour les classes couramment utilisées qui peuvent ne pas être appropriées pour la représentation par défaut.
Voici une liste de ces classes:
Sérialisation / désérialisation personnalisée
Parfois, l'implémentation par défaut de GSON n'est pas ce que vous voulez, ce qui est plus courant lorsque vous traitez avec certaines bibliothèques de classe (telles que DateTime).
GSON vous permet d'enregistrer des sérialiseurs / désérialiseurs personnalisés. Pour ce faire, vous devez implémenter les parties suivantes:
Sérialiseur JSON: Besoin de personnaliser la sérialisation pour un objet
JSON Deerializer: vous devez personnaliser le créateur de classe de désérialisation pour un type: s'il y a un constructeur sans paramètre ou un désérialiseur a été enregistré, il n'est pas nécessaire.
Gsonbuilder gson = new gsonBuilder (); gson.registerTypeAdapter (myType2.class, new myTypeAdapter ()); gson.registerTypeAdapter (myType.class, new myserializer ()); gson.registerTypeAdapter (myType.class, new MyDeSerializer ()); gson.registerTypeAdapter (myType.class, new myInstanCreator ());
RegisterTypeAdapter vérifie si l'adaptateur de type implémente plusieurs interfaces et enregistre l'adaptateur de type pour ces interfaces.
Écrivez un sérialiseur
Voici un exemple de personnalisation du sérialiseur pour DateTime:
Classe privée DateTiTeSerializer implémente JSonSerializer <DateTime> {public JSonElement Serialize (DateTime Src, Type TypeOfSrc, JSonSerializationContext Context) {return new JSONPrimitive (src.ToString ()); }}GSON appelle TOJSON () lors de la sérialisation des instances de DateTime.
Écrivez un désérialiseur
L'exemple suivant montre comment rédiger un désérialiseur de la classe DateTime:
classe privée DatetimeDeSerializer implémente JSondeSerializer <DateTime> {public DateTime Deerialize (JsonElement JSON, Type Typeoft, JSondeSerializationContext Context) lève JSONParseException {return new DateTime (json.getasjsonPrimitive (). GetAssString ()); }}Lorsque GSON doit désérialiser une chaîne JSON à un objet DateTime, Fromjson () sera appelé.
Pour les sérialiseurs / désérialiseurs, l'attention doit être accordée à:
Écrivez un créateur d'instance
Lors de la désérialisation d'un objet, GSON doit créer une instance d'une classe. Une classe qui fonctionne bien pendant la sérialisation / désérialisation signifie que cette classe a un constructeur sans paramètres. En règle générale, lorsqu'ils traitent des classes sans constructeurs sans paramètres dans une bibliothèque de classe, un créateur d'instance est requis.
Exemple d'exemple du créateur:
classe privée MoneyInstanCreator implémente InstanCreator <Sone> {public Money CreateInstance (type Type) {return new Money ("1000000", CurrencyCode.USD); }}Créateur d'instance de type paramétré
Parfois, le type à instanciation sera un type paramétré. Dans l'ensemble, comme l'instance réelle est un type primitif, ce n'est pas un problème. Voici un exemple:
Class MyList <T> étend ArrayList <T> {} classe MyListInstanCreator implémente InstanCreator <MyList <? >> {@SuppressWarnings ("Un-momentd") public MyList <?> CreateInstance (Type Type) {// Pas besoin d'utiliser une liste paramétrée car l'instance réelle aura de toute façon le type brut. retourner new MyList (); }}Cependant, vous devez parfois créer des instances basées sur des types paramétrés réels. Dans ce cas, vous pouvez transmettre le paramètre de type à la méthode CreateInstance. Voici un exemple:
classe publique id <T> {classe finale privée <T> classofid; Valeur longue finale privée; public id (class <t> classofid, longue valeur) {this.classofid = classofid; this.value = valeur; }} class idInStanCreator implémente instanCreator <id <? >> {public id <?> CreateInstance (type type) {type [] typarameters = ((paramétriedType) type) .getActualTypeArGuments (); Type idType = typeParameters [0]; // id n'a qu'un seul type paramétré t return id.get ((classe) idType, 0l); }}Dans l'exemple ci-dessus, une instance de la classe ID ne peut pas être créée sans passer le type vrai au type paramétré. Nous pouvons résoudre ce problème en passant le type de paramètre à la méthode. Ici, l'objet type peut être considéré comme une représentation du type paramétré Java d'ID <foo>, et l'instance correspondante doit être liée à ID <foo>. Étant donné que l'ID de classe n'a qu'un seul paramètre de paramètre, nous utilisons GetActualTypeargument () pour renvoyer le 0ème élément du tableau de type, dans cet exemple, foo.class.
Sortie compacte vs belle sortie
La sortie par défaut de JSON dans GSON est au format JSON compact. C'est-à-dire qu'il n'y a pas de personnages Whitespace supplémentaires dans JSON. Par conséquent, il n'y a pas d'espace vierge entre le nom du champ et la valeur du champ, entre les champs et entre les éléments du tableau dans la sortie de JSON. De plus, le champ NULL ne sera pas sorti (Remarque: NULL sera conservé dans les objets de collecte et de tableau).
Si vous souhaitez sortir plus magnifiquement, vous devez utiliser GSONBuilder pour configurer les instances GSON. JSONFormatter n'existe pas dans l'API publique, donc le client ne peut pas configurer les paramètres de sortie par défaut. Maintenant, nous fournissons uniquement JSONPrintformatter, ce qui est par défaut de 80 caractères par ligne, l'indentation utilise 2 caractères et la marge droite est de 4 caractères.
L'exemple suivant montre comment obtenir une instance GSON pour utiliser un JSONPrintformatter au lieu d'utiliser le JSONCompactFormatter par défaut.
Gson gson = new gsonbuilder (). SetPrettypring (). Create (); string jsonOutput = gson.tojson (someObject);
Objet vide
Dans l'implémentation par défaut de GSON, les objets null sont ignorés. Cela peut rendre le format de sortie (qui peut être considéré comme le résultat de la sérialisation) plus serré; Cependant, le client doit définir une valeur par défaut pour cela afin que JSON puisse désérialiser normalement.
Si vous souhaitez faire une série d'instance GSON NULL, vous pouvez:
Gson gson = new gsonBuilder (). Serializenulls (). Create ();
Notez que lors de la sérialisation NULL, un élément JSONNULL sera ajouté à la structure JSONElement. Par conséquent, nous pouvons utiliser cet objet (GSON) dans notre sérialiseur / désérialiseur personnalisé.
Voici un exemple:
classe publique foo {chaîne finale privée s; Final privé int i; public foo () {this (null, 5); } public foo (String s, int i) {this.s = s; this.i = i; }} Gson gson = new gsonbuilder (). Serializenulls (). Create (); foo foo = new foo (); string json = gson.tojson (foo); system.out.println (json); json = gson.tojson (null); system.out.println (json);Sortir:
{"s": null, "i": 5} nullPrise en charge de la version
Vous pouvez utiliser l'annotation @Since pour maintenir plusieurs versions du même objet. Cette annotation peut être utilisée sur les classes et les champs, et sera également prise en charge sur les méthodes à l'avenir. Pour utiliser cette fonctionnalité, vous devez configurer l'instance GSON pour ignorer les champs et les objets supérieurs à un certain numéro de version. Si la version n'est pas définie dans l'objet GSON, tous les champs et classes sont utilisés lors de la sérialisation / désérialisation.
classe publique VersionEdClass {@Since (1.1) Private Final String NewerField; @Since (1.0) String final privé Newfield; champ de chaîne final privé; public versionedClass () {this.newerfield = "newer"; this.newfield = "new"; this.field = "old"; }} VersionedClass versioneDObject = new VersionEdClass (); gson gson = new gsonBuilder (). SetVersion (1.0) .Create (); String JSONOutput = gson.tojson (someObject); System.out.println (jsonoutput); jsonoutput = gson.tojson (someObject); System.out.println (jsonOutput);Sortir:
?
Exclure les champs de la sérialisation / désérialisation
GSON prend en charge l'utilisation de nombreuses méthodes pour supprimer les classes, les champs et les types de champs. Si la méthode suivante ne répond pas à vos besoins, vous pouvez utiliser la méthode de sérialisation / désérialiseur personnalisée.
1. Exclusion du modificateur java
Par défaut, si un champ est déclaré transitoire, le champ est exclu. De plus, si un champ est déclaré statique, ce champ sera également exclu par défaut. Si vous souhaitez inclure certains champs déclarés transitoires, vous pouvez le faire:
import java.lang.reflect.modificier; gson gson = new gsonBuilder () .ExcluseFieldswithModificaires (modificateur.static) .Create ();
Notez que dans la méthode ExcluseFieldsWithModificateurs, vous pouvez utiliser autant de constantes de modificateur que possible. Par exemple:
Gson gson = new gsonBuilder () .ExcluseFieldswithModificateurs (modificateur.static, modificateur.transient, modificateur.vollatile) .Create ();
2. Utilisez le champ @expose pour exclure
Cette fonctionnalité vous permet d'étiqueter des champs spécifiques de la classe afin qu'ils ne soient pas exclus / exclus dans la sérialisation / désérialisation. Pour utiliser cette annotation, vous devez créer un GSON en utilisant un nouveau gsonBuilder (). ExcluseFields withOutExPoseAnNotation (). Create (). L'instance GSON exclura tous les champs de la classe qui ne sont pas marqués par @Expose.
3. Politique d'exclusion définie par l'utilisateur
Si la méthode d'exclusion ci-dessus ne peut pas répondre aux besoins, vous pouvez également personnaliser votre stratégie d'exclusion. Pour plus d'informations, veuillez vous référer à ExclusionStrategy Javadoc.
L'exemple suivant montre comment exclure les champs marqués de @foo et exclure les types de niveau supérieur de classe de chaîne ou de types de champs déclarés:
@Retention (RetentionPolicy.Runtime) @target ({elementType.field}) public @Interface Foo {// Field Tag uniquement Annotation} classe publique SampleObjectFortTest {@foo private final int annotatedField; String Final String privé StringField; Final privé Long Longfield; classe finale privée <?> Clazzfield; public SampleObjectFortTest () {annotedField = 5; StringField = "SomeDefaultValue"; Longfield = 1234; }} classe publique MyExclusionsStrategy implémente exclusionStrategy {private final class <?> typetoSkip; MyExclusionsTrategy privé (classe <?> TypeToSkip) {this.typetoskip = typetoSkip; } public booléen sailskipclass (class <?> Clazz) {return (Clazz == TypeToSkip); } public boolean Sousskipfield (fieldAttributes f) {return f.getAnnotation (foo.class)! = null; }} public static void main (String [] args) {gson gson = new gsonBuilder () .SetExclusionsStrategies (new myExclusionsTrategy (string.class)) .serializenulls () .Create (); SampleObjectFortTest src = new SampleObjectForTest (); String json = gson.tojson (src); System.out.println (JSON); }Sortir:
{"Longfield": 1234}Prise en charge de la dénomination du champ JSON
Certaines stratégies de dénomination de champ prédéfinies de GSON peuvent convertir les noms de champ Java standard (c'est-à-dire la nomenclature de camel, tels que SampleFieldNameInjava) en un nom de champ JSON (c'est-à-dire Sample_field_Name_in_java ou SampleFieldNameInjava). Pour plus d'informations, veuillez vous référer à FieldNamingPolicy.
GSON a également une politique basée sur l'annotation pour permettre aux clients de personnaliser les noms des champs. Dans cette stratégie, si un nom de champ illégal est fourni comme valeur annotée, GSON lancera une exception d'exécution.
L'exemple suivant montre comment utiliser ces deux stratégies de dénomination GSON:
classe privée someObject {@SerializedName ("Custom_naming") String final privé SomeField; chaîne finale privée Someotherfield; public SomeObject (String A, String b) {this.Somefield = a; this.someotherfield = b; }} SomeObject SomeObject = new SomeObject ("First", "Second"); gson gson = new gsonBuilder (). SetFieldnamingPolicy (FieldNamingPolicy.upper_Camel_Case) .Create (); String JsonRepresetation = gson.tojson (SomeObject); System.out.Println (jsonRepresentation);Sortir:
{"Custom_naming": "First", "Someotherfield": "Second"}Si vous souhaitez personnaliser le nom, vous pouvez utiliser l'annotation @SerializedName.
Partage de l'état entre le sérialiseur et le désérialiseur
Parfois, vous devrez partager l'état entre le sérialiseur et le désérialiseur, et vous pouvez utiliser les trois méthodes suivantes pour atteindre votre objectif:
Les deux premières méthodes ne sont pas des filets, le troisième est.
Solution à l'erreur nul d'analyse GSON
Un inconvénient de GSON est qu'il ne peut pas définir le remplacement nul.
Nous ne pouvons que remplacer manuellement le NULL renvoyé par le serveur par lots. Lorsque l'interface normale est définie, le serveur ne sera certainement pas autorisé à retourner null, mais le résultat de l'arrière-plan apparaîtra toujours nul!
Si vous recherchez, il y a une réponse commune,
Gson gson = new gsonBuilder (). Serializenulls (). Create ();
Mais cela ne peut pas résoudre le problème de déséquence, comment le résoudre?
La solution est la suivante:
Gson gson = new gsonbuilder (). RegisterTypeAdapterFactory (new nullstringtoemptyAdapterFactory ()). Create (); // utilisez ensuite le GSON écrit dans la ligne ci-dessus pour sérialiser et désérialiser la classe d'entité typegson.fromjson (json, type); Gson.tojson (type); // nullstringtoempteryadapterfactory. NullStringtoEmpTyAdapterFactory <T> implémente TypeAdapterFactory {@SuppressWarnings ("Unchecked") public <T> typEadapter <T> create (gson gson, typetoken <t> type) {class <t> RawType = (class <t>) type.getRawtype (); if (RawType! = String.class) {return null; } return (typeAdapter <T>) new StringNulladapter (); }} // StringNulladapter Code public class StringNulladapter étend typeadapter <string> {@Override public String read (lecteur JSonReader) lance ioException {// TODO Auto-généré par Stub if (Reader.Peek () == JSontoken.Null) {Reader.nextNull (); retour ""; } return Reader.NextString (); } @Override public void write (JSONWriter Writer, String Value) lève IOException {// TODO Méthode générée automatiquement Stub if (valeur == null) {writer.nullValue (); retour; } writer.value (valeur); }}