Az Opcionális használata Jacksonnal
1. Bemutatkozás
Ebben a cikkben áttekintést adunk a Választható osztályban, majd magyarázzon el néhány problémát, amelyekbe belefuthatunk, ha Jacksonnal használjuk.
Ezt követően bemutatunk egy megoldást, amely Jackson kezelésére készteti Opcionális mintha közönséges semmissé váló tárgyak lennének.
2. A probléma áttekintése
Először vessünk egy pillantást arra, hogy mi történik, amikor megpróbáljuk sorosítani és deszerializálni Opcionális Jacksonnal.
2.1. Maven-függőség
Jackson használatához győződjön meg arról, hogy a legújabb verzióját használjuk:
com.fasterxml.jackson.core jackson-core 2.11.1
2.2. Könyvtárgyunk
Ezután hozzunk létre egy osztályt Könyv, egy közönséget és egyet Választható terület:
nyilvános osztály Könyv {Húr cím; Opcionális alcím; // getterek és beállítók kihagyva}
Tartsd észben, hogy Opcionális nem szabad mezőként használni, és ezt a probléma szemléltetésére tesszük.
2.3. Serializálás
Most példázzuk a Könyv:
Könyvkönyv = új Könyv (); book.setTitle ("Oliver Twist"); book.setSubTitle (Opcionális.of ("A plébános fiú haladása"));
És végül próbáljuk meg egy Jackson használatával sorosítani ObjectMapper:
Karakterlánc eredménye = mapper.writeValueAsString (könyv);
Meglátjuk, hogy a Választható mező nem tartalmazza az értékét, hanem egy beágyazott JSON objektumot, amelynek neve mező ajándék:
{"title": "Oliver Twist", "subTitle": {"jelen": true}}
Bár ez furcsának tűnhet, valójában erre kell számítanunk.
Ebben az esetben, jelen van() nyilvános ismeretterjesztő a Választható osztály. Ez azt jelenti, hogy soros lesz, amelynek értéke: igaz vagy hamis, attól függően, hogy üres-e vagy sem. Ez Jackson alapértelmezett sorosítási viselkedése.
Ha belegondolunk, amit akarunk, az a tényleges értéke felirat sorosítandó mező.
2.4. Deserializáció
Most fordítsuk meg előző példánkat, ezúttal megpróbálva deserializálni egy objektumot Választható. Meglátjuk, hogy most kapunk egy JsonMappingException:
@Test (várható = JsonMappingException.class) public void givenFieldWithValue_whenDeserializing_thenThrowException String bookJson = "{\" title \ ": \" Oliver Twist \ ", \" subTitle \ ": \" foo \ "}"; Könyv eredménye = mapper.readValue (bookJson, Book.class); }
Nézzük meg a verem nyomát:
com.fasterxml.jackson.databind.JsonMappingException: Nem lehet elkészíteni a java.util példányát. Opcionális: nincs String argumentumú konstruktor / gyári módszer a String értékből deserializálni ('The Parish Boy's Progress')
Ennek a viselkedésnek ismét értelme van. Lényegében Jacksonnak olyan konstruktorra van szüksége, amely képes felvenni az értékét felirat érvként. A mi esetünkben nem ez a helyzet Választható terület.
3. Megoldás
Amit akarunk, az az, hogy Jackson egy üreset kezeljen Választható mint nulla, és egy ajándék kezelésére Választható mint az értékét képviselő mező.
Szerencsére ez a probléma megoldódott számunkra. Jacksonnak van egy sor modulja, amelyek a JDK 8 adattípusokkal foglalkoznak Választható.
3.1. Maven Függőség és regisztráció
Először adjuk hozzá a legújabb verziót Maven-függőségként:
com.fasterxml.jackson.datatype jackson-datatype-jdk8 2.9.6
Most csak annyit kell tennünk, hogy regisztráljuk a modult a ObjectMapper:
ObjectMapper mapper = új ObjectMapper (); mapper.registerModule (új Jdk8Module ());
3.2. Serializálás
Most teszteljük. Ha megpróbáljuk sorosítani a Könyv megint látni fogjuk, hogy van egy felirat, szemben a beágyazott JSON-nal:
Könyvkönyv = új Könyv (); book.setTitle ("Oliver Twist"); book.setSubTitle (Opcionális.of ("A plébános fiú haladása")); String serializedBook = mapper.writeValueAsString (könyv); assertThat (from (serializedBook) .getString ("subTitle")) .isEqualTo ("A plébános fiú haladása");
Ha megpróbálunk egy üres könyvet sorosítani, akkor az a nulla:
book.setSubTitle (Opcionális.empty ()); String serializedBook = mapper.writeValueAsString (könyv); assertThat (from (serializedBook) .getString ("subTitle")). isNull ();
3.3. Deserializáció
Most ismételjük meg a deserializációs teszteket. Ha újraolvassuk a Könyvünket, látni fogjuk, hogy már nem kapunk egy JsonMappingException:
Book newBook = mapper.readValue (eredmény, Könyv.osztály); assertThat (newBook.getSubTitle ()). isEqualTo (Opcionális.of ("A plébános fiú haladása"));
Végül ismételjük meg újra a tesztet, ezúttal a nulla. Meglátjuk, hogy még egyszer nem kapunk egy JsonMappingException, és valójában legyen egy üres Választható:
assertThat (newBook.getSubTitle ()). isEqualTo (Opcionális.empty ());
4. Következtetés
Megmutattuk, hogyan lehet kiküszöbölni ezt a problémát a JDK 8 DataTypes modul kihasználásával, bemutatva, hogyan lehet Jackson számára kezelni egy Választható mint nulla, és egy ajándék Választható mint hétköznapi mező.
Ezeknek a példáknak a megvalósítása megtalálható a GitHub oldalon; ez egy Maven-alapú projekt, ezért könnyen futtathatónak kell lennie.