Pretvorite JSON u mapu pomoću Gsona

1. Uvod

U ovom brzom vodiču naučit ćemo kako pretvoriti JSON niz u Karta koristeći Gson od Googlea.

Vidjet ćemo tri različita pristupa kako bismo to postigli i razgovarali o njihovim prednostima i nedostacima - s nekoliko praktičnih primjera.

2. Prolazeći Karta.razred

Općenito, Gson nudi sljedeći API u svom Gson klasa za pretvaranje JSON niza u objekt:

javni T fromJson (String json, Class classOfT) baca JsonSyntaxException;

Iz potpisa je vrlo jasno da je drugi parametar klasa objekta u koji namjeravamo JSON raščlaniti. U našem bi slučaju to trebalo biti Karta.razred:

Niz jsonString = "{'zaposlenik.ime': 'Bob', 'zaposlenik.plata': 10000}"; Gson gson = novi Gson (); Karta karte = gson.fromJson (jsonString, Map.class); Assert.assertEquals (2, map.size ()); Assert.assertEquals (Double.class, map.get ("staff.salary"). GetClass ());

Ovaj će pristup najbolje pogoditi vrstu vrijednosti za svako svojstvo.

Na primjer, brojevi će biti prisiljeni na Dvostrukos, pravi i lažno u Booleova, i predmeti u LinkedTreeMaps.

Ako postoje duplicirani ključevi, prisila neće uspjeti i bacit će znak JsonSyntaxException.

I, zbog brisanje tipa, nećemo moći konfigurirati ni ovo ponašanje prisile. Dakle, ako trebamo navesti tip ključa ili vrijednosti, trebat će nam drugačiji pristup.

3. Korištenje TypeToken

Da bi se prevladao problem brisanja tipova za generičke tipove, Gson ima preopterećenu verziju API-ja:

javni T fromJson (String json, Type typeOfT) baca JsonSyntaxException;

Možemo konstruirati a Karta sa svojim parametrima tipa koristeći Gsonov TypeToken. The TypeToken klasa vraća instancu ParameterizedTypeImpl koji čuva tip ključa i vrijednosti čak i za vrijeme izvođenja:

Niz jsonString = "{'Bob': {'name': 'Bob Willis'}," + "'Jenny': {'name': 'Jenny McCarthy'}," + "'Steve': {'name': 'Steven Waugh'}} "; Gson gson = novi Gson (); Upišite empMapType = novi TypeToken() {} .getType (); Ime karteEeeeeMap = gson.fromJson (jsonString, empMapType); Assert.assertEquals (3, nameEfficieeMap.size ()); Assert.assertEquals (Employee.class, nameEfficieeMap.get ("Bob"). GetClass ()); 

Sad, ako konstruiramo svoj Karta upišite kao Karta, tada će parser i dalje biti zadan, kao što smo vidjeli u prethodnom odjeljku.

Naravno, ovo se još uvijek vraća natrag Gsonu zbog prisiljavanja primitivnih tipova. Međutim, one se mogu prilagoditi.

4. Korištenje Custom JsonDeserializer

Kad trebamo sitnozrni nadzor nad izgradnjom našeg Karta objekt, možemo implementirati prilagođeni deserijalizator tipa JsonDeserializer.

Da bismo vidjeli primjer, pretpostavimo da naš JSON sadrži ime zaposlenika kao ključ i datum zaposlenja kao vrijednost. Nadalje, pretpostavimo da je format datuma gggg / MM / dd, koji nije standardni format za Gson.

Možemo konfigurirati Gson da drugačije analizira našu kartu, primjenom a JsonDeserijalizator:

javna klasa StringDateMapDeserializer implementira JsonDeserializer {privatni format SimpleDateFormat = novi SimpleDateFormat ("yyyy / MM / dd"); @Override public Map deserialize (JsonElement elem, Type type, JsonDeserializationContext jsonDeserializationContext) {return elem.getAsJsonObject () .entrySet () .stream () .filter (e -> e.getValue (). IsJsonPrimitive (). -> e.getValue (). getAsJsonPrimitive (). isString ()) .collect (Collectors.toMap (Map.Entry :: getKey, e -> formatDate (e.getValue ()))); } private Date formatDate (vrijednost objekta) {try {return format (value.getAsString ()); } catch (ParseException ex) {throw new JsonParseException (ex); }}} 

Sada ga moramo registrirati u GsonBuilder protiv našeg ciljanog tipa Karta> i izradite prilagođeni Gson objekt.

Kad nazovemo odJson API o ovome Gson objekta, raščlanjivač poziva prilagođeni deserijalizator i vraća željeni Karta primjer:

Niz jsonString = "{'Bob': '01.06.2017', 'Jennie': '03.01.2015'}"; Tip tipa = novi TypeToken() {}. getType (); Gson gson = novi GsonBuilder () .registerTypeAdapter (tip, novi StringDateMapDeserializer ()) .create (); Karta empJoiningDateMap = gson.fromJson (jsonString, tip); Assert.assertEquals (2, empJoiningDateMap.size ()); Assert.assertEquals (Date.class, empJoiningDateMap.get ("Bob"). GetClass ()); 

Ova je taktika korisna i kada naša karta može sadržavati heterogene vrijednosti i imamo dobru ideju o tome koliko različitih vrsta vrijednosti može biti tamo.

Da biste saznali više o prilagođenom deserijalizatoru u sustavu Windows Gson, slobodno prođite kroz Gson Deserialization Cookbook.

5. Zaključak

U ovom kratkom članku naučili smo nekoliko načina za izgradnju mape iz niza u JSON-obliku. Također smo razgovarali o pravilnim slučajevima upotrebe za ove varijacije.

Izvorni kod za primjere dostupan je na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found