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, така че трябва да е лесно да се импортира и да се изпълнява както е.