Kuchárska kniha deserializácie spoločnosti Gson

V tejto kuchárskej knihe skúmame rôzne spôsoby, ako unmarshall JSON do objektov Javapomocou populárnej knižnice Gson.

1. Deserializujte JSON na jeden základný objekt

Začnime jednoducho - ideme na unmarshall jednoduchý JSON na objekt Java - Foo:

public class Foo {public int intValue; public String stringValue; // + štandardné implementácie equals a hashCode}

A riešenie:

@Test public void whenDeserializingToSimpleObject_thenCorrect () {String json = "{" intValue ": 1," stringValue ":" one "}"; Foo targetObject = nový Gson (). FromJson (json, Foo.class); assertEquals (targetObject.intValue, 1); assertEquals (targetObject.stringValue, "jedna"); }

2. Deserializujte JSON na generický objekt

Ďalej - definujme objekt pomocou generík:

public class GenericFoo {public T theValue; }

A zrušte zdieľanie niektorých súborov JSON s týmto typom objektu:

@Test public void whenDeserializingToGenericObject_thenCorrect () {Type typeToken = new TypeToken() {} .getType (); Reťazec json = "{" theValue ": 1}"; GenericFoo targetObject = nový Gson (). FromJson (json, typeToken); assertEquals (targetObject.theValue, nové celé číslo (1)); }

3. Deserializujte JSON s extra neznámymi poľami na objekt

Ďalej - poďme rekonštruovať nejaký komplexný JSON, ktorý obsahuje ďalšie, neznáme polia:

@Test public void givenJsonHasExtraValues_whenDeserializing_thenCorrect () {String json = "{" intValue ": 1," stringValue ":" one "," extraString ":" two "," extraFloat ": 2.2}"; Foo targetObject = nový Gson (). FromJson (json, Foo.class); assertEquals (targetObject.intValue, 1); assertEquals (targetObject.stringValue, "jedna"); }

Ako môžeš vidieť, Gson bude neznáme polia ignorovať a jednoducho porovnajte polia, ktoré je schopný.

4. Deserializujte JSON s nezhodnými názvami polí pre objekt

Teraz sa pozrime, ako to robí Gson s reťazcom json obsahujúcim polia, ktoré sa jednoducho nezhodujú s poľami nášho Foo objekt:

@Test public void givenJsonHasNonMatchingFields_whenDeserializingWithCustomDeserializer_thenCorrect () {String json = "{" valueInt ": 7," valueString ":" seven "}"; GsonBuilder gsonBldr = nový GsonBuilder (); gsonBldr.registerTypeAdapter (Foo.class, nový FooDeserializerFromJsonWithDifferentFields ()); Foo targetObject = gsonBldr.create (). FromJson (json, Foo.class); assertEquals (targetObject.intValue, 7); assertEquals (targetObject.stringValue, "sedem"); }

Všimnite si, že sme sa zaregistrovali vlastný deserializátor - toto dokázalo správne analyzovať polia z reťazca json a namapovať ich na naše Foo:

public class FooDeserializerFromJsonWithDifferentFields implements JsonDeserializer {@Override public Foo deserialize (JsonElement jElement, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {JsonObject jObject = jElement.jslj int intValue = jObject.get ("valueInt"). getAsInt (); String stringValue = jObject.get ("valueString"). GetAsString (); vrátiť nové Foo (intValue, stringValue); }}

5. Deserializujte pole JSON na pole objektov Java

Ďalej ideme deserializovať pole json do poľa Java z Foo objekty:

@Test public void givenJsonArrayOfFoos_whenDeserializingToArray_thenCorrect () {String json = "[{" intValue ": 1," stringValue ":" one "}," + "{" intValue ": 2," stringValue ":" dva "}]" "; Foo [] targetArray = nový GsonBuilder (). Create (). FromJson (json, Foo []. Trieda); assertThat (Lists.newArrayList (targetArray), hasItem (new Foo (1, "one")))); assertThat (Lists.newArrayList (targetArray), hasItem (new Foo (2, "two")))); assertThat (Lists.newArrayList (targetArray), nie (hasItem (new Foo (1, "two")))); }

6. Deserializujte pole JSON na kolekciu Java

Ďalej pole JSON priamo do zbierky Java:

@Test public void givenJsonArrayOfFoos_whenDeserializingCollection_thenCorrect () {String json = "[{" intValue ": 1," stringValue ":" one "}, {" intValue ": 2," stringValue ":" two "}]" "; Typ targetClassType = nový TypeToken() {} .getType (); Zbierka targetCollection = nový Gson (). FromJson (json, targetClassType); assertThat (targetCollection, instanceOf (ArrayList.class)); }

7. Deserializácia JSON na vnorené objekty

Ďalej definujeme náš vnorený objekt - FooWithInner:

public class FooWithInner {public int intValue; public String stringValue; verejné InnerFoo innerFoo; public class InnerFoo {public String name; }}

A tu je postup, ako deserializovať vstup obsahujúci tento vnorený objekt:

@Test public void whenDeserializingToNestedObjects_thenCorrect () {String json = "{\" intValue \ ": 1, \" stringValue \ ": \" one \ ", \" innerFoo \ ": {\" name \ ": \" internal \ "}}"; FooWithInner targetObject = nový Gson (). FromJson (json, FooWithInner.class); assertEquals (targetObject.intValue, 1); assertEquals (targetObject.stringValue, "jedna"); assertEquals (targetObject.innerFoo.name, "vnútorné"); }

8. Deserializujte JSON pomocou vlastného konštruktora

Na záver sa pozrime, ako vynútiť použitie konkrétneho konštruktora počas deserializácie namiesto predvoleného použitia - bez použitia konštruktora argumentov InstanceCreator:

public class FooInstanceCreator implementuje InstanceCreator {@Override public Foo createInstance (Type type) {return new Foo ("sample"); }}

A tu je spôsob, ako využiť našu FooInstanceCreator pri deserializácii:

@Test public void whenDeserializingUsingInstanceCreator_thenCorrect () {String json = "{\" intValue \ ": 1}"; GsonBuilder gsonBldr = nový GsonBuilder (); gsonBldr.registerTypeAdapter (Foo.class, new FooInstanceCreator ()); Foo targetObject = gsonBldr.create (). FromJson (json, Foo.class); assertEquals (targetObject.intValue, 1); assertEquals (targetObject.stringValue, "vzorka"); }

Všimnite si, že namiesto hodnoty null slúži znak Foo.stringValue rovná sa vzorka pretože sme použili nasledujúci konštruktor:

public Foo (String stringValue) {this.stringValue = stringValue; }

9. Záver

Tento článok ukazuje, ako využiť knižnicu Gson na analyzovať vstup JSON - prechádzanie najbežnejších prípadov použitia pre jednotlivé aj viac objektov.

Implementácia všetkých týchto príkladov a útržkov kódu nájdete v mojom projekte github - toto je projekt založený na Eclipse, takže by malo byť ľahké ho importovať a spustiť tak, ako je.


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