Първи стъпки с персонализирана десериализация в Джаксън

1. Общ преглед

Този бърз урок ще илюстрира как да използвате Jackson 2 за десериализиране на JSON с помощта на персонализиран Deserializer .

Ако искате да копаете по-дълбоко и да научите други страхотни неща, които можете да правите с Jackson 2 - преминете към основния урок за Jackson.

2. Стандартна десериализация

Нека започнем с дефинирането на 2 обекта и ще видим как Джаксън ще десериализира JSON представяне на тези обекти без никаква персонализация:

public class User { public int id; public String name; } public class Item { public int id; public String itemName; public User owner; }

Сега, нека дефинираме JSON представлението, което искаме да десериализираме:

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

И накрая, нека демаркираме този JSON към Java Entities:

Item itemWithOwner = new ObjectMapper().readValue(json, Item.class);

3. Персонализиран десериализатор на ObjectMapper

В предишния пример представянето на JSON съвпада идеално с обектите на java - следващото ще опростим JSON:

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

Когато демаркирате това на същите обекти - по подразбиране това разбира се ще се провали:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "createdBy" (class org.baeldung.jackson.dtos.Item), not marked as ignorable (3 known properties: "id", "owner", "itemName"]) at [Source: [email protected]; line: 1, column: 43] (through reference chain: org.baeldung.jackson.dtos.Item["createdBy"])

Ще разрешим това, като направим собствена десериализация с персонализиран десериализатор :

public class ItemDeserializer extends StdDeserializer { public ItemDeserializer() { this(null); } public ItemDeserializer(Class vc) { super(vc); } @Override public Item deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonNode node = jp.getCodec().readTree(jp); int id = (Integer) ((IntNode) node.get("id")).numberValue(); String itemName = node.get("itemName").asText(); int userId = (Integer) ((IntNode) node.get("createdBy")).numberValue(); return new Item(id, itemName, new User(userId, null)); } }

Както можете да видите, десериализаторът работи със стандартното Jackson представяне на JSON - JsonNode . След като входният JSON е представен като JsonNode , вече можем да извлечем съответната информация от него и да изградим собствена субект Item .

Най-просто казано, трябва да регистрираме този персонализиран десериализатор и просто да десериализираме JSON нормално:

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

4. Персонализиран десериализатор за класа

Друга възможност е да регистрираме десериализатора директно в класа :

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

С десериализатора, дефиниран на ниво клас, няма нужда да го регистрирате в ObjectMapper - картографирането по подразбиране ще работи добре:

Item itemWithOwner = new ObjectMapper().readValue(json, Item.class);

Този тип конфигурация по клас е много полезна в ситуации, в които може да нямаме директен достъп до суровия ObjectMapper за конфигуриране.

5. Заключение

Тази статия показва как да се използва Jackson 2 за четене на нестандартни JSON входове - и как да се картографира този вход към всяка графика на java обект с пълен контрол върху картографирането.

Внедряването на всички тези примери и кодови фрагменти може да бъде намерено в над на GitHub - това е проект, базиран на Maven, така че трябва да е лесно да се импортира и да се изпълнява както е.