web-dev-qa-db-fra.com

Convertir les noms des propriétés de style JSON en Java noms CamelCase avec GSON

J'utilise GSON pour convertir les données JSON que j'obtiens en Java objet. Cela fonctionne plutôt bien dans tous mes tests . Le problème est que nos objets réels ont des propriétés nommées comme is_online. GSON ne les mappe que s'ils sont nommés totalement égaux, ce serait bien d'avoir GSON convertir les noms en Java cas de chameau isOnline .

Il semble que cela soit possible lors de la création des données JSON, la casse de chameau est convertie en mots séparés séparés par un soulignement dans JSON. Mais je ne peux pas trouver un moyen de spécifier cela dans l'autre sens.

90
Janusz

J'ai trouvé que le paramètre suivant fonctionne parfaitement lors de la lecture de json avec des attributs soulignés et de l'utilisation de camelcasing dans mes modèles.

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .create()
279
Hampei

Vous pouvez utiliser l'annotation SerializedName :

@SerializedName("field_name_in_json")
private final String fieldNameInJava;

Remarque: Lorsque vous avez déjà défini un FieldNamingPolicy, SerializedName écrasera ses paramètres pour ce champ spécifique (assez pratique pour les cas spéciaux).

85
saschoar

Gardez à l'esprit que votre exemple est un cas Edge. Si vous avez une propriété 'foo', son getter doit être nommé 'getFoo', et si vous avez une propriété nommée 'foo_bar', son getter doit être nommé 'getFooBar', cependant, dans votre exemple, vous mappez un booléen et les booléens ont conventions de dénomination des cas spéciaux en Java. Une propriété booléenne primitive nommée en ligne doit avoir un getter nommé 'isOnline', PAS 'getOnline' ou pire encore, 'getIsOnline'. Un objet wrapper booléen (c'est-à-dire booléen) ne doit pas suivre ce cas spécial et une propriété nommée 'online' doit avoir un getter nommé 'getOnline'.

Par conséquent, avoir des propriétés booléennes avec 'is' dans le nom est un cas Edge, où vous voudrez supprimer ce préfixe particulier lors de votre conversion. Dans le sens inverse, votre code peut vouloir inspecter l'objet json à la fois pour un nom de propriété brute ainsi qu'une version "is_XXX".

2
Jherico

Je pense que ce que vous voulez c'est ici . En utilisant des annotations, vous pouvez dire à GSON que mySuperCoolField est en fait appelé this_field_is_fun dans le JSON et qu'il le décompressera correctement. Au moins, je pense que cela fonctionne aussi pour la désérialisation.

Si cela ne fonctionne pas, vous pouvez utiliser JsonSerializer/JsonDeserializers personnalisés, qui fonctionnent très bien, mais vous devez les mettre à jour pour les changements dans votre classe (comme lorsque vous ajoutez un champ). Vous perdez l'auto-magie.

La chose la plus simple à faire (ce qui serait laid, mais très propre et simple si la première suggestion ne fonctionne pas) serait de simplement nommer le champ de manière à faire plaisir à GSON, et d'ajouter des méthodes d'accesseur supplémentaires avec les noms que vous aimez , par exemple.

public boolean isXXX() {return this.is_XXX;}
2
MBCook