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.