Мапирование объектов с использованием библиотеки Jackson

JavaJavaBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии мы узнаем, как использовать класс ObjectMapper Jackson для преобразования объектов в JSON и JSON в объекты. Мы будем использовать простой Java-класс с именем DemoClass и познакомимся с различными методами чтения и записи JSON-данных.

Создание и компиляция DemoClass

Создайте новый проект в директории ~/project и создайте новый Java-класс DemoClass. Вставьте следующий код в файл с кодом DemoClass.java.

import java.util.Date;

public class DemoClass {
    private String field1;
    private Double field2;
    private Date dateField;

    // Конструкторы
    DemoClass() {}

    DemoClass(String field1, Double field2, Date dateField) {
        this.field1 = field1;
        this.field2 = field2;
        this.dateField = dateField;
    }

    // Геттеры и сеттеры
    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }

    public Double getField2() {
        return field2;
    }

    public void setField2(Double field2) {
        this.field2 = field2;
    }

    public Date getDateField() {
        return dateField;
    }

    public void setDateField(Date dateField) {
        this.dateField = dateField;
    }
}

Компилируйте Java-класс DemoClass с использованием следующей команды:

javac DemoClass.java

Чтение объектов из JSON-файла

Мы можем использовать метод readValue() класса ObjectMapper для чтения данных из JSON-файла в объект. Наш JSON-файл содержит только пары свойство-значение для одного объекта.

Создайте новый файл с именем demo.json и вставьте в него следующее содержимое JSON.

{
    "field1": "Sample-1",
    "field2": 20.21,
    "dateField": "2021-07-30T14:20:30.000Z"
}

Используйте следующий код для чтения JSON-файла и его преобразования в объект DemoClass.

