Aan de slag met aangepaste deserialisering in Jackson

1. Overzicht

Deze korte tutorial laat zien hoe je Jackson 2 kunt gebruiken om JSON te deserialiseren met een aangepaste Deserializer.

Als je dieper wilt graven en leren andere coole dingen die je kunt doen met de Jackson 2 - ga naar de belangrijkste Jackson-tutorial.

2. Standaard deserialisatie

Laten we beginnen met het definiëren van 2 entiteiten en kijken hoe Jackson een JSON-representatie deserialiseert naar deze entiteiten zonder enige aanpassing:

openbare klasse Gebruiker {openbare int id; public String naam; } public class Item {public int id; openbare String itemName; openbare gebruiker eigenaar; }

Laten we nu de JSON-weergave definiëren die we willen deserialiseren:

{"id": 1, "itemName": "theItem", "owner": {"id": 2, "name": "theUser"}}

En tot slot, laten we deze JSON unmarshall naar Java-entiteiten:

Item itemWithOwner = nieuwe ObjectMapper (). ReadValue (json, Item.class);

3. Aangepaste deserializer aan ObjectMapper

In het vorige voorbeeld kwam de JSON-weergave perfect overeen met de java-entiteiten - vervolgens zullen we de JSON vereenvoudigen:

{"id": 1, "itemName": "theItem", "createdBy": 2}

Wanneer dit naar exact dezelfde entiteiten wordt gedemarkeerd, zal dit standaard natuurlijk mislukken:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "createdBy" (class org.baeldung.jackson.dtos.Item), niet gemarkeerd als negeerbaar (3 bekende eigenschappen: "id", "owner", "itemName" ]) op [Bron: [e-mail beschermd]; regel: 1, kolom: 43] (via referentieketen: org.baeldung.jackson.dtos.Item ["createdBy"])

We lossen dit op door te doen onze eigen deserialisatie met een aangepaste deserializer:

openbare klasse ItemDeserializer breidt StdDeserializer {openbare ItemDeserializer () {dit (null) uit; } openbare ItemDeserializer (Klasse vc) {super (vc); } @Override public Item deserialize (JsonParser jp, DeserializationContext ctxt) gooit IOException, JsonProcessingException {JsonNode node = jp.getCodec (). ReadTree (jp); int id = (geheel getal) ((IntNode) node.get ("id")). numberValue (); String itemName = node.get ("itemName"). AsText (); int userId = (Integer) ((IntNode) node.get ("createdBy")). numberValue (); retourneer nieuw item (id, itemName, nieuwe gebruiker (userId, null)); }}

Zoals je kunt zien, werkt de deserializer met de standaard Jackson-weergave van JSON - het JsonNode. Zodra de invoer JSON wordt weergegeven als een JsonNode, kunnen we nu haal er de relevante informatie uit en onze eigen construeren Item entiteit.

Simpel gezegd, we moeten registreer deze aangepaste deserializer en deserialiseer gewoon de JSON normaal:

ObjectMapper-mapper = nieuwe ObjectMapper (); SimpleModule module = nieuwe SimpleModule (); module.addDeserializer (Item.class, nieuwe ItemDeserializer ()); mapper.registerModule (module); Item readValue = mapper.readValue (json, Item.class);

4. Aangepaste deserializer op de klas

Als alternatief kunnen we ook registreer de deserializer rechtstreeks in de klas:

@JsonDeserialize (using = ItemDeserializer.class) openbare klasse Item {...}

Met de deserializer gedefinieerd op klasniveau, is het niet nodig om deze te registreren op het ObjectMapper - een standaard mapper werkt prima:

Item itemWithOwner = nieuwe ObjectMapper (). ReadValue (json, Item.class);

Dit type configuratie per klasse is erg handig in situaties waarin we mogelijk geen directe toegang hebben tot de raw ObjectMapper configureren.

5. Conclusie

Dit artikel laat zien hoe u Jackson 2 kunt gebruiken om lees niet-standaard JSON-invoer - en hoe u die invoer kunt toewijzen aan een Java-entiteitsgrafiek met volledige controle over de toewijzing.

De implementatie van al deze voorbeelden en codefragmenten is te vinden in meer dan op GitHub - het is een op Maven gebaseerd project, dus het moet gemakkelijk te importeren en uit te voeren zijn zoals het is.