Použitie voliteľné s Jacksonom

1. Úvod

V tomto článku poskytneme prehľad Voliteľné triedy a potom vysvetlite niektoré problémy, na ktoré by sme mohli naraziť pri použití s ​​Jacksonom.

Potom predstavíme riešenie, ktoré prinúti Jacksona liečiť Voliteľné akoby to boli obyčajné objekty s možnou hodnotou null.

2. Prehľad problémov

Najprv sa pozrime, čo sa stane, keď sa pokúsime serializovať a deserializovať Voliteľné s Jacksonom.

2.1. Maven závislosť

Ak chcete používať Jackson, uistite sa, že používame jeho najnovšiu verziu:

 com.fasterxml.jackson.core jackson-core 2.11.1 

2.2. Objekt našej knihy

Potom vytvorme triedu Rezervovať, obsahujúci jeden obyčajný a jeden Voliteľné lúka:

public class Book {Názov reťazca; Voliteľný podnadpis; // vynechávači a nastavovatelia}

Pamätajte na to Voliteľné by sa nemali používať ako polia a robíme to pre ilustráciu problému.

2.3. Serializácia

Teraz poďme vytvoriť inštanciu a Kniha:

Kniha kniha = nová Kniha (); book.setTitle ("Oliver Twist"); book.setSubTitle (Optional.of ("Pokrok farného chlapca"));

A nakoniec to skúsme serializovať pomocou Jacksona ObjectMapper:

Výsledok reťazca = mapper.writeValueAsString (kniha);

Uvidíme, že výstup z Voliteľné pole neobsahuje jeho hodnotu, ale namiesto toho vnorený objekt JSON s názvom poľa prítomný:

{"title": "Oliver Twist", "subTitle": {"present": true}}

Aj keď to môže vyzerať zvláštne, je to vlastne to, čo by sme mali čakať.

V tomto prípade, je prítomný() je verejný getter na internete Voliteľné trieda. To znamená, že bude serializovaný s hodnotou pravda alebo nepravdivé, podľa toho, či je prázdny alebo nie. Toto je Jacksonove predvolené správanie pri serializácii.

Ak o tom premýšľame, to, čo chceme, je skutočná hodnota podtitul pole, ktoré sa má serializovať.

2.4. Deserializácia

Teraz, poďme obrátiť náš predchádzajúci príklad, tentokrát sa snažme deserializovať objekt na Voliteľné. Uvidíme, že teraz dostaneme a JsonMappingException:

@Test (očakáva sa = JsonMappingException.class) public void givenFieldWithValue_whenDeserializing_thenThrowException String bookJson = "{\" title \ ": \" Oliver Twist \ ", \" subTitle \ ": \" foo \ "}"; Výsledok knihy = mapper.readValue (bookJson, Book.class); } 

Pozrime sa na stopu zásobníka:

com.fasterxml.jackson.databind.JsonMappingException: Nie je možné zostrojiť inštanciu java.util. Voliteľné: žiadna metóda konštruktora / továrenského argumentu reťazca na deserializáciu z hodnoty reťazca („The Parish Boy's Progress“)

Toto správanie má opäť zmysel. V zásade potrebuje Jackson konštruktor, ktorý môže mať hodnotu podtitul ako argument. To nie je prípad nášho Voliteľné lúka.

3. Riešenie

Chceme, aby Jackson zaobchádzal s prázdnou Voliteľné ako nulový, a liečiť darček Voliteľné ako pole predstavujúce jeho hodnotu.

Tento problém bol našťastie pre nás vyriešený. Jackson má sadu modulov, ktoré sa zaoberajú dátovými typmi JDK 8, vrátane Voliteľné.

3.1. Maven závislosť a registrácia

Najskôr pridajme najnovšiu verziu ako závislosť Maven:

 com.fasterxml.jackson.datatype jackson-datatype-jdk8 2.9.6 

Teraz musíme modul zaregistrovať iba u našich ObjectMapper:

ObjectMapper mapovač = nový ObjectMapper (); mapper.registerModule (nový Jdk8Module ());

3.2. Serializácia

Poďme si to otestovať. Ak sa pokúsime serializovať naše Kniha znova objekt, uvidíme, že teraz existuje a podtitul, na rozdiel od vnoreného súboru JSON:

Kniha kniha = nová Kniha (); book.setTitle ("Oliver Twist"); book.setSubTitle (Optional.of ("Pokrok farného chlapca")); Reťazec serializedBook = mapper.writeValueAsString (kniha); assertThat (z (serializedBook) .getString ("subTitle")) .isEqualTo ("Pokrok farného chlapca");

Ak sa pokúsime serializovať prázdnu knihu, bude uložená ako nulový:

book.setSubTitle (Optional.empty ()); Reťazec serializedBook = mapper.writeValueAsString (kniha); assertThat (z (serializedBook) .getString ("subTitle")). isNull ();

3.3. Deserializácia

Teraz si zopakujme naše testy na deserializáciu. Ak si znovu prečítame našu Knihu, uvidíme, že už viac nedostaneme JsonMappingException:

Kniha newBook ​​= mapper.readValue (result, Book.class); assertThat (newBook.getSubTitle ()). isEqualTo (Optional.of ("Pokrok farníka"));

Na záver zopakujeme test ešte raz, tentokrát s nulový. Uvidíme, že opäť nedostaneme a JsonMappingException, a v skutočnosti mať prázdny Voliteľné:

assertThat (newBook.getSubTitle ()). isEqualTo (Optional.empty ());

4. Záver

Ukázali sme, ako tento problém obísť, využitím modulu JDK 8 DataTypes a demonštrujeme, ako umožňuje Jacksonovi zaobchádzať s prázdnym Voliteľné ako nulový, a darček Voliteľné ako obyčajné pole.

Implementáciu týchto príkladov možno nájsť na GitHub; toto je projekt založený na Maven, takže by mal byť ľahko spustiteľný tak, ako je.


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