J'essaie d'apprendre Gson et je lutte contre l'exclusion de terrain. Voici mes cours
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 une ExclusionStrategy pour un nom de champ comme firstName
ou country
mais je n'arrive pas à exclure les propriétés de certains champs comme country.name
.
En utilisant 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
.
PS: Je veux éviter les annotations car je veux améliorer cela et utiliser RegEx pour filtrer les champs.
Edit : j'essaie de voir s'il est possible d'émuler le comportement du plugin Struts2 JSON
en utilisant 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 deuxième champ avec le même type pour clarifier ce problème. Fondamentalement, je veux exclure country.name
mais pas countrOfBirth.name
. Je ne veux pas non plus exclure Country en tant que type. Donc, les types sont les mêmes, c'est la place réelle dans le graphique d'objet que je veux localiser et exclure.
la source
JsonSerializer
pour un certain type -Country
dans votre cas - pour laquelle est ensuite appliqué unExclusionStrategy
qui décide quels champs à sérialiser.Réponses:
Tous les champs que vous ne voulez pas sérialiser en général, vous devez utiliser le modificateur "transitoire", et cela s'applique également aux sérialiseurs json (au moins c'est le cas pour quelques-uns que j'ai utilisés, y compris gson).
Si vous ne voulez pas que le nom apparaisse dans le json sérialisé, donnez-lui un mot-clé transitoire, par exemple:
Plus de détails dans la documentation Gson
la source
transient
au lieu de@Expose
est que vous devez toujours simuler un POJO sur votre client avec tous les champs qui pourraient éventuellement entrer. Dans le cas d'une API principale qui pourrait être partagée entre les projets, cela pourrait être problématique au cas où des champs supplémentaires sont ajoutés. Il s'agit essentiellement d'une liste blanche par rapport à une liste noire des champs.Nishant a fourni une bonne solution, mais il existe un moyen plus simple. Marquez simplement les champs souhaités avec l'annotation @Expose, tels que:
Omettez tous les champs que vous ne souhaitez pas sérialiser. Ensuite, créez simplement votre objet Gson de cette façon:
la source
Donc, vous voulez exclure
firstName
etcountry.name
. Voici à quoiExclusionStrategy
devrait ressembler votreSi vous voyez de près, il revient
true
pourStudent.firstName
etCountry.name
, ce que vous voulez exclure.Vous devez appliquer ceci
ExclusionStrategy
comme ceci,Cela renvoie:
Je suppose que l'objet country est initialisé avec
id = 91L
en classe d'étudiant.Vous pouvez devenir fantaisiste. Par exemple, vous ne voulez sérialiser aucun champ contenant une chaîne "nom" dans son nom. Faites ceci:
Cela reviendra:
EDIT: Ajout d'informations supplémentaires comme demandé.
Cela
ExclusionStrategy
fera l'affaire, mais vous devez passer "Nom de champ entièrement qualifié". Voir ci-dessous:Voici comment nous pouvons l'utiliser de manière générique.
Il renvoie:
la source
country.name
et exclure le champ uniquementname
lors de la sérialisation du champcountry
. Il doit être suffisamment générique pour s'appliquer à chaque classe possédant une propriété nommée country de la classe Country. Je ne veux pas créer une stratégie d'exclusion pour chaque classeAprès avoir lu toutes les réponses disponibles, j'ai découvert que le plus flexible, dans mon cas, était d'utiliser des
@Exclude
annotations personnalisées . Donc, j'ai mis en place une stratégie simple pour cela (je ne voulais pas marquer tous les champs à l'aide@Expose
ni je voulais utilisertransient
qui était en conflit avec laSerializable
sérialisation dans l'application ):Annotation:
Stratégie:
Usage:
la source
addSerializationExclusionStrategy
ouaddDeserializationExclusionStrategy
au lieu desetExclusionStrategies
f.getAnnotation(Exclude.class) != null
àf.getAnnotation(Exclude.class) == null
transient
raison des besoins d'autres bibliothèques. Merci!J'ai rencontré ce problème, dans lequel j'avais un petit nombre de champs que je voulais exclure uniquement de la sérialisation, j'ai donc développé une solution assez simple qui utilise l'
@Expose
annotation de Gson avec des stratégies d'exclusion personnalisées.La seule manière intégrée d'utiliser
@Expose
est de définirGsonBuilder.excludeFieldsWithoutExposeAnnotation()
, mais comme son nom l'indique, les champs sans explicite@Expose
sont ignorés. Comme je n'avais que quelques champs que je voulais exclure, j'ai trouvé la perspective d'ajouter l'annotation à chaque champ très lourde.En fait, je voulais l'inverse, dans lequel tout était inclus, sauf si je l'exclus explicitement
@Expose
. J'ai utilisé les stratégies d'exclusion suivantes pour y parvenir:Maintenant, je peux facilement exclure quelques champs avec
@Expose(serialize = false)
ou des@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 cela est accompli de manière plus concise en déclarant le champ à latransient
place (qui prend toujours effet avec ces stratégies d'exclusion personnalisées).la source
Vous pouvez explorer l'arbre json avec gson.
Essayez quelque chose comme ceci:
Vous pouvez également ajouter certaines propriétés:
Testé avec gson 2.2.4.
la source
J'ai créé une usine de classe pour prendre en charge cette fonctionnalité. Passez n'importe quelle combinaison de champs ou de classes que vous souhaitez exclure.
Pour l'utiliser, créez deux listes (chacune est facultative) et créez votre objet GSON:
la source
J'ai résolu ce problème avec des annotations personnalisées. Voici ma classe d'annotation "SkipSerialisation":
et voici mon GsonBuilder:
Exemple :
la source
@Retention(RetentionPolicy.RUNTIME)
à votre annotation.Ou peut dire quels champs ne seront pas exposés avec:
sur votre classe sur l'attribut:
la source
excludeFieldsWithModifiers()
cela.J'ai utilisé cette stratégie: j'ai exclu chaque champ qui n'est pas marqué avec l' annotation @SerializedName , c'est-à-dire:
Il revient
la source
Une autre approche (particulièrement utile si vous devez prendre la décision d'exclure un champ au moment de l'exécution) consiste à enregistrer un TypeAdapter avec votre instance gson. Exemple ci-dessous:
Dans le cas ci-dessous, le serveur attendrait l'une des deux valeurs, mais comme il s'agissait de deux entiers, gson les sérialiserait tous les deux. Mon objectif était d'omettre toute valeur qui est zéro (ou moins) du json qui est publié sur le serveur.
la source
L'
@Transient
annotation de Kotlin fait aussi apparemment l'affaire.Production:
la source
Je travaille juste en mettant l'
@Expose
annotation, voici ma version que j'utiliseEn
Model
classe:En
Adapter
classe:la source
J'ai la version Kotlin
et comment vous pouvez l'ajouter à Retrofit GSONConverterFactory:
la source
C'est ce que j'utilise toujours:
Le comportement par défaut implémenté dans Gson est que les champs d'objet null sont ignorés.
Signifie que l'objet Gson ne sérialise pas les champs avec des valeurs nulles en JSON. Si un champ dans un objet Java est nul, Gson l'exclut.
Vous pouvez utiliser cette fonction pour convertir un objet en null ou bien défini par vous-même
la source