Hogyan sorozhatjuk le és deserializálhatjuk az enumokat Jackson-szal

1. Áttekintés

Ez a gyors bemutató bemutatja, hogyan lehet irányítani az utat A Java Enums sorosított és deserializált a Jackson 2-vel.

Kicsit mélyebbre ásni és tanulni egyéb jó dolgokat megtehetünk Jackson 2 - folytassa a Jackson fő oktatóanyaggal.

2. Az Enum képviselet ellenőrzése

Határozzuk meg a következő Enum-ot:

nyilvános enum Távolság {KILOMETER ("km", 1000), MILE ("mérföld", 1609.34), MÉRŐ ("méter", 1), INCH ("hüvelyk", 0.0254), CENTIMETER ("cm", 0.01), MILLIMETER ("mm", 0,001); saját vonós egység; privát végső dupla méter; privát távolság (húr egység, dupla méter) {this.egység = mértékegység; ez.mérők = méter; } // szokásos mérőeszközök és beállítók}

3. Az Enums sorosítása a JSON-hoz

3.1. Alapértelmezett Enum ábrázolás

Alapértelmezés szerint Jackson a Java Enums-et egyszerű karakterláncként fogja képviselni - például:

új ObjectMapper (). writeValueAsString (Távolság.MILE);

Ennek eredménye:

"MÉRFÖLD"

Amit szeretnénk kapni, amikor ezt megismételjük JSON-objektum felsorolása valami olyasmit adni, mint:

{"unit": "mérföld", "méter": 1609,34} 

3.2. Enum mint JSON Object

A Jackson 2.1.2-től kezdve van egy konfigurációs lehetőség, amely képes kezelni ezt a fajta ábrázolást. Ez a @JsonFormat osztályozás szintű kommentár:

@JsonFormat (shape = JsonFormat.Shape.OBJECT) nyilvános enum távolság {...}

Ez a kívánt sorozat eredményéhez vezet enum mert Távolság.MÉRFÖLD:

{"unit": "mérföld", "méter": 1609,34}

3.3. Enums és @JsonValue

Egy másik egyszerű módja a kimenet egy enum vezérlésének a @JsonValue kommentár egy getteren:

public enum Távolság {... @JsonValue public String getMeters () {return meter; }}

Amit itt kifejezünk, az az getMeters () ennek az enumnak a tényleges ábrázolása. Tehát a sorosítás eredménye:

1609.34

3.4. Custom Serializer for Enum

A Jackson 2.1.2 előtt, vagy ha még több testreszabásra van szükség az enumhoz, használhatjuk a egyedi Jackson sorosító. Először meg kell határoznunk:

public class A DistanceSerializer kiterjeszti a StdSerializer {public DistanceSerializer () {super (Distance.class); } public DistanceSerializer (t osztály) {super (t); } public void serialize (Távolság, JsonGenerator generátor, SerializerProvider szolgáltató) dobja az IOException, JsonProcessingException {generator.writeStartObject (); generator.writeFieldName ("név"); generator.writeString (távolság.név ()); generator.writeFieldName ("egység"); generator.writeString (távolság.getUnit ()); generator.writeFieldName ("méter"); generator.writeNumber (distance.getMeters ()); generator.writeEndObject (); }}

Mostantól a sorosítót alkalmazzuk a sorosítani kívánt osztályra:

@JsonSerialize (using = DistanceSerializer.class) public enum TypeEnum {...}

Ennek eredményeként:

{"name": "MILE", "unit": "mérföld", "méter": 1609.34}

4. A JSON deserializálása az Enum felé

Először definiáljuk a Város osztály, amelynek van egy Távolság tag:

nyilvános osztály Város {privát Távolság távolság; ...}

Ezután megvitatjuk a JSON karakterlánc Enerré való deserializálásának különböző módjait.

4.1. Alapértelmezett viselkedés

Alapértelmezés szerint Jackson az Enum nevet használja a JSON-tól való deszerializációra.

Például deserializálja a JSON-t:

{"távolság": "KILOMETER"}

A Távolság. Kilométer tárgy:

City city = new ObjectMapper (). ReadValue (json, City.class); assertEquals (Távolság.KILOMETER, city.getDistance ());

4.2. Használata @JsonValue

Megtanultuk a használatát @JsonValue hogy sorosítsa az Enumst. Ugyanezt az annotációt használhatjuk a deserializációhoz is. Ez azért lehetséges, mert az Enum értékek konstansok.

Először is használjuk @JsonValue az egyik getter módszerrel - getMeters ():

public enum Távolság {... @JsonValue public double getMeters () {return meter; }}

Most a visszatérési értéke getMeters () metódus az Enum objektumokat reprezentálja. Így a minta JSON deserializálásakor:

{"távolság": "0,0254"}

Jackson megkeresi az Enum objektumot, amelynek van getMeters () visszatérési értéke 0,0254. Ebben az esetben az objektum az Távolság.HÜVELYK:

assertEquals (Távolság.INCH, city.getDistance ()); 

4.3. Használata @JsonProperty

A @JsonProperty a feliratozást felsorolási példányokon használják:

public enum Távolság {@JsonProperty ("távolság km-ben") KILOMETER ("km", 1000), @JsonProperty ("távolság-mérföldben") MILE ("mérföld", 1609,34); ...}

Ennek a kommentárnak a használatával egyszerűen azt mondjuk Jacksonnak, hogy térképezze fel a @JsonProperty az ezzel az értékkel feljegyzett objektumra.

A fenti deklaráció eredményeként a példa JSON karakterlánc:

{"távolság": "távolság km-ben"}

Feltérképezésre kerül a Távolság. Kilométer tárgy:

assertEquals (Távolság.KILOMETER, city.getDistance ());

4.4. Használata @JsonCreator

Jackson a jegyzetekkel ellátott módszerekre hivatkozik @JsonCreator hogy a záróosztály példányát megkapjuk.

Tekintsük a JSON képviseletet:

{"távolság": {"mértékegység": "mérföld", "méter": 1609,34}}

Most definiáljuk a forValues ​​() gyári módszer a @JsonCreator kommentár:

public enum Távolság {@JsonCreator public static Distance forValues ​​(@JsonProperty ("unit") String unit, @JsonProperty ("meters") double meters) {for (Távolság távolság: Távolság.értékek ()) {if (távolság.egység. egyenlő (egység) && Dupla.összehasonlítás (távolság.mérő, méter) == 0) {visszatérési távolság; }} return null; } ...}

Vegye figyelembe a @JsonProperty megjegyzés, hogy a JSON mezőket a metódus argumentumokkal kösse össze.

Ezután, amikor deszerializáljuk a JSON mintát, megkapjuk az eredményt:

assertEquals (Távolság.MILE, city.getDistance ());

4.5. Egyéni használata Deserializer

Egyéni deserializáló használható, ha a leírt technikák egyike sem áll rendelkezésre. Például előfordulhat, hogy nincs hozzáférésünk az Enum forráskódjához, vagy használhatunk egy régebbi Jackson verziót, amely nem támogatja az eddig lefedett egy vagy több feljegyzést.

Egyéni deserializációs cikkünk szerint az előző szakaszban megadott JSON deserializálása érdekében a deserializációs osztály létrehozásával kezdjük:

public class CustomEnumDeserializer kiterjeszti a StdDeserializer {@Override public Distance deserialize (JsonParser jsonParser, DeserializationContext ctxt) dobja az IOException, JsonProcessingException {JsonNode node = jsonParser.getCree ((). Karakterlánc egység = csomópont.get ("egység"). AsText (); dupla méter = csomópont.get ("méter"). asDupla (); for (Távolság távolság: Távolság.értékek ()) {if (távolság.getUnit (). egyenlő (egység) && Double.compare (távolság.getMeters (), méter) == 0) {visszatérési távolság; }} return null; }} 

Ezután a @JsonDeserialize annotáció az Enum-on az egyedi deserializer megadásához:

@JsonDeserialize (using = CustomEnumDeserializer.class) public enum Távolság {...}

Eredményünk pedig:

assertEquals (Távolság.MILE, city.getDistance ());

5. Következtetés

Ez a cikk bemutatta, hogyan lehet jobb irányítást szerezni a Java Enums sorosítási és deszerializációs folyamatai és formátumai.

Ezen példák és kódrészletek megvalósítása megtalálható a GitHub-on.