Автор оригинала: Eugen Paraschiv.
1. Обзор
Этот краткий учебник проиллюстрирует, как использовать Jackson 2 для десериализации JSON с помощью пользовательского десериализатора .
Если вы хотите копнуть глубже и узнать другие интересные вещи, которые вы можете сделать с Jackson 2 – перейдите к основному учебнику Джексона .
Дальнейшее чтение:
Вступление к объектмапперу Джексона
Джексон – Решите, Какие Поля Будут Сериализованы/Десериализованы
Джексон – Пользовательский сериализатор
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-сущности:
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)); } }
Как вы можете видеть, десериализатор работает со стандартным джексоновским представлением JSON – JsonNode . Как только входной JSON представлен в виде JsonNode , мы можем теперь извлечь из него соответствующую информацию и построить свой собственный Item entity.
Проще говоря, нам нужно зарегистрировать этот пользовательский десериализатор и просто десериализовать 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);
Этот тип конфигурации для каждого класса очень полезен в ситуациях, когда у нас может не быть прямого доступа к raw ObjectMapper для настройки.
5. Заключение
В этой статье показано, как использовать Jackson 2 для чтения нестандартного ввода JSON -и как сопоставить этот ввод с любым графом сущностей java с полным контролем над отображением.
Реализацию всех этих примеров и фрагментов кода можно найти в over on GitHub – это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.