További Jackson kommentárok

1. Áttekintés

Ez a cikk néhány további megjegyzéssel foglalkozik, amelyekre nem vonatkozott az előző cikk, A Guide to Jackson Annotations - ezek közül héten megyünk keresztül.

2. @JsonIdentityReference

@JsonIdentityReference olyan objektumokra történő hivatkozások testreszabására szolgál, amelyek objektumazonosítókként lesznek sorosítva a teljes POJO-k helyett. A következőkkel együttműködve működik @JsonIdentityInfo kényszeríteni az objektumazonosságok használatát minden sorosításban, eltérően az első alkalom kivételével @JsonIdentityReference hiányzik. Ez a pár annotáció akkor hasznos, ha az objektumok körkörös függőségeivel foglalkozunk. További információkért olvassa el a Jackson - Kétirányú kapcsolat cikk 4. szakaszát.

A használat bemutatása érdekében @JsonIdentityReference, két különböző babosztályt fogunk meghatározni, anélkül és ezzel az annotációval.

A bab nélkül @JsonIdentityReference:

@JsonIdentityInfo (generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class BeanWithoutIdentityReference {private int id; privát karakterlánc neve; // kivitelező, mérőeszközök és beállítók}

A bab használatához @JsonIdentityReference, választjuk a id tulajdonság az objektumazonosság:

@JsonIdentityInfo (generátor = ObjectIdGenerators.PropertyGenerator.class, tulajdonság = "id") @JsonIdentityReference (alwaysAsId = true) nyilvános osztály BeanWithIdentityReference {private int id; privát karakterlánc neve; // kivitelező, mérőeszközök és beállítók}

Az első esetben hol @JsonIdentityReference hiányzik, a babot sorozatosan adják meg annak tulajdonságairól:

BeanWithoutIdentityReference bean = új BeanWithoutIdentityReference (1, "Bean Identity Reference Annotation nélkül"); Karakterlánc jsonString = mapper.writeValueAsString (bab);

A fenti sorosítás kimenete:

{"id": 1, "name": "Bean Identity Reference Annotation nélkül"}

Mikor @JsonIdentityReference használatos, a babot egyszerű identitásként sorosítják:

BeanWithIdentityReference bean = new BeanWithIdentityReference (1, "Bean With Identity Reference Annotation"); Karakterlánc jsonString = mapper.writeValueAsString (bab); assertEquals ("1", jsonString);

3. @JsonAppend

A @JsonAppend annotációval virtuális tulajdonságokat adhat hozzá egy objektumhoz a szokásosakon kívül, amikor az objektum sorosítva van. Erre akkor van szükség, ha az osztálydefiníció megváltoztatása helyett kiegészítő információkat akarunk közvetlenül hozzáadni egy JSON karakterlánchoz. Például kényelmesebb lehet a változat a metaadatok a megfelelő JSON dokumentumhoz, mint hogy további tulajdonságot nyújtson számára.

Tegyük fel, hogy van babunk anélkül @JsonAppend alábbiak szerint:

public class BeanWithoutAppend {private int id; privát karakterlánc neve; // kivitelező, mérőeszközök és beállítók}

Egy teszt megerősíti, hogy a @JsonAppend megjegyzés, a szerializációs kimenet nem tartalmaz információt a kiegészítőről változat ingatlan, annak ellenére, hogy megpróbáljuk hozzáadni a ObjectWriter tárgy:

BeanWithoutAppend bean = új BeanWithoutAppend (2, "Bab annotáció nélkül"); ObjectWriter író = mapper.writerFor (BeanWithoutAppend.class) .withAttribute ("verzió", "1.0"); Karakterlánc jsonString = író.writeValueAsString (bab);

A sorosítási kimenet:

{"id": 2, "name": "Bab annotation hozzáadása nélkül"}

Tegyük fel, hogy van egy babunk, amellyel jegyzetelt @JsonAppend:

@JsonAppend (attrs = {@ JsonAppend.Attr (value = "version")}) public class BeanWithAppend {private int id; privát karakterlánc neve; // kivitelező, mérőeszközök és beállítók}

Az előzőhöz hasonló teszt igazolja, hogy amikor a @JsonAppend annotáció kerül alkalmazásra, a sorozást követően a kiegészítő tulajdonság szerepel:

BeanWithAppend bean = new BeanWithAppend (2, "Bab kiegészítõ kommentárral"); ObjectWriter író = mapper.writerFor (BeanWithAppend.class) .withAttribute ("verzió", "1.0"); Karakterlánc jsonString = író.writeValueAsString (bab);

A sorosítás eredménye azt mutatja, hogy a változat tulajdonság hozzáadva:

{"id": 2, "name": "Bean with annotation", "version": "1.0"}

4. @JsonNaming

A @JsonNaming az annotációt használják a tulajdonságok elnevezési stratégiáinak kiválasztására a sorozatosítás során, felülírva az alapértelmezettet. Használni a érték elemet, megadhatunk bármilyen stratégiát, beleértve az egyediakat is.

Az alapértelmezett mellett, ami LOWER_CAMEL_CASE (például. lowerCamelCase), A Jackson könyvtár további négy beépített ingatlan-elnevezési stratégiát kínál nekünk a kényelem érdekében:

  • KEBAB_CASE: A névelemeket kötőjelek választják el, pl. kebab-tok.
  • LOWER_CASE: Minden betű kisbetű, elválasztó nélkül, pl. kisbetűs.
  • SNAKE_CASE: Minden betű kisbetűs, aláhúzással, mint elválasztókkal a névelemek között, pl. kígyóház.
  • UPPER_CAMEL_CASE: Minden névelem, beleértve az elsőt is, nagybetűvel kezdődik, majd kisbetűket követ, és nincsenek elválasztók, pl. UpperCamelCase.

Ez a példa bemutatja a tulajdonságok sorosítási módját kígyónevek használatával, ahol egy tulajdonság megnevezve babnév sorozatszámú babnév.

Adott egy babdefiníciót:

@JsonNaming (PropertyNamingStrategy.SnakeCaseStrategy.class) public class NamingBean {private int id; private String beanName; // kivitelező, mérőeszközök és beállítók}

Az alábbi teszt azt mutatja, hogy a megadott elnevezési szabály a kívánt módon működik:

NamingBean bab = új NamingBean (3, "Bab elnevezése"); Karakterlánc jsonString = mapper.writeValueAsString (bab); assertThat (jsonString, tartalmazzaString ("babnév"));

A jsonString változó a következő adatokat tartalmazza:

{"id": 3, "bean_name": "Bean elnevezése"}

5. @JsonPropertyDescription

A Jackson könyvtár JSON-sémákat hozhat létre Java-típusokhoz a JSON-séma nevű külön modul segítségével. A séma akkor hasznos, ha meg akarjuk adni a várható kimenetet a Java-objektumok sorosítása során, vagy egy JSON-dokumentumot érvényesítenünk kell a deserializálás előtt.

A @JsonPropertyDescription az annotáció lehetővé teszi egy ember számára olvasható leírás hozzáadását a létrehozott JSON-sémához a leírás terület.

Ez a szakasz az alábbiakban ismertetett babot használja fel a @JsonPropertyDescription:

public class PropertyDescriptionBean {private int id; @JsonPropertyDescription ("Ez a név tulajdonság leírása") privát karakterlánc neve; // szerelők és beállítók}

A JSON séma előállításának módszere a leírás mező az alábbiakban látható:

SchemaFactoryWrapper wrapper = új SchemaFactoryWrapper (); mapper.acceptJsonFormatVisitor (PropertyDescriptionBean.class, burkoló); JsonSchema jsonSchema = burkoló.finalSchema (); Karakterlánc jsonString = mapper.writeValueAsString (jsonSchema); assertThat (jsonString, tartalmazString ("Ez a név tulajdonság leírása"));

Mint láthatjuk, a JSON-séma generálása sikeres volt:

{"type": "object", "id": "urn: jsonschema: com: baeldung: jackson: annotation: extra: PropertyDescriptionBean", "properties": {"name": {"type": "string", " description ":" Ez a név tulajdonság leírása "}," id ": {" type ":" integer "}}}

6. @JsonPOJOBuilder

A @JsonPOJOBuilder annotációval konfigurálható egy készítő osztály egy JSON-dokumentum deserializációjának testreszabására POJO-k helyreállítására, ha a névadási szokás eltér az alapértelmezettől.

Tegyük fel, hogy deszerializálnunk kell a következő JSON karakterláncot:

{"id": 5, "name": "POJO Builder Bean"}

Ezt a JSON forrást fogják használni a POJOBuilderBean:

@JsonDeserialize (builder = BeanBuilder.class) public class POJOBuilderBean {private int identitás; private String beanName; // kivitelező, mérőeszközök és beállítók}

A bab tulajdonságainak megnevezése eltér a JSON karakterlánc mezőinek nevétől. Ez az, ahol @JsonPOJOBuilder megmentésre kerül.

A @JsonPOJOBuilder az annotációt két tulajdonság kíséri:

  • buildMethodName: A no-arg módszer neve, amely a várható bab példányosítására szolgál, miután a JSON mezőket az adott bab tulajdonságaihoz kötötte. Az alapértelmezett név épít.
  • withPrefix: A név előtag a JSON és a bab tulajdonságai közötti automatikus azonosításhoz. Az alapértelmezett előtag a val vel.

Ez a példa a BeanBuilder osztály alatt, amelyet a POJOBuilderBean:

@JsonPOJOBuilder (buildMethodName = "createBean", withPrefix = "construct") nyilvános osztály BeanBuilder {private int idValue; privát String nameValue; public BeanBuilder constructId (int id) {idValue = id; adja vissza ezt; } public BeanBuilder constructName (karakterlánc neve) {nameValue = név; adja vissza ezt; } public POJOBuilderBean createBean () {return new POJOBuilderBean (idValue, nameValue); }}

A fenti kódban konfiguráltuk a @JsonPOJOBuilder nevű építési módszert használni createBean és a konstrukció előtag a megfelelő tulajdonságokhoz.

A @JsonPOJOBuilder A babot a következőképpen írják le és tesztelik:

Karakterlánc jsonString = "{\" id \ ": 5, \" name \ ": \" POJO Builder Bean \ "}"; POJOBuilderBean bab = mapper.readValue (jsonString, POJOBuilderBean.class); assertEquals (5, bab.getIdentity ()); assertEquals ("POJO Builder Bean", bean.getBeanName ());

Az eredmény azt mutatja, hogy egy új adatobjektumot sikeresen újrateremtettek egy JSON-forrásból a tulajdonságok nevének eltérése ellenére.

7. @JsonTypeId

A @JsonTypeId az annotációt arra használják, hogy jelezzék, hogy az annotált tulajdonságot nem a szokásos tulajdonságként, hanem a tipusazonosítóként kell sorosítani, ha a polimorf típusú információkat tartalmazza. Ezt a polimorf metaadatot a deszeriálizálás során ugyanazon altípusú objektumok újrateremtésére használják, mint amilyenek a szerializáció előtt voltak, nem pedig a deklarált szupertípusokat.

Jackson örökségének kezelésével kapcsolatos további információkért lásd: Jackson öröklése 2. szakasza.

Tegyük fel, hogy a bab osztály definíciója a következő:

public class TypeIdBean {private int id; @JsonTypeId privát karakterlánc neve; // kivitelező, mérőeszközök és beállítók}

A következő teszt ezt érvényesíti @JsonTypeId úgy működik, ahogy célja:

mapper.enableDefaultTyping (DefaultTyping.NON_FINAL); TypeIdBean bab = új TypeIdBean (6, "Type Id Bean"); Karakterlánc jsonString = mapper.writeValueAsString (bab); assertThat (jsonString, tartalmazString ("Type Id Bean"));

A sorosítási folyamat kimenete:

["Type Id Bean", {"id": 6}]

8. @JsonTypeIdResolver

A @JsonTypeIdResolver az annotációt egy egyedi típusú identitáskezelő jelölésére használják a szerializációban és a deserializációban. Ez a kezelő felelős a JSON-dokumentumban szereplő Java-típusok és típus-azonosító közötti átalakításért.

Tegyük fel, hogy a következő információkat szeretnénk beágyazni egy JSON karakterláncba, amikor a következő osztályhierarchiával foglalkozunk.

A AbstractBean szuperosztály:

@JsonTypeInfo (use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type") @JsonTypeIdResolver (BeanIdResolver.class) public class AbstractBean {private int id; védett AbstractBean (int id) {this.id = id; } // no-arg konstruktor, getter és setter}

A FirstBean alosztály:

a FirstBean nyilvános osztály kiterjeszti az AbstractBean {String keresztnév; public FirstBean (int id, String name) {szuper (id); setFirstName (név); } // no-arg konstruktor, getter és setter}

A LastBean alosztály:

a LastBean nyilvános osztály kiterjeszti az AbstractBean {String vezetéknév; public LastBean (int id, String name) {szuper (id); setLastName (név); } // no-arg konstruktor, getter és setter}

Ezen osztályok példányait használják a BeanContainer tárgy:

public class BeanContainer {private List bab; // getter és setter}

Láthatjuk, hogy a AbstractBean osztályban van jelölve @JsonTypeIdResolver, jelezve, hogy szokást használ TypeIdResolver annak eldöntése, hogy miként vonják be az altípus adatait a sorosításba, és hogyan használják fel ezeket a metaadatokat fordítva.

Itt van a megoldó osztály a típusinformációk felvételére:

a BeanIdResolver public class kiterjeszti a TypeIdResolverBase {private JavaType superType; @Orride public void init (JavaType baseType) {superType = baseType; } @Orride public Id getMechanism () {return Id.NAME; } @Orride public String idFromValue (Object obj) {return idFromValueAndType (obj, obj.getClass ()); } @Orride public String idFromValueAndType (Object obj, Class subType) {String typeId = null; kapcsoló (subType.getSimpleName ()) {case "FirstBean": typeId = "bab1"; szünet; "LastBean" eset: typeId = "bab2"; } return typeId; } @Orride public JavaType typeFromId (DatabindContext context, String id) {Class subType = null; kapcsoló (id) {case "bab1": subType = FirstBean.class; szünet; case "bab2": subType = LastBean.class; } return context.constructSpecializedType (superType, subType); }}

A két legnevezetesebb módszer a idFromValueAndType és typeFromId, az előbbi megmondja a típusinformációk beépítésének módját a POJO-k sorosítása során, míg az utóbbiak meghatározzák az újra létrehozott objektumok altípusait e metaadatok felhasználásával.

Annak érdekében, hogy a szerializáció és a deserializáció egyaránt jól működjön, írjunk egy tesztet a teljes előrehaladás érvényesítésére.

Először be kell állítanunk egy babtartályt és babosztályokat, majd töltsük fel ezt a tartályt babpéldányokkal:

FirstBean bab1 = új FirstBean (1, "Bab 1"); LastBean bab2 = new LastBean (2, "Bab 2"); Listabab = new ArrayList (); bab.add (bab1); bab.add (bab2); BeanContainer serializedContainer = új BeanContainer (); serializedContainer.setBeans (bab);

Ezután a BeanContainer Az objektum sorosítva van, és megerősítjük, hogy a kapott karakterlánc típusinformációt tartalmaz:

Karakterlánc jsonString = mapper.writeValueAsString (serializedContainer); assertThat (jsonString, tartalmazzaString ("bab1")); assertThat (jsonString, tartalmazzaString ("bab2"));

A sorosítás kimenete az alábbiakban látható:

{"bab": [{"@type": "bab1", "id": 1, "keresztnév": "Bab 1"}, {"@type": "bab2", "id": 2, "vezetéknév ":" Bab 2 "}]}

Ezt a JSON struktúrát arra használják, hogy ugyanazon altípusú objektumokat hozza létre újra, mint a sorozatosítás előtt. A deserializáció megvalósításának lépései:

BeanContainer deserializedContainer = mapper.readValue (jsonString, BeanContainer.class); BeanList = deserializedContainer.getBeans () lista; assertThat (beanList.get (0), instanceOf (FirstBean.class)); assertThat (beanList.get (1), instanceOf (LastBean.class));

9. Következtetés

Ez a bemutató számos kevésbé elterjedt Jackson-feljegyzést ismertetett részletesen. Ezeknek a példáknak és kódrészleteknek a megvalósítása megtalálható egy GitHub projektben.