Jackson Annotation-voorbeelden

1. Overzicht

In deze tutorial gaan we dieper in op Jackson-aantekeningen.

We zullen zien hoe u de bestaande annotaties kunt gebruiken, hoe u aangepaste annotaties kunt maken en ten slotte hoe u ze kunt uitschakelen.

2. Jackson-serialiseringsaantekeningen

Eerst kijken we naar de serialiseringsannotaties.

2.1. @Jonvaneerd

De @Jonvaneerd annotatie zorgt voor de flexibiliteit van het gebruik van een Kaart veld als standaardeigenschappen.

Bijvoorbeeld de Uitschuifbaar Bean entiteit heeft de naam eigenschap en een set uitbreidbare attributen in de vorm van sleutel / waarde-paren:

openbare klasse ExtendableBean {openbare tekenreeksnaam; particuliere kaarteigenschappen; @JsonAnyGetter openbare kaart getProperties () {retourneer eigenschappen; }}

Wanneer we een instantie van deze entiteit serialiseren, krijgen we alle sleutelwaarden in het Kaart standaard, effen eigenschappen:

{"name": "My bean", "attr2": "val2", "attr1": "val1"}

Hier ziet u hoe de serialisatie van deze entiteit er in de praktijk uitziet:

@Test openbare leegte whenSerializingUsingJsonAnyGetter_thenCorrect () gooit JsonProcessingException {ExtendableBean bean = new ExtendableBean ("My bean"); bean.add ("attr1", "val1"); bean.add ("attr2", "val2"); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (bean); assertThat (resultaat, bevatString ("attr1")); assertThat (resultaat, bevatString ("val1")); }

We kunnen ook het optionele argument gebruiken ingeschakeld net zo false uitschakelen @JsonAnyGetter (). In dit geval is het Kaart wordt geconverteerd naar JSON en verschijnt onder de eigendommen variabele na serialisering.

2.2. @JsonGetter

De @JsonGetter annotatie is een alternatief voor de @JsonProperty annotatie, die een methode markeert als een gettermethode.

In het volgende voorbeeld specificeren we de methode getTheName () als de getter-methode van de naam eigendom van een MyBean entiteit:

openbare klasse MyBean {openbare int id; private String naam; @JsonGetter ("naam") openbare String getTheName () {naam retourneren; }}

Hier is hoe dit in de praktijk werkt:

@Test openbare leegte whenSerializingUsingJsonGetter_thenCorrect () gooit JsonProcessingException {MyBean bean = nieuwe MyBean (1, "My bean"); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (bean); assertThat (resultaat, bevatString ("Mijn boon")); assertThat (resultaat, bevatString ("1")); }

2.3. @JsonPropertyOrder

We kunnen de @JsonPropertyOrder annotatie om te specificeren de volgorde van eigenschappen bij serialisatie.

Laten we een aangepaste volgorde instellen voor de eigenschappen van een MyBean entiteit:

@JsonPropertyOrder ({"name", "id"}) openbare klasse MyBean {openbare int id; public String naam; }

Hier is de output van serialisatie:

{"name": "My bean", "id": 1}

Dan kunnen we een eenvoudige test doen:

@Test openbare leegte whenSerializingUsingJsonPropertyOrder_thenCorrect () gooit JsonProcessingException {MyBean bean = nieuwe MyBean (1, "My bean"); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (bean); assertThat (resultaat, bevatString ("Mijn boon")); assertThat (resultaat, bevatString ("1")); }

We kunnen ook gebruik maken van @JsonPropertyOrder (alfabetisch = waar) om de eigenschappen alfabetisch te ordenen. In dat geval is de output van serialisatie:

{"id": 1, "name": "My bean"}

2.4. @JsonRawValue

De @JsonRawValue annotatie kan instrueer Jackson om een ​​eigenschap exact zo te serialiseren.

In het volgende voorbeeld gebruiken we @JsonRawValue om een ​​aangepaste JSON in te sluiten als een waarde van een entiteit:

openbare klasse RawBean {openbare tekenreeksnaam; @JsonRawValue openbare String json; }

De output van het serialiseren van de entiteit is:

{"name": "My bean", "json": {"attr": false}}

Hier is een eenvoudige test:

