В этом руководстве мы рассмотрим, как преобразовать объект JSON в объект Java с помощью Jackson , чрезвычайно популярной библиотеки привязки данных для Java.
В частности, мы будем работать с этим объектом JSON:
{
"name":"David",
"position":"Software Engineer",
"skilltree":[
"Java",
"Python",
"JavaScript"
],
"address":{
"street":"Street",
"streetNo":"123"
}
}
Поскольку мы работаем с внешней библиотекой, давайте добавим зависимость. Если вы используете Maven, вы можете добавить его с помощью:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
Или, если вы используете Gradle, вы можете добавить:
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.11.3'
Создание настраиваемого класса
После этого мы можем создать простой настраиваемый класс для размещения
Employee
из содержимого JSON:
public class Employee {
private String name;
private POSITION position;
private List<String> skilltree;
private Address address;
// Constructors, Getters, Setters, toString()
}
Примечание. Если мы хотим, чтобы Джексон мог автоматически связывать свойства нашего класса и свойства в объекте JSON, они должны иметь одинаковые имена. Мы расскажем, как изменить это поведение чуть позже. Кроме того, вам понадобится пустой конструктор для создания экземпляра.
Здесь мы используем перечисление POSITION
, которое выглядит так:
public enum POSITION {
MANAGER, SOFTWARE_ENGINEER, CEO
}
И объект Address
public class Address {
private String street;
private String streetNo;
// Constructors, Getters and Setters, toString()
}
Преобразование объекта JSON в объект Java
Центральный класс Джексона - ObjectMapper
. Это основной API для
привязки данных к объектам, и вы все время будете использовать его с
Джексоном.
Чтобы преобразовать объект JSON в объект Java, вы будете использовать
метод readValue()
ObjectMapper
, который десериализует его в
предоставленную ссылку на класс:
String json = "{ \"name\":\"David\", \"position\":\"SOFTWARE_ENGINEER\", \"skilltree\":[ \"Java\", \"Python\", \"JavaScript\" ], \"address\":{ \"street\":\"Street\", \"streetNo\":\"123\" } }";
// ObjectMapper instantiation
ObjectMapper objectMapper = new ObjectMapper();
// Deserialization into the `Employee` class
Employee employee = objectMapper.readValue(json, Employee.class);
// Print information
System.out.println(employee);
Выполнение этого кода приведет к:
Employee{name='David', position=SOFTWARE_ENGINEER, skillTree=[Java, Python, JavaScript], address=Address{street='Street', streetNo='123'}}
Другой способ сообщить Джексону, в какой класс следует
десериализоваться, - использовать TypeReference
:
Employee employee = objectMapper.readValue(json, new TypeReference<Employee>(){});
Печать этого employee
также приведет к:
Employee{name='David', position=SOFTWARE_ENGINEER, skillTree=[Java, Python, JavaScript], address=Address{street='Street', streetNo='123'}}
Оба они создают данный объект и вызывают один и тот же процесс десериализации. Таким образом, единственная разница между этими двумя вызовами заключается в том, делаете ли вы статическую или динамическую ссылку на тип.