Рубрики
Без рубрики

Начало работы с пользовательской десериализацией в Джексоне

Используйте Jackson для сопоставления пользовательского JSON с любым графом сущностей java с полным контролем над процессом десериализации.

Автор оригинала: 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, поэтому его должно быть легко импортировать и запускать как есть.