Ako serializovať a deserializovať výpisy s Jacksonom

1. Prehľad

Tento rýchly tutoriál ukáže, ako ovládať cestu Java Enums sú serializované a deserializované s Jacksonom 2.

Hĺbiť sa trochu hlbšie a učiť sa ďalšie super veci, ktoré môžeme urobiť Jackson 2 - pokračujte ďalej k hlavnému výukovému programu Jackson.

2. Ovládanie reprezentácie Enum

Definujme nasledujúci Enum:

verejné enum Vzdialenosť {KILOMETER ("km", 1000), MILE ("míle", 1609,34), METER ("metre", 1), PALCA ("palce", 0,0254), CENTIMETER ("cm", 0,01), MILIMETER ("mm", 0,001); súkromná strunová jednotka; súkromné ​​konečné dvojité metre; súkromná vzdialenosť (reťazcová jednotka, dvojité metre) {this.unit = jednotka; this.meters = metre; } // štandardní zakladatelia a zakladatelia}

3. Serializácia výčtov na JSON

3.1. Predvolené zastúpenie výčtu

V predvolenom nastavení bude Jackson reprezentovať Java Enums ako jednoduchý reťazec - napríklad:

nový ObjectMapper (). writeValueAsString (Distance.MILE);

Výsledkom bude:

„MILE“

Čo by sme chceli dostať, keď to zaraďujeme Enum to JSON Object je dať niečo ako:

{"unit": "míle", "metre": 1609,34} 

3.2. Výčet ako objekt JSON

Počnúc verziou Jackson 2.1.2 je teraz k dispozícii možnosť konfigurácie, ktorá zvládne tento druh znázornenia. To je možné vykonať prostredníctvom @JsonFormat anotácia na úrovni triedy:

@JsonFormat (shape = JsonFormat.Shape.OBJECT) verejné enum vzdialenosť {...}

Toto povedie k požadovanému výsledku pri jeho serializácii enum pre Vzdialenosť.MILE:

{"unit": "míle", "metre": 1609,34}

3.3. Výčty a @JsonValue

Ďalším jednoduchým spôsobom riadenia výstupu zaraďovania pre enum je použitie @JsonValue anotácia na getri:

public enum Distance {... @JsonValue public String getMeters () {return meters; }}

To, čo tu vyjadrujeme, je to getMeters () je skutočné zastúpenie tohto výčtu. Výsledok serializácie bude teda:

1609.34

3.4. Vlastný serializátor pre Enum

Pred Jacksonom 2.1.2 alebo ak je pre enum potrebné ešte viac prispôsobenia, môžeme použiť a Jacksonov vlastný serializátor. Najprv to budeme musieť definovať:

verejná trieda DistanceSerializer rozširuje StdSerializer {public DistanceSerializer () {super (Distance.class); } verejný DistanceSerializer (trieda t) {super (t); } public void serialize (vzdialenosť, generátor JsonGenerator, poskytovateľ SerializerProvider) hodí IOException, JsonProcessingException {generator.writeStartObject (); generator.writeFieldName ("meno"); generator.writeString (distance.name ()); generator.writeFieldName ("jednotka"); generator.writeString (distance.getUnit ()); generator.writeFieldName ("metre"); generator.writeNumber (distance.getMeters ()); generator.writeEndObject (); }}

Teraz použijeme serializátor na triedu, ktorá sa bude serializovať:

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

Čo vedie k:

{"name": "MILE", "unit": "míle", "metre": 1609,34}

4. Deserializácia JSON na Enum

Najskôr definujme a Mesto trieda, ktorá má a Vzdialenosť člen:

verejná trieda Mesto {súkromná Vzdialenosť vzdialenosť; ...}

Ďalej si ukážeme rôzne spôsoby deserializácie reťazca JSON na Enum.

4.1. Predvolené správanie

V predvolenom nastavení bude Jackson na deserializáciu z JSON používať meno Enum.

Napríklad rekonštruuje JSON:

{"distance": "KILOMETER"}

Do a Vzdialenosť. KILOMETER objekt:

Mesto mesto = nový ObjectMapper (). ReadValue (json, City.class); assertEquals (Distance.KILOMETER, city.getDistance ());

4.2. Použitím @JsonValue

Naučili sme sa, ako používať @JsonValue serializovať Enums. Rovnakú anotáciu môžeme použiť aj na deserializáciu. Je to možné, pretože hodnoty Enum sú konštanty.

Najprv použijeme @JsonValue jednou z getrových metód - getMeters ():

public enum Distance {... @JsonValue public double getMeters () {return meters; }}

Teraz je návratová hodnota getMeters () metóda predstavuje objekty Enum. Pri deserializácii vzorka JSON:

{"distance": "0,0254"}

Jackson bude hľadať objekt Enum, ktorý má a getMeters () návratná hodnota 0,0254. V tomto prípade je objekt Vzdialenosť.PALEC:

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

4.3. Použitím @JsonProperty

The @JsonProperty anotácia sa používa v inštanciách výčtu:

verejné enum Vzdialenosť {@JsonProperty ("vzdialenosť v km") KILOMETER ("km", 1 000), @JsonProperty ("vzdialenosť v míľach") MILE ("míle", 1609,34); ...}

Použitím tejto anotácie jednoducho hovoríme Jacksonovi, aby zmapoval hodnotu @JsonProperty k objektu anotovanému touto hodnotou.

V dôsledku vyššie uvedeného vyhlásenia je príkladom reťazca JSON:

{"distance": "vzdialenosť v km"}

Budú mapované do Vzdialenosť. KILOMETER objekt:

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

4.4. Použitím @JsonCreator

Jackson sa odvoláva na metódy anotované pomocou @JsonCreator získať inštanciu priloženej triedy.

Zvážte zastúpenie JSON:

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

Teraz definujme forValues ​​() továrenská metóda s @JsonCreator anotácia:

public enum Distance {@JsonCreator public static Distance forValues ​​(@JsonProperty ("unit") String unit, @JsonProperty ("meters") double meters) {for (Distance distance: Distance.values ​​()) {if (distance.unit. rovná sa (jednotka) && Double.compare (distance.meters, meters) == 0) {spiatočná vzdialenosť; }} return null; } ...}

Všimnite si použitie @JsonProperty anotácia na vytvorenie väzby polí JSON s argumentmi metódy.

Keď potom deserializujeme vzorku JSON, dostaneme výsledok:

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

4.5. Používanie Custom Deserializátor

Ak nie je k dispozícii žiadna z opísaných techník, je možné použiť vlastný deserializátor. Napríklad nemusíme mať prístup k zdrojovému kódu Enum alebo používame staršiu verziu Jacksona, ktorá nepodporuje jednu alebo viac doteraz zahrnutých anotácií.

Podľa nášho článku o vlastnej deserializácii, aby sme mohli deserializovať súbor JSON uvedený v predchádzajúcej časti, začneme vytvorením triedy deserializácie:

public class CustomEnumDeserializer extends StdDeserializer {@Override public Distance deserialize (JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {JsonNode node = jsonParser.getCodec (). readTree (jsonParser) Reťazcová jednotka = node.get ("jednotka"). AsText (); dvojité metre = node.get ("metre"). asDouble (); pre (Distance distance: Distance.values ​​()) {if (distance.getUnit (). equals (unit) && Double.compare (distance.getMeters (), meters) == 0) {return distance; }} return null; }} 

Ďalej použijeme @JsonDeserialize anotácia na Enum, aby ste určili náš vlastný deserializátor:

@JsonDeserialize (using = CustomEnumDeserializer.class) verejný výčet Vzdialenosť {...}

A náš výsledok je:

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

5. Záver

Tento článok ilustroval, ako nad ním získať lepšiu kontrolu procesy serializácie a deserializácie a formáty Java Enums.

Implementáciu všetkých týchto príkladov a útržkov kódu nájdete na GitHub.


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