@Test public void whenSerializingUsingJsonRawValue_thenCorrect () gooit JsonProcessingException {RawBean bean = nieuwe RawBean ("My bean", "{\" attr \ ": false}"); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (bean); assertThat (resultaat, bevatString ("Mijn boon")); assertThat (resultaat, bevatString ("{\" attr \ ": false}")); }

We kunnen ook het optionele booleaanse argument gebruiken waarde dat bepaalt of deze annotatie actief is of niet.

2.5. @JsonValue

@JsonValue geeft een enkele methode aan die de bibliotheek zal gebruiken om de hele instantie te serialiseren.

In een opsomming annoteren we bijvoorbeeld de getName met @JsonValue zodat een dergelijke entiteit wordt geserialiseerd via zijn naam:

openbare opsomming TypeEnumWithValue {TYPE1 (1, "Type A"), TYPE2 (2, "Type 2"); privé geheel getal id; private String naam; // standard constructors @ JsonValue public String getName () {return naam; }}

Nu is hier onze test:

@Test openbare leegte whenSerializingUsingJsonValue_thenCorrect () gooit JsonParseException, IOException {String enumAsString = nieuwe ObjectMapper () .writeValueAsString (TypeEnumWithValue.TYPE1); assertThat (enumAsString, is ("" Type A "")); }

2.6. @JsonRootName

De @JsonRootName annotatie wordt gebruikt, als wrapping is ingeschakeld, om de naam van de te gebruiken root-wrapper te specificeren.

Wrapping betekent dat in plaats van een Gebruiker naar zoiets als:

{"id": 1, "name": "John"}

Het wordt als volgt ingepakt:

{"Gebruiker": {"id": 1, "naam": "John"}}

Laten we dus naar een voorbeeld kijken. W.we gaan de @JsonRootName annotatie om de naam van deze potentiële wrapper-entiteit aan te geven:

@JsonRootName (waarde = "gebruiker") openbare klasse UserWithRoot {openbare int id; public String naam; }

Standaard is de naam van de wrapper de naam van de klasse - UserWithRoot. Door de annotatie te gebruiken, krijgen we de schoonmaker gebruiker:

@Test public void whenSerializingUsingJsonRootName_thenCorrect () gooit JsonProcessingException {UserWithRoot user = new User (1, "John"); ObjectMapper-mapper = nieuwe ObjectMapper (); mapper.enable (SerializationFeature.WRAP_ROOT_VALUE); String resultaat = mapper.writeValueAsString (gebruiker); assertThat (resultaat, bevatString ("John")); assertThat (resultaat, bevatString ("gebruiker")); }

Hier is de output van serialisatie:

{"user": {"id": 1, "name": "John"}}

Sinds Jackson 2.4, een nieuw optioneel argument naamruimte is beschikbaar voor gebruik met gegevensindelingen zoals XML. Als we het toevoegen, wordt het onderdeel van de volledig gekwalificeerde naam:

@JsonRootName (waarde = "gebruiker", namespace = "gebruikers") openbare klasse UserWithRootNamespace {openbare int id; public String naam; // ...}

Als we het serialiseren met XmlMapper, de output zal zijn:

 1 John 

2.7. @JsonSerialize

@JsonSerialize geeft een aangepaste serialisator aan die moet worden gebruikt wanneer rangschikking de entiteit.

Laten we naar een snel voorbeeld kijken. We gaan gebruiken @JsonSerialize om het eventDate eigendom met een CustomDateSerializer:

openbare klasse EventWithSerializer {openbare tekenreeksnaam; @JsonSerialize (using = CustomDateSerializer.class) public Date eventDate; }

Hier is de eenvoudige aangepaste Jackson-serialisator:

openbare klasse CustomDateSerializer breidt StdSerializer uit {privé statische SimpleDateFormat-formatter = nieuwe SimpleDateFormat ("dd-MM-jjjj uu: mm: ss"); openbare CustomDateSerializer () {dit (null); } openbare CustomDateSerializer (Klasse t) {super (t); } @Override public void serialize (datumwaarde, JsonGenerator gen, SerializerProvider arg2) gooit IOException, JsonProcessingException {gen.writeString (formatter.format (waarde)); }}

Laten we deze nu in een test gebruiken:

@Test openbare leegte whenSerializingUsingJsonSerialize_thenCorrect () gooit JsonProcessingException, ParseException {SimpleDateFormat df = nieuwe SimpleDateFormat ("dd-MM-jjjj uu: mm: ss"); String toParse = "20-12-2014 02:30:00"; Datum datum = df.parse (toParse); EventWithSerializer event = nieuwe EventWithSerializer ("party", datum); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (event); assertThat (resultaat, bevatString (toParse)); }

3. Jackson Deserialization Annotations

Laten we vervolgens de annotaties van Jackson-deserialisatie bekijken.

3.1. @RTLnieuws

We kunnen de @RTLnieuws annotatie om de constructor / fabriek af te stemmen die bij deserialisatie wordt gebruikt.

Het is erg handig als we een JSON moeten deserialiseren die niet exact overeenkomt met de doelentiteit die we nodig hebben.

Laten we naar een voorbeeld kijken. Stel dat we de volgende JSON moeten deserialiseren:

{"id": 1, "theName": "My bean"}

Er is echter geen de naam veld in onze doelentiteit is er alleen een naam veld. Nu willen we de entiteit zelf niet wijzigen, we hebben alleen wat meer controle nodig over het niet-marshalling-proces door de constructor te annoteren met @JsonCreator, en het gebruik van de @JsonProperty annotatie ook:

openbare klasse BeanWithCreator {openbare int id; public String naam; @JsonCreator openbare BeanWithCreator (@JsonProperty ("id") int id, @JsonProperty ("theName") Stringnaam) {this.id = id; this.name = naam; }}

Laten we dit in actie zien:

@Test public void whenDeserializingUsingJsonCreator_thenCorrect () gooit IOException {String json = "{\" id \ ": 1, \" theName \ ": \" My bean \ "}"; BeanWithCreator bean = nieuwe ObjectMapper () .readerFor (BeanWithCreator.class) .readValue (json); assertEquals ("My bean", bean.name); }

3.2. @JacksonInject

@JacksonInject geeft aan dat een eigenschap zijn waarde krijgt van de injectie en niet van de JSON-gegevens.

In het volgende voorbeeld gebruiken we @JacksonInject om de woning te injecteren ID kaart:

openbare klasse BeanWithInject {@JacksonInject openbare int id; public String naam; }

Dit is hoe het werkt:

@Test public void whenDeserializingUsingJsonInject_thenCorrect () gooit IOException {String json = "{\" name \ ": \" My bean \ "}"; InjectableValues ​​inject = nieuwe InjectableValues.Std () .addValue (int.class, 1); BeanWithInject bean = nieuwe ObjectMapper (). Reader (injecteren) .forType (BeanWithInject.class) .readValue (json); assertEquals ("My bean", bean.name); assertEquals (1, bean.id); }

3.3. @RTLnieuws

@RTLnieuws geeft ons de flexibiliteit om een Kaart als standaard eigenschappen. Bij deserialisatie worden de eigenschappen van JSON eenvoudig aan de kaart toegevoegd.

Eerst gebruiken we @RTLnieuws om de entiteit te deserialiseren Uitschuifbaar Bean:

openbare klasse ExtendableBean {openbare tekenreeksnaam; particuliere kaarteigenschappen; @JsonAnySetter public void add (String key, String value) {properties.put (key, value); }}

Dit is de JSON die we nodig hebben om te deserialiseren:

{"name": "My bean", "attr2": "val2", "attr1": "val1"}

Dan is hier hoe het allemaal samengaat:

@Test public void whenDeserializingUsingJsonAnySetter_thenCorrect () gooit IOException {String json = "{\" name \ ": \" My bean \ ", \" attr2 \ ": \" val2 \ ", \" attr1 \ ": \" val1 \ "}"; ExtendableBean bean = nieuwe ObjectMapper () .readerFor (ExtendableBean.class) .readValue (json); assertEquals ("My bean", bean.name); assertEquals ("val2", bean.getProperties (). get ("attr2")); }

3.4. @JsonSetter

@JsonSetter is een alternatief voor @JsonProperty dat markeert de methode als een setter-methode.

Dit is ongelooflijk handig als we enkele JSON-gegevens moeten lezen, maar de doelentiteitsklasse komt niet exact overeen met die gegevens, en dus moeten we het proces afstemmen om het passend te maken.

In het volgende voorbeeld specificeren we de methode setTheName () als de setter van de naam eigendom in ons MyBean entiteit:

openbare klasse MyBean {openbare int id; private String naam; @JsonSetter ("naam") public void setTheName (String naam) {this.name = naam; }}

Als we nu enkele JSON-gegevens moeten verwijderen, werkt dit perfect:

@Test public void whenDeserializingUsingJsonSetter_thenCorrect () gooit IOException {String json = "{\" id \ ": 1, \" name \ ": \" My bean \ "}"; MyBean bean = nieuwe ObjectMapper () .readerFor (MyBean.class) .readValue (json); assertEquals ("Mijn boon", bean.getTheName ()); }

3.5. @JsonDeserialize

@JsonDeserialize geeft het gebruik van een aangepaste deserializer aan.

Eerst gebruiken we @JsonDeserialize om het eventDate eigendom met de CustomDateDeserializer:

openbare klasse EventWithSerializer {openbare tekenreeksnaam; @JsonDeserialize (using = CustomDateDeserializer.class) public Date eventDate; }

Hier is de aangepaste deserializer:

openbare klasse CustomDateDeserializer breidt StdDeserializer uit {privé statische SimpleDateFormat-formatter = nieuwe SimpleDateFormat ("dd-MM-jjjj uu: mm: ss"); openbare CustomDateDeserializer () {dit (null); } openbare CustomDateDeserializer (klasse vc) {super (vc); } @Override public Date deserialize (JsonParser jsonparser, DeserializationContext context) genereert IOException {String date = jsonparser.getText (); probeer {return formatter.parse (date); } catch (ParseException e) {throw nieuwe RuntimeException (e); }}}

Hier is de back-to-back-test:

@Test public void whenDeserializingUsingJsonDeserialize_thenCorrect () gooit IOException {String json = "{" name ":" party "," eventDate ":" 20-12-2014 02:30:00 "}"; SimpleDateFormat df = nieuwe SimpleDateFormat ("dd-MM-jjjj uu: mm: ss"); EventWithSerializer event = new ObjectMapper () .readerFor (EventWithSerializer.class) .readValue (json); assertEquals ("20-12-2014 02:30:00", df.format (event.eventDate)); }

3.6. @JsonAlias

De @JsonAlias definieert een of meer alternatieve namen voor een eigenschap tijdens deserialisatie.

Laten we eens kijken hoe deze annotatie werkt met een snel voorbeeld:

openbare klasse AliasBean {@JsonAlias ​​({"fName", "f_name"}) privé String firstName; private String achternaam; }

Hier hebben we een POJO, en we willen JSON deserialiseren met waarden zoals fNaam, f_naam, en Voornaam in de Voornaam variabele van de POJO.

Hieronder ziet u een test om ervoor te zorgen dat deze annotatie werkt zoals verwacht:

@Test public void whenDeserializingUsingJsonAlias_thenCorrect () gooit IOException {String json = "{\" fName \ ": \" John \ ", \" lastName \ ": \" Green \ "}"; AliasBean aliasBean = nieuwe ObjectMapper (). ReaderFor (AliasBean.class) .readValue (json); assertEquals ("John", aliasBean.getFirstName ()); }

4. Jackson Property Inclusion-aantekeningen

4.1. @JsonIgnoreProperties

@JsonIgnoreProperties is een annotatie op klasniveau die een eigenschap of een lijst met eigenschappen markeert die Jackson zal negeren.

Laten we eens kijken naar een snel voorbeeld waarin de eigenschap wordt genegeerd ID kaart van serialisatie:

@JsonIgnoreProperties ({"id"}) openbare klasse BeanWithIgnore {openbare int id; public String naam; }

Nu is hier de test om ervoor te zorgen dat het negeren gebeurt:

@Test openbare leegte whenSerializingUsingJsonIgnoreProperties_thenCorrect () gooit JsonProcessingException {BeanWithIgnore bean = new BeanWithIgnore (1, "My bean"); String resultaat = nieuwe ObjectMapper () .writeValueAsString (bean); assertThat (resultaat, bevatString ("Mijn boon")); assertThat (resultaat, niet (bevatString ("id"))); }

Om onbekende eigenschappen in JSON-invoer zonder uitzondering te negeren, kunnen we instellen ignoreUnknown = true van @JsonIgnoreProperties annotatie.

4.2. @JsonIgnore

In tegenstelling daarmee is de @JsonIgnore annotatie wordt gebruikt om een ​​eigenschap te markeren die op veldniveau moet worden genegeerd.

Laten we gebruiken @JsonIgnore om de eigenschap te negeren ID kaart van serialisatie:

openbare klasse BeanWithIgnore {@JsonIgnore openbare int id; public String naam; }

Dan zullen we testen om er zeker van te zijn ID kaart werd met succes genegeerd:

@Test openbare leegte whenSerializingUsingJsonIgnore_thenCorrect () gooit JsonProcessingException {BeanWithIgnore bean = nieuwe BeanWithIgnore (1, "My bean"); String resultaat = nieuwe ObjectMapper () .writeValueAsString (bean); assertThat (resultaat, bevatString ("Mijn boon")); assertThat (resultaat, niet (bevatString ("id"))); }

4.3. @JsonIgnoreType

@JsonIgnoreType markeert alle eigenschappen van een geannoteerd type om te worden genegeerd.

We kunnen de annotatie gebruiken om alle eigenschappen van het type te markeren Naam te negeren:

openbare klasse Gebruiker {openbare int id; openbare naam naam; @JsonIgnoreType openbare statische klasse Naam {openbare tekenreeks firstName; openbare tekenreeks achternaam; }}

We kunnen ook testen om ervoor te zorgen dat het negeren correct werkt:

@Test public void whenSerializingUsingJsonIgnoreType_thenCorrect () gooit JsonProcessingException, ParseException {User.Name name = new User.Name ("John", "Doe"); Gebruiker gebruiker = nieuwe gebruiker (1, naam); String resultaat = nieuwe ObjectMapper () .writeValueAsString (gebruiker); assertThat (resultaat, bevatString ("1")); assertThat (resultaat, niet (bevatString ("naam"))); assertThat (resultaat, niet (bevatString ("John"))); }

4.4. @JsonInclude

We kunnen gebruiken @JsonInclude om eigenschappen met lege / null / standaardwaarden uit te sluiten.

Laten we eens kijken naar een voorbeeld dat null-waarden uitsluit van serialisering:

@JsonInclude (include.NON_NULL) openbare klasse MyBean {openbare int id; public String naam; }

Hier is de volledige test:

public void whenSerializingUsingJsonInclude_thenCorrect () gooit JsonProcessingException {MyBean bean = nieuwe MyBean (1, null); String resultaat = nieuwe ObjectMapper () .writeValueAsString (bean); assertThat (resultaat, bevatString ("1")); assertThat (resultaat, niet (bevatString ("naam"))); }

4.5. @JsonAutoDetect

@JsonAutoDetect kan de standaardsemantiek van welke eigenschappen zijn zichtbaar en welke niet.

Laten we eerst eens kijken hoe de annotatie erg nuttig kan zijn met een eenvoudig voorbeeld; laten we het serialiseren van privé-eigenschappen inschakelen:

@JsonAutoDetect (fieldVisibility = Visibility.ANY) openbare klasse PrivateBean {privé int id; private String naam; }

Dan de test:

@Test openbare leegte whenSerializingUsingJsonAutoDetect_thenCorrect () gooit JsonProcessingException {PrivateBean bean = nieuwe PrivateBean (1, "My bean"); String resultaat = nieuwe ObjectMapper () .writeValueAsString (bean); assertThat (resultaat, bevatString ("1")); assertThat (resultaat, bevatString ("Mijn boon")); }

5. Jackson Polymorphic Type Handling Annotations

Laten we nu eens kijken naar de annotaties van het polymorfe type van Jackson:

  • @JsonTypeInfo - geeft details aan van het type informatie dat in de serialisatie moet worden opgenomen
  • @JsonSubTypes - geeft subtypen van het geannoteerde type aan
  • @JsonTypeName - definieert een logische typenaam om te gebruiken voor een geannoteerde klasse

Laten we een complexer voorbeeld bekijken en alle drie gebruiken - @JsonTypeInfo, @JsonSubTypes, en @JsonTypeName - om de entiteit te serialiseren / deserialiseren Dierentuin:

openbare klasse Dierentuin {openbaar Dierlijk dier; @JsonTypeInfo (gebruik = JsonTypeInfo.Id.NAME, include = As.PROPERTY, property = "type") @JsonSubTypes ({@ JsonSubTypes.Type (waarde = Dog.class, name = "dog"), @ JsonSubTypes.Type ( waarde = Cat.class, name = "cat")}) openbare statische klasse Dier {openbare tekenreeksnaam; } @JsonTypeName ("hond") openbare statische klasse Hond breidt Dier uit {openbare dubbele blafVolume; } @JsonTypeName ("cat") openbare statische klasse Cat breidt Animal {boolean likesCream; openbare int levens; }}

Wanneer we serialisatie doen:

@Test openbare leegte whenSerializingPolymorphic_thenCorrect () gooit JsonProcessingException {Zoo.Dog dog = nieuwe Zoo.Dog ("lacy"); Zoo zoo = nieuwe dierentuin (hond); String resultaat = nieuwe ObjectMapper () .writeValueAsString (dierentuin); assertThat (resultaat, bevatString ("type")); assertThat (resultaat, bevatString ("hond")); }

Hier is wat de serialisering van het Dierentuin instantie met de Hond zal resulteren in:

{"animal": {"type": "dog", "name": "lacy", "barkVolume": 0}}

Nu voor de-serialisering. Laten we beginnen met de volgende JSON-invoer:

{"animal": {"name": "lacy", "type": "cat"}}

Laten we dan eens kijken hoe dat ongemarkeerd wordt tot een Dierentuin voorbeeld:

@Test openbare leegte whenDeserializingPolymorphic_thenCorrect () gooit IOException {String json = "{\" dier \ ": {\" naam \ ": \" lacy \ ", \" type \ ": \" kat \ "}}"; Zoo zoo = new ObjectMapper () .readerFor (Zoo.class) .readValue (json); assertEquals ("lacy", zoo.animal.name); assertEquals (Zoo.Cat.class, zoo.animal.getClass ()); }

6. Algemene annotaties van Jackson

Laten we nu enkele van Jackson's meer algemene annotaties bespreken.

6.1. @JsonProperty

We kunnen toevoegen de @JsonProperty annotatie om de eigenschapsnaam in JSON aan te geven.

Laten we gebruiken @JsonProperty om de eigenschap te serialiseren / deserialiseren naam als we te maken hebben met niet-standaard getters en setters:

openbare klasse MyBean {openbare int id; private String naam; @JsonProperty ("naam") public void setTheName (String naam) {this.name = name; } @JsonProperty ("naam") openbare String getTheName () {naam retourneren; }}

Het volgende is onze test:

@Test public void whenUsingJsonProperty_thenCorrect () gooit IOException {MyBean bean = new MyBean (1, "My bean"); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (bean); assertThat (resultaat, bevatString ("Mijn boon")); assertThat (resultaat, bevatString ("1")); MyBean resultBean = nieuwe ObjectMapper () .readerFor (MyBean.class) .readValue (resultaat); assertEquals ("Mijn boon", resultBean.getTheName ()); }

6.2. @JsonFormat

De @JsonFormat annotatie specificeert een indeling bij het serialiseren van datum- / tijdwaarden.

In het volgende voorbeeld gebruiken we @JsonFormat om het formaat van de eigenschap te bepalen eventDate:

openbare klasse EventWithFormat {openbare tekenreeksnaam; @JsonFormat (vorm = JsonFormat.Shape.STRING, patroon = "dd-MM-jjjj uu: mm: ss") openbare datum eventDate; }

Dan is hier de test:

@Test openbare leegte whenSerializingUsingJsonFormat_thenCorrect () gooit JsonProcessingException, ParseException {SimpleDateFormat df = nieuwe SimpleDateFormat ("dd-MM-jjjj uu: mm: ss"); df.setTimeZone (TimeZone.getTimeZone ("UTC")); String toParse = "20-12-2014 02:30:00"; Datum datum = df.parse (toParse); EventWithFormat event = nieuwe EventWithFormat ("party", datum); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (event); assertThat (resultaat, bevatString (toParse)); }

6.3. @JsonUnwrapped

@JsonUnwrapped definieert waarden die moeten worden uitgepakt / afgevlakt wanneer ze worden geserialiseerd / gedeserialiseerd.

Laten we eens kijken hoe dit precies werkt; we gebruiken de annotatie om de eigenschap uit te pakken naam:

openbare klasse UnwrappedUser {openbare int id; @JsonUnwrapped publieke naam naam; openbare statische klasse Naam {openbare tekenreeks voornaam; openbare tekenreeks achternaam; }}

Laten we nu een instantie van deze klasse serialiseren:

@Test public void whenSerializingUsingJsonUnwrapped_thenCorrect () gooit JsonProcessingException, ParseException {UnwrappedUser.Name name = new UnwrappedUser.Name ("John", "Doe"); UnwrappedUser-gebruiker = nieuwe UnwrappedUser (1, naam); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (gebruiker); assertThat (resultaat, bevatString ("John")); assertThat (resultaat, niet (bevatString ("naam"))); }

Eindelijk, hier is hoe de uitvoer eruit ziet - de velden van de statische geneste klasse uitgepakt samen met het andere veld:

{"id": 1, "firstName": "John", "lastName": "Doe"}

6.4. @JsonView

@JsonView geeft de weergave aan waarin de eigenschap zal worden opgenomen voor serialisatie / deserialisatie.

We gebruiken bijvoorbeeld @JsonView om een ​​instantie van Item entiteit.

Laten we eerst beginnen met de weergaven:

public class Weergaven {public static class Public {} public static class Intern breidt openbaar uit {}}

Het volgende is het Item entiteit die de weergaven gebruikt:

public class Item {@JsonView (Views.Public.class) public int id; @JsonView (Views.Public.class) public String itemName; @JsonView (Views.Internal.class) public String ownerName; }

Eindelijk de volledige test:

@Test public void whenSerializingUsingJsonView_thenCorrect () gooit JsonProcessingException {Item item = new Item (2, "book", "John"); String resultaat = nieuwe ObjectMapper () .writerWithView (Views.Public.class) .writeValueAsString (item); assertThat (resultaat, bevatString ("boek")); assertThat (resultaat, bevatString ("2")); assertThat (resultaat, niet (bevatString ("John"))); }

6.5. @JsonManagedReference, @JsonBackReference

De @JsonManagedReference en @JsonBackReference annotaties kunnen ouder / kindrelaties aan en werk rond lussen.

In het volgende voorbeeld gebruiken we @JsonManagedReference en @JsonBackReference om onze ItemWithRef entiteit:

openbare klasse ItemWithRef {openbare int id; openbare String itemName; @JsonManagedReference openbare UserWithRef-eigenaar; }

Onze UserWithRef entiteit:

openbare klasse UserWithRef {openbare int id; public String naam; @JsonBackReference openbare lijst userItems; }

Dan de test:

@Test public void whenSerializingUsingJacksonReferenceAnnotation_thenCorrect () gooit JsonProcessingException {UserWithRef user = new UserWithRef (1, "John"); ItemWithRef item = nieuw ItemWithRef (2, "boek", gebruiker); user.addItem (item); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (item); assertThat (resultaat, bevatString ("boek")); assertThat (resultaat, bevatString ("John")); assertThat (resultaat, niet (bevatString ("userItems"))); }

6.6. @JsonIdentityInfo

@JsonIdentityInfo geeft aan dat Object Identity moet worden gebruikt bij het serialiseren / deserialiseren van waarden, bijvoorbeeld bij het omgaan met oneindige recursietypes van problemen.

In het volgende voorbeeld hebben we een ItemWithIdentity entiteit met een bidirectionele relatie met de UserWithIdentity entiteit:

@JsonIdentityInfo (generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") openbare klasse ItemWithIdentity {openbare int id; openbare String itemName; openbare UserWithIdentity-eigenaar; }

De UserWithIdentity entiteit:

@JsonIdentityInfo (generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") openbare klasse UserWithIdentity {openbare int id; public String naam; openbare lijst userItems; }

Nu laten we eens kijken hoe het probleem van oneindige recursie wordt aangepakt:

@Test openbare leegte whenSerializingUsingJsonIdentityInfo_thenCorrect () gooit JsonProcessingException {UserWithIdentity gebruiker = nieuwe UserWithIdentity (1, "John"); ItemWithIdentity item = nieuw ItemWithIdentity (2, "boek", gebruiker); user.addItem (item); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (item); assertThat (resultaat, bevatString ("boek")); assertThat (resultaat, bevatString ("John")); assertThat (resultaat, bevatString ("userItems")); }

Hier is de volledige uitvoer van het seriedragende artikel en de gebruiker:

{"id": 2, "itemName": "book", "owner": {"id": 1, "name": "John", "userItems": [2]}}

6.7. @JsonFilter

De @JsonFilter annotatie specificeert een filter dat moet worden gebruikt tijdens serialisering.

Eerst definiëren we de entiteit en wijzen we naar het filter:

@JsonFilter ("myFilter") openbare klasse BeanWithFilter {openbare int id; public String naam; }

Nu in de volledige test definiëren we het filter, dat alle andere eigenschappen uitsluit, behalve naam van serialisatie:

@Test openbare leegte whenSerializingUsingJsonFilter_thenCorrect () gooit JsonProcessingException {BeanWithFilter bean = nieuwe BeanWithFilter (1, "My bean"); FilterProvider filters = nieuwe SimpleFilterProvider (). AddFilter ("myFilter", SimpleBeanPropertyFilter.filterOutAllExcept ("naam")); String resultaat = nieuwe ObjectMapper () .writer (filters) .writeValueAsString (bean); assertThat (resultaat, bevatString ("Mijn boon")); assertThat (resultaat, niet (bevatString ("id"))); }

7. Aangepaste Jackson-annotatie

Laten we nu eens kijken hoe u een aangepaste Jackson-annotatie kunt maken. We kunnen gebruik maken van de @BuienRadarNL annotatie:

@Retention (RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonInclude (include.NON_NULL) @JsonPropertyOrder ({"name", "id", "dateCreated"}) public @interface CustomAnnotation {}

Als we nu de nieuwe annotatie op een entiteit gebruiken:

@CustomAnnotation openbare klasse BeanWithCustomAnnotation {openbare int id; public String naam; public Date dateCreated; }

We kunnen zien hoe het de bestaande annotaties combineert tot een eenvoudige aangepaste annotatie die we als een steno kunnen gebruiken:

@Test openbare leegte whenSerializingUsingCustomAnnotation_thenCorrect () gooit JsonProcessingException {BeanWithCustomAnnotation bean = new BeanWithCustomAnnotation (1, "My bean", null); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (bean); assertThat (resultaat, bevatString ("Mijn boon")); assertThat (resultaat, bevatString ("1")); assertThat (resultaat, niet (bevatString ("dateCreated"))); }

De output van het serialisatieproces:

{"name": "My bean", "id": 1}

8. Jackson MixIn-annotaties

Laten we vervolgens kijken hoe we Jackson MixIn-annotaties kunnen gebruiken.

Laten we bijvoorbeeld de MixIn-annotaties gebruiken om de eigenschappen van het type te negeren Gebruiker:

public class Item {public int id; openbare String itemName; openbare gebruiker eigenaar; }
@JsonIgnoreType openbare klasse MyMixInForIgnoreType {}

Laten we dit dan in actie zien:

@Test public void whenSerializingUsingMixInAnnotation_thenCorrect () gooit JsonProcessingException {Item item = new Item (1, "book", null); String resultaat = nieuwe ObjectMapper (). WriteValueAsString (item); assertThat (resultaat, bevatString ("eigenaar")); ObjectMapper-mapper = nieuwe ObjectMapper (); mapper.addMixIn (User.class, MyMixInForIgnoreType.class); result = mapper.writeValueAsString (item); assertThat (resultaat, niet (bevatString ("eigenaar"))); }

9. Schakel Jackson Annotation uit

Laten we tot slot kijken hoe we dat kunnen schakel alle Jackson-annotaties uit. We kunnen dit doen door het MapperFeature.USE_ANNOTATIONS zoals in het volgende voorbeeld:

@JsonInclude (Inclusief.NON_NULL) @JsonPropertyOrder ({"naam", "id"}) openbare klasse MyBean {openbare int id; public String naam; }

Nu, na het uitschakelen van annotaties, zouden deze geen effect moeten hebben en zouden de standaardinstellingen van de bibliotheek van toepassing moeten zijn:

@Test openbare leegte whenDisablingAllAnnotations_thenAllDisabled () gooit IOException {MyBean bean = nieuwe MyBean (1, null); ObjectMapper-mapper = nieuwe ObjectMapper (); mapper.disable (MapperFeature.USE_ANNOTATIONS); String resultaat = mapper.writeValueAsString (bean); assertThat (resultaat, bevatString ("1")); assertThat (resultaat, bevatString ("naam")); }

Het resultaat van serialisering voordat annotaties werden uitgeschakeld:

{"id": 1}

Het resultaat van serialisering na het uitschakelen van annotaties:

{"id": 1, "naam": null}

10. Conclusie

In dit artikel hebben we Jackson-annotaties onderzocht, waarbij we de oppervlakte van het soort flexibiliteit bekrassen dat we kunnen krijgen door ze correct te gebruiken.

De implementatie van al deze voorbeelden en codefragmenten is te vinden op GitHub.