Converti i nomi delle proprietà di stile JSON in nomi Java CamelCase con GSON


107

Sto usando GSON per convertire i dati JSON che ottengo in un oggetto Java. Funziona abbastanza bene in tutti i miei test. Il problema è che i nostri oggetti reali hanno alcune proprietà chiamate is_online. GSON li mappa solo se sono denominati totalmente uguali, sarebbe bello che GSON convertisse i nomi in Java camel case isOnline.

Sembra che ciò sia possibile durante la creazione dei dati JSON, il caso del cammello viene convertito in parole separate da trattini bassi in JSON. Ma non riesco a trovare un modo per specificarlo al contrario.


5
Proporrei di accettare una risposta
JeanValjean

Risposte:


313

Ho riscontrato che la seguente impostazione funziona perfettamente durante la lettura di json con attributi sottolineati e l'utilizzo di camelcasing nei miei modelli.

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

2
Ottima risposta, grazie! @janusz, se una di queste risposte ti ha aiutato, contrassegnala come Risposta accettata.
sufinawaz

1
Se hai un caso in cui il nome contiene due trattini bassi, ignora il primo trattino basso. Ex. this_key_has__two_underscores verrà convertito in thisKeyHas_TwoUnderscores e lo stesso viceversa. Il punto chiave è il FieldNamingPolicy dove l'enum dice "minuscolo" con trattini bassi mentre qui il nome convertito ha un maiuscolo con trattino basso (_T).
Deepak GM

Molto semplice, mi evita di dover annotare un mucchio di campi!
William T. Mallard,

99

Puoi usare l' SerializedNameannotazione:

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

Nota: quando hai già impostato un FieldNamingPolicy, SerializedNamesovrascriverà le sue impostazioni per quel campo specifico (abbastanza utile per casi speciali).


2

Tieni presente che il tuo esempio è un caso limite. Se hai una proprietà 'foo', il suo getter dovrebbe essere chiamato 'getFoo', e se hai una proprietà chiamata 'foo_bar' il suo getter dovrebbe essere chiamato 'getFooBar', tuttavia, nel tuo esempio stai mappando un booleano e un booleano hanno convenzioni di denominazione per casi speciali in java. Una proprietà booleana primitiva denominata online dovrebbe avere un getter denominato "isOnline", NON "getOnline" o, peggio ancora, "getIsOnline". Un oggetto wrapper booleano (cioè Boolean) non dovrebbe seguire questo caso speciale e una proprietà denominata "online" dovrebbe avere un getter denominato "getOnline".

Quindi, avere proprietà booleane con "è" nel nome è un caso limite, in cui ti consigliamo di eliminare questo particolare prefisso durante la conversione. Nella direzione opposta, il codice potrebbe voler ispezionare l'oggetto json sia per un nome di proprietà non elaborato che per una versione "is_XXX".


2

Penso che quello che vuoi sia qui . Usando le annotazioni puoi dire a GSON che mySuperCoolField è effettivamente chiamato this_field_is_fun nel JSON e lo decomprimerà correttamente. Almeno penso che funzioni anche per la deserializzazione.

Se non funziona, puoi utilizzare JsonSerializer / JsonDeserializer personalizzati, che funzionano alla grande, ma devi aggiornarli per le modifiche nella tua classe (come quando aggiungi un campo). Perdi l'auto-magia.

La cosa più semplice da fare (che sarebbe brutta, ma molto pulita e semplice se il primo suggerimento non funziona) sarebbe semplicemente nominare il campo in modo da rendere felice GSON e aggiungere metodi di accesso extra con i nomi che ti piacciono , per esempio

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

la cosa facile è quello che sto facendo in questo momento e funziona benissimo. Tutto il codice in stile java brutto e non tipico è nascosto nelle classi di dati e nessuno lo vedrà dall'esterno. Ma mi sta ancora tormentando un po ':)
Janusz
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.