Gson: Comment exclure des domaines spécifiques de la Sérialisation sans annotations
J'essaie d'apprendre à Gson et j'ai du mal avec le champ de l'exclusion. Voici mes classes
public class Student {
private Long id;
private String firstName = "Philip";
private String middleName = "J.";
private String initials = "P.F";
private String lastName = "Fry";
private Country country;
private Country countryOfBirth;
}
public class Country {
private Long id;
private String name;
private Object other;
}
Je peux utiliser le GsonBuilder et ajouter un ExclusionStrategy pour un nom de champ comme firstName
ou country
mais je n'arrive pas à gérer exclure des propriétés de certains domaines, comme la country.name
.
À l'aide de la méthode public boolean shouldSkipField(FieldAttributes fa)
, FieldAttributes ne contient pas suffisamment d'informations pour faire correspondre le champ avec un filtre comme country.name
.
Je vous serais reconnaissant de toute aide à une solution à ce problème.
P. S: je veux éviter les annotations depuis je veux améliorer sur ce point et utiliser des RegEx pour filtrer les trames.
Merci
Modifier: je suis en train de voir si il est possible d'émuler le comportement de Struts2 JSON plugin
à l'aide de Gson
<interceptor-ref name="json">
<param name="enableSMD">true</param>
<param name="excludeProperties">
login.password,
studentList.*\.sin
</param>
</interceptor-ref>
Edit:
J'ai rouvert la question avec l'ajout suivant:
J'ai ajouté un second champ avec le même type de plus de clarifier ce problème. Fondamentalement, je veux exclure country.name
mais pas countrOfBirth.name
. Aussi, je ne veux pas exclure Pays comme un type.
Si les types sont les mêmes, c'est la place réelle dans l'objet graphique que je veux d'identifier et d'exclure.
- Toujours à partir de la version 2.2, je ne peux pas spécifier un chemin d'accès à exclure. flexjson.sourceforge.net se sent comme une bonne alternative.
- Jetez un oeil sur ma réponse pour un tout à fait une question similaire. Il est basé sur la création d'une coutume
JsonSerializer
pour certains typeCountry
dans votre cas pour ce qui est ensuite appliqué uneExclusionStrategy
qui décide quels sont les champs à sérialiser. - stackoverflow.com/questions/3544919/...
Vous devez vous connecter pour publier un commentaire.
Les champs que vous ne voulez pas sérialisé en général, vous devez utiliser le "transitoire" modificateur, et cela s'applique également aux json sérialiseurs (au moins, il ne à quelques-uns que j'ai utilisé, y compris gson).
Si vous ne voulez pas le nom à afficher dans le json sérialisé donner un transitoire mot-clé, par exemple:
Plus de détails dans la documentation Gson
transient
au lieu de@Expose
est que vous avez encore de se moquer d'un POJO sur votre client avec tous les champs qui pourraient éventuellement venir dans. Dans le cas d'une API qui peut être partagée entre les projets, ce qui pourrait être problématique dans le cas des champs supplémentaires sont ajoutés. Il s'agit essentiellement d'une liste blanche vs la mise en liste noire de domaines.transient
exclut à la fois le champ de la sérialisation, mais aussi ne laissez pas JPA pour traiter le terrain (il ne sera pas géré automatiquement).@Transient
)Nishant une bonne solution, mais il y a un moyen plus facile. Il suffit de marquer les zones de votre choix avec le @Exposer annotation, tels que:
Quitter les zones que vous ne voulez pas sérialiser. Puis il suffit de créer votre Gson objet de cette façon:
how to ... without annotations
. Un:use annotation...
i0.kym-cdn.com/entries/icons/mobile/000/010/277/genius.jpgGsonBuilder
pour cela, donc si vous êtes dans le contrôle du code qui sérialise c'est bien, mais si quelqu'un d'autre sérialise une hiérarchie d'objets, sans jamais savoir que le terrain n'était pas destiné à être sérialisé, et d'utiliser une plainenew Gson()...
Donc, vous voulez exclure
firstName
etcountry.name
. Voici ce que votreExclusionStrategy
devrait ressembler àSi vous voyez de près, il retourne
true
pourStudent.firstName
etCountry.name
, qui est ce que vous voulez exclure.Vous devez appliquer ce
ExclusionStrategy
comme ça,Ce retourne:
Je suppose que les pays de l'objet est initialisé avec
id = 91L
des élèves de la classe.Vous pouvez obtenir la fantaisie. Par exemple, vous ne voulez pas sérialiser un champ qui contient "nom" de la chaîne dans son nom. Ce faire:
Ce sera de retour:
EDIT: Ajouté plus d'info sur demande.
Ce
ExclusionStrategy
va faire la chose, mais vous devez passer "Nom de rubrique Entièrement Qualifié". Voir ci-dessous:Ici est de savoir comment nous pouvons l'utiliser de façon générique.
Il retourne:
country.name
et seulement exlude le domainename
lors de la sérialisation du champcountry
. Il doit être suffisamment générique pour s'appliquer à chaque classe qui possède une propriété nommée pays de la catégorie de personnes de Pays. Je ne veux pas créer un ExclusionStrategy pour chaque classeGsonBuilder
pour cela; mais imaginez maintenant l'autre côté de quelqu'un de la sérialisation de l'Objet de votre par accident - c'est un grand hiérarchie par exemple, et de ne même pas savoir à propos de votre traitement particulier de certains champs, de sorte qu'il utilise une plainenew Gson()...
. Je ne vois pas un moyen d'atteindre cetAprès la lecture de la réponse, j'ai trouvé que la plupart flexible, dans mon cas, était d'utiliser des
@Exclude
annotation. Donc, j'ai mis en place une stratégie simple pour cela (je ne voulais pas marquer tous les champs à l'aide de@Expose
ni je voulais utilisertransient
qui était en conflit avec l'appSerializable
sérialisation) :Annotation:
Stratégie:
Utilisation:
addSerializationExclusionStrategy
ouaddDeserializationExclusionStrategy
au lieu desetExclusionStrategies
f.getAnnotation(Exclude.class) != null
àf.getAnnotation(Exclude.class) == null
transient
parce que d'autres bibliothèques besoins. Merci!Je suis tombé sur cette question, à laquelle j'ai eu un petit nombre de champs que je voulais exclure uniquement à partir de la sérialisation, j'ai donc développé une solution plutôt simple qui utilise Gson de
@Expose
annotation personnalisée avec des stratégies d'élimination.Le seul moyen intégré pour utilisation
@Expose
est par la mise enGsonBuilder.excludeFieldsWithoutExposeAnnotation()
, mais comme le nom l'indique, les champs sans explicite@Expose
sont ignorés. Comme je n'avais que quelques champs je voulais à exclure, j'ai trouvé la perspective de l'ajout de l'annotation de chaque champ est très lourde.J'ai effectivement voulu l'inverse, dans lequel tout a été inclus à moins que j'ai utilisé explicitement
@Expose
à l'exclure. J'ai utilisé la suite de l'exclusion des stratégies pour ce faire:Maintenant je peut facilement exclure un certain nombre de champs avec
@Expose(serialize = false)
ou@Expose(deserialize = false)
annotations (notez que la valeur par défaut pour les deux@Expose
attributs esttrue
). Vous pouvez bien sûr utiliser@Expose(serialize = false, deserialize = false)
, mais c'est plus concise effectue en déclarant le domainetransient
à la place (encore prendre effet avec les stratégies d'élimination).Vous pouvez explorer le json arbre avec gson.
Essayer quelque chose comme cela :
Vous pouvez ajouter quelques propriétés :
Testé avec gson 2.2.4.
Je suis venu avec une fabrique de classe pour prendre en charge cette fonctionnalité. Passer dans n'importe quelle combinaison de champs ou les classes que vous souhaitez exclure.
D'utiliser, de créer deux listes (chacun est en option), et de créer votre GSON objet:
J'ai résolu ce problème avec des annotations personnalisées.
C'est mon "SkipSerialisation" Annotation de classe:
et c'est mon GsonBuilder:
Exemple :
@Retention(RetentionPolicy.RUNTIME)
à votre annotation.Ou peut dire ce champs n'est pas exposera avec:
sur votre classe sur l'attribut:
excludeFieldsWithModifiers()
pour que.J'ai utilisé cette stratégie:
j'exclus tous les champs qui est pas marqué avec @SerializedName annotation, c'est à dire:
Il retourne
Une autre approche (particulièrement utile si vous avez besoin pour prendre une décision d'exclure un champ au moment de l'exécution) est à inscrire un TypeAdapter avec votre gson instance. L'exemple ci-dessous:
Dans le cas ci-dessous, le serveur devrait s'attendre à l'une des deux valeurs, mais puisqu'ils étaient tous deux ints puis gson serait sérialiser les deux. Mon objectif était d'omettre toute valeur est égale à zéro (ou moins) à partir du json qui est publiée sur le serveur.
Kotlin de
@Transient
annotation également fait le truc apparemment.De sortie:
Je travaille juste en mettant le
@Expose
annotation, voici ma version que j'utiliseDans
Model
classe:Dans le
Adapter
classe:J'ai Kotlin version
et comment Vous pouvez l'ajouter à Rénover GSONConverterFactory:
Ce que j'ai toujours utiliser:
Le comportement par défaut mis en œuvre dans Gson, c'est que l'objet null champs sont ignorés.
Signifie Gson l'objet n'a pas sérialiser les champs avec les valeurs null en JSON. Si un champ dans un objet Java est null, Gson l'exclut.
Vous pouvez utiliser cette fonction pour convertir un objet à null ou bien par vos propres