import java.io.File;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMapperDemo {
    public static void main(String[] args) {
        try {
            String filePath = "demo.json";
            File file = new File(filePath);

            ObjectMapper objMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            DemoClass obj = objMapper.readValue(file, DemoClass.class);

            System.out.println("Field1: " + obj.getField1());
            System.out.println("Field2: " + obj.getField2());
            System.out.println("DateField: " + obj.getDateField());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

Результат будет таким:

Field1: Sample-1
Field2: 20.21
DateField: Fri Jul 30 14:20:30 UTC 2021

Чтение объектов из JSON-строки

Мы можем читать данные из JSON-строки в объект. Для этого мы будем использовать метод readValue() класса ObjectMapper. Также необходимо передать тип класса этому методу.

Добавьте следующий код для чтения данных из JSON-строки.

String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}";

ObjectMapper objMapper = new ObjectMapper();
DemoClass obj = objMapper.readValue(jsonString, DemoClass.class);

System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());

Результат будет таким:

Field1: Sample-1
Field2: 20.21
DateField: Fri Jul 30 14:20:30 UTC 2021

Чтение объектов из JSON-URL

Чтение объектов из URL также довольно простой процесс. Нам нужно передать объект URL и тип класса методу readValue().

Добавьте следующий код для чтения и преобразования объектов из JSON-URL.

import java.net.URL;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMapperDemo {
    public static void main(String[] args) {
        try {
            URL jsonFileUrl = new URL("file:demo.json");
            ObjectMapper objMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            DemoClass obj = objMapper.readValue(jsonFileUrl, DemoClass.class);

            System.out.println("Field1: " + obj.getField1());
            System.out.println("Field2: " + obj.getField2());
            System.out.println("DateField: " + obj.getDateField());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

Результат будет таким же, как и в шаге 2.

Чтение из массива JSON-строк в массив объектов

Предположим, что строка содержит данные о нескольких объектах (в виде массива) в формате JSON. Мы можем прочитать все эти данные в массив типа DemoClass с использованием класса ObjectMapper.

Добавьте следующий код для чтения объектов из массива JSON-строк в массив объектов.

String jsonString = " [{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}," +
        " {\"field1\":\"Sample-2\",\"field2\":22.55,\"dateField\":\"2021-07-31T14:20:30.000Z\"}]";

ObjectMapper objMapper = new ObjectMapper();
DemoClass[] objectArr = objMapper.readValue(jsonString, DemoClass[].class);

for (DemoClass obj : objectArr) {
    System.out.println("Field1: " + obj.getField1());
    System.out.println("Field2: " + obj.getField2());
    System.out.println("DateField: " + obj.getDateField());
    System.out.println();
}

Результат будет таким:

Field1: Sample-1
Field2: 20.21
DateField: Fri Jul 30 14:20:30 UTC 2021

Field1: Sample-2
Field2: 22.55
DateField: Sat Jul 31 14:20:30 UTC 2021

Чтение из массива JSON-строк в список объектов

Мы можем прочитать объекты в список, если не хотим считывать данные в массив объектов фиксированного размера.

Добавьте следующий код для чтения объектов из массива JSON-строк в список объектов.

String jsonString = " [{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}," +
        " {\"field1\":\"Sample-2\",\"field2\":22.55,\"dateField\":\"2021-07-31T14:20:30.000Z\"}]";

ObjectMapper objMapper = new ObjectMapper();
ArrayList<DemoClass> objectList = objMapper.readValue(jsonString, new TypeReference<ArrayList<DemoClass>>(){});

for (DemoClass obj : objectList) {
    System.out.println("Field1: " + obj.getField1());
    System.out.println("Field2: " + obj.getField2());
    System.out.println("DateField: " + obj.getDateField());
    System.out.println();
}

Результат будет таким же, как и в шаге 5.

Чтение из массива JSON-строк в карту объектов

Мы также можем прочитать данные из JSON-строки в карту. Каждая property класса станет ключом, а значение property - значением.

Добавьте следующий код для чтения данных из JSON-строки в карту.

String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}";

ObjectMapper objMapper = new ObjectMapper();
Map<String, Object> objectMap = objMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {});

for (Map.Entry<String, Object> entry : objectMap.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

Результат будет таким:

field1: Sample-1
field2: 20.21
dateField: 2021-07-30T14:20:30.000Z

Чтение JSON в объект JsonNode

Класс JsonNode предоставляет нам более гибкий способ анализировать JSON. Мы можем использовать метод readTree() класса ObjectMapper для чтения JSON в объект JsonNode.

Добавьте следующий код для чтения JSON в объект JsonNode.

String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}";

ObjectMapper objMapper = new ObjectMapper();
JsonNode node = objMapper.readTree(jsonString);

System.out.println("Field1: " + node.get("field1").asText());
System.out.println("Field2: " + node.get("field2").asDouble());
System.out.println("DateField: " + node.get("dateField").asText());

Результат будет таким же, как и в шаге 2.

Настройка ObjectMapper

Мы можем настроить ObjectMapper, чтобы он мог работать с непредвиденными входными данными.

Добавьте следующий код, чтобы настроить ObjectMapper на игнорирование любых новых свойств.

String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"field3\":\"Unknown\"}";

ObjectMapper objMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DemoClass obj = objMapper.readValue(jsonString, DemoClass.class);

System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());

Результат будет таким же, как и в шаге 2.

Работа с датами

По умолчанию ObjectMapper будет сопоставлять java.util.date с long значением. Это long значение - это количество миллисекунд, прошедших с 1 января 1970 года.

Добавьте следующий код, чтобы показать, как определить формат даты с использованием SimpleDateFormat для сериализации java.util.date.

ObjectMapper objMapper = new ObjectMapper();

SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
objMapper.setDateFormat(dateFormat);

DemoClass obj = new DemoClass("Sample-1", 20.21, new Date());
String jsonString = objMapper.writeValueAsString(obj);

System.out.println(jsonString);

Результат будет таким:

{"field1":"Sample-1","field2":20.21,"dateField":"30-07-2021"}

Резюме

В этом практическом занятии мы узнали, как использовать класс ObjectMapper Jackson для сопоставления объектов с JSON и JSON с объектами. Мы узнали, как прочитать JSON-файл в объект, прочитать данные из JSON-строки и сопоставить их с объектом, а также прочитать объекты из массива JSON-строк в список или массив объектов. Мы также узнали, как прочитать JSON-строку в объект JsonNode и настроить ObjectMapper на игнорирование новых свойств или значений null для примитивных типов. Наконец, мы узнали, как работать с датами и использовать конкретный формат даты при сериализации java.util.date.