Kako serizirati i deseseralizirati enume s Jacksonom

1. Pregled

Ovaj će brzi vodič pokazati kako kontrolirati put Java Enumi su serijski i deserijalizirani s Jackson 2.

Kopati malo dublje i učiti druge cool stvari koje možemo učiniti Jackson 2 - krenite prema glavnom Jacksonovom vodiču.

2. Kontrola zastupanja Enum

Definirajmo sljedeći Enum:

javni popis Udaljenost {KILOMETAR ("km", 1000), MILE ("milje", 1609,34), METER ("metri", 1), INCH ("inči", 0,0254), CENTIMETAR ("cm", 0,01), MILIMETAR ("mm", 0,001); privatna string jedinica; privatni završni dvostruki metri; privatna udaljenost (niz jedinica, dvostruka brojila) {this.unit = jedinica; this.meters = metri; } // standardni getteri i postavljači}

3. Serijaliziranje enuma u JSON

3.1. Zadani prikaz Enum

Jackson će prema zadanim postavkama Java Enums predstavljati kao jednostavni niz - na primjer:

novi ObjectMapper (). writeValueAsString (Udaljenost.MILE);

Rezultat će:

"MILJA"

Što bismo željeli dobiti prilikom marširanja ovoga Enum za JSON objekt je dati nešto poput:

{"jedinica": "milje", "metri": 1609,34} 

3.2. Enum kao JSON objekt

Počevši od Jacksona 2.1.2, sada postoji opcija konfiguracije koja se može nositi s ovom vrstom predstavljanja. To se može učiniti putem @JsonFormat napomena na razini predavanja:

@JsonFormat (shape = JsonFormat.Shape.OBJECT) public enum Udaljenost {...}

To će dovesti do željenog rezultata kada se ovo serializira nabrajanje za Udaljenost.MILJA:

{"jedinica": "milje", "metri": 1609,34}

3.3. Enum i @JsonValue

Još jedan jednostavan način kontrole marširanja rezultata za nabrajanje je upotreba @JsonValue napomena na geteru:

public enum Udaljenost {... @JsonValue public String getMeters () {return metri; }}

Ono što ovdje izražavamo je to getMeters () je stvarni prikaz ovog popisa. Dakle, rezultat serializacije bit će:

1609.34

3.4. Prilagođeni serilizator za Enum

Prije Jacksona 2.1.2 ili ako je za nabrajanje potrebno još više prilagođavanja, možemo koristiti prilagođeni Jackson serializer. Prvo ćemo ga morati definirati:

javna klasa DistanceSerializer proširuje StdSerializer {javni DistanceSerializer () {super (Distance.class); } javni DistanceSerializer (klasa t) {super (t); } public void serialize (Udaljenost udaljenosti, generator JsonGenerator, dobavljač SerializerProvider) baca IOException, JsonProcessingException {generator.writeStartObject (); generator.writeFieldName ("ime"); generator.writeString (distance.name ()); generator.writeFieldName ("jedinica"); generator.writeString (distance.getUnit ()); generator.writeFieldName ("metri"); generator.writeNumber (distance.getMeters ()); generator.writeEndObject (); }}

Sada ćemo primijeniti serializator na klasu koja će biti serializirana:

@JsonSerialize (koristeći = DistanceSerializer.class) javni popis TypeEnum {...}

Što rezultira:

{"name": "MILE", "unit": "miles", "metri": 1609.34}

4. Deserijalizacija JSON-a na Enum

Prvo, definirajmo a Grad razred koji ima Udaljenost član:

javni razred Grad {privatna udaljenost Udaljenost; ...}

Dalje ćemo razgovarati o različitim načinima deserializacije JSON niza na Enum.

4.1. Zadano ponašanje

Prema zadanim postavkama, Jackson će koristiti ime Enum za deserializaciju iz JSON-a.

Na primjer, deserijalizirat će JSON:

{"distance": "KILOMETER"}

Za a Udaljenost.KILOMETAR objekt:

City city = novi ObjectMapper (). ReadValue (json, City.class); assertEquals (Udaljenost.KILOMETER, city.getDistance ());

4.2. Koristeći @JsonValue

Naučili smo kako koristiti @JsonValue za serializaciju Enuma. Istu napomenu možemo koristiti i za deserializaciju. To je moguće jer su vrijednosti Enum konstante.

Prvo, poslužimo se @JsonValue s jednom od metoda dobivanja - getMeters ():

public enum Udaljenost {... @JsonValue public double getMeters () {return metri; }}

Sada, povratna vrijednost getMeters () metoda predstavlja Enum objekte. Dakle, prilikom deserializacije uzorka JSON:

{"distance": "0,0254"}

Jackson će potražiti Enum objekt koji ima getMeters () povratna vrijednost od 0,0254. U ovom slučaju objekt je Udaljenost.INCH:

assertEquals (Udaljenost.INCH, city.getDistance ()); 

4.3. Koristeći @JsonProperty

The @JsonProperty anotacija se koristi na primjerima popisivanja:

javni popis Udaljenost {@JsonProperty ("udaljenost-u-kilometru") KILOMETER ("km", 1000), @JsonProperty ("udaljenost-u-miljama") MILE ("milje", 1609,34); ...}

Korištenjem ove bilješke, mi jednostavno kažemo Jacksonu da mapira vrijednost @JsonProperty na objekt označen ovom vrijednošću.

Kao rezultat gornje deklaracije, primjer JSON niza:

{"distance": "udaljenost-u-km"}

Bit će preslikana na Udaljenost.KILOMETAR objekt:

assertEquals (Udaljenost.KILOMETER, city.getDistance ());

4.4. Koristeći @JsonCreator

Jackson poziva metode označene s @JsonCreator kako bi dobili instancu klase koja obuhvaća.

Razmotrite JSON predstavu:

{"distance": {"unit": "miles", "metri": 1609.34}}

Sada, definirajmo zaVrijednosti () tvornička metoda s @JsonCreator napomena:

public enum Udaljenost {@JsonCreator javna statička udaljenost zaVrijednosti (@JsonProperty ("unit") Niz jedinica, @JsonProperty ("metri") dupla metra) {for (Udaljenost udaljenost: Distance.values ​​()) {if (distance.unit. jednako (jedinica) && Double.compare (distance.meters, metri) == 0) {return distance; }} return null; } ...}

Obratite pažnju na upotrebu @JsonProperty napomena za povezivanje JSON polja s argumentima metode.

Zatim, kad deserializiramo JSON uzorak, dobit ćemo rezultat:

assertEquals (Distance.MILE, city.getDistance ());

4.5. Korištenje prilagođenog Deserijalizator

Prilagođeni deserializator može se koristiti ako nijedna od opisanih tehnika nije dostupna. Na primjer, možda nemamo pristup izvornom kodu Enuma ili koristimo stariju Jackson verziju koja ne podržava jednu ili više do sada obrađenih bilješki.

Prema našem prilagođenom članku o deserializaciji, kako bismo deserializirali JSON naveden u prethodnom odjeljku, započet ćemo stvaranjem klase deserializacije:

javna klasa CustomEnumDeserializer proširuje StdDeserializer {@Override javna udaljenost deserializira (JsonParser jsonParser, DeserializationContext ctxt) baca IOException, JsonProcessingException {JsonNode node = jsonParser.getCodec (); Niz jedinica = node.get ("jedinica"). AsText (); dvostruki metri = node.get ("metri"). asDouble (); for (Udaljenost udaljenosti: Udaljenost.vrijednosti ()) {if (distance.getUnit (). jednako (jedinica) && Double.compare (distance.getMeters (), metri) == 0) {return distance; }} return null; }} 

Dalje koristimo @JsonDeserialize napomena na Enumu za specificiranje našeg prilagođenog deserijalizatora:

@JsonDeserialize (using = CustomEnumDeserializer.class) public enum Udaljenost {...}

A naš rezultat je:

assertEquals (Distance.MILE, city.getDistance ());

5. Zaključak

Ovaj je članak ilustrirao kako steći bolju kontrolu nad procesi serializacije i deserializacije i formati Java Enumsa.

Provedbu svih ovih primjera i isječaka koda možete pronaći na GitHubu.


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