1. Introduzione
In questo breve tutorial, impareremo come convertire una stringa JSON in una mappa utilizzando Gson di Google .
Vedremo tre diversi approcci per ottenere ciò e discuteremo i loro pro e contro, con alcuni esempi pratici.
2. Passaggio di Map.class
In generale, Gson fornisce la seguente API nella sua classe Gson per convertire una stringa JSON in un oggetto :
public T fromJson(String json, Class classOfT) throws JsonSyntaxException;
Dalla firma, è molto chiaro che il secondo parametro è la classe dell'oggetto che intendiamo analizzare con il JSON. Nel nostro caso, dovrebbe essere Map.class :
String jsonString = "{'employee.name':'Bob','employee.salary':10000}"; Gson gson = new Gson(); Map map = gson.fromJson(jsonString, Map.class); Assert.assertEquals(2, map.size()); Assert.assertEquals(Double.class, map.get("employee.salary").getClass());
Questo approccio farà la sua migliore ipotesi per quanto riguarda il tipo di valore per ogni proprietà.
Ad esempio, i numeri verranno convertiti in Double s, true e false in Boolean e gli oggetti in LinkedTreeMap s.
Se sono presenti chiavi duplicate, tuttavia, la coercizione fallirà e genererà un'eccezione JsonSyntaxException.
E, a causa della cancellazione del tipo, non saremo in grado di configurare nemmeno questo comportamento di coercizione. Quindi, se dobbiamo specificare i tipi di chiave o valore, avremo bisogno di un approccio diverso.
3. Utilizzo di TypeToken
Per superare il problema della cancellazione del tipo per i tipi generici, Gson ha una versione sovraccarica dell'API :
public T fromJson(String json, Type typeOfT) throws JsonSyntaxException;
Possiamo costruire una mappa con i suoi parametri di tipo usando TypeToken di Gson . La classe TypeToken restituisce un'istanza di ParameterizedTypeImpl che conserva il tipo di chiave e valore anche in fase di esecuzione :
String jsonString = "{'Bob' : {'name': 'Bob Willis'}," + "'Jenny' : {'name': 'Jenny McCarthy'}, " + "'Steve' : {'name': 'Steven Waugh'}}"; Gson gson = new Gson(); Type empMapType = new TypeToken
Ora, se noi costruiamo la nostra mappa tipo Map , allora il parser sarà ancora di default come abbiamo visto nel paragrafo precedente.
Naturalmente, questo ricade ancora su Gson per costringere i tipi primitivi. Anche quelli, tuttavia, possono essere personalizzati.
4. Utilizzo di JsonDeserializer personalizzato
Quando abbiamo bisogno di un controllo granulare sulla costruzione del nostro oggetto Map , possiamo implementare un deserializzatore personalizzato di tipo JsonDeserializer.
Per vedere un esempio, supponiamo che il nostro JSON contenga il nome del dipendente come chiave e la data di assunzione come valore. Inoltre, supponiamo che il formato della data sia aaaa / MM / gg , che non è un formato standard per Gson .
Possiamo configurare Gson per analizzare la nostra mappa in modo diverso, quindi, implementando un JsonDeserializer:
public class StringDateMapDeserializer implements JsonDeserializer
Ora dobbiamo registrarlo in GsonBuilder contro il nostro tipo di destinazione Map
Quando chiamiamo l' API fromJson su questo oggetto Gson , il parser richiama il deserializzatore personalizzato e restituisce l' istanza Map desiderata :
String jsonString = "{'Bob': '2017-06-01', 'Jennie':'2015-01-03'}"; Type type = new TypeToken
Questa tattica è utile anche quando la nostra mappa può contenere valori eterogenei e abbiamo una buona idea di quanti diversi tipi di valori potrebbero esserci.
Per ulteriori informazioni su un deserializzatore personalizzato in Gson , non esitare a consultare il libro di ricette sulla deserializzazione di Gson .
5. conclusione
In questo breve articolo, abbiamo imparato diversi modi per costruire una mappa da una stringa in formato JSON. E abbiamo anche discusso i casi d'uso appropriati per queste variazioni.
Il codice sorgente per gli esempi è disponibile su GitHub.