Делаем сериализацию в JSON и обратно c Jackson
Java Software Engineer в Devexperts, Преподаватель Компьютерной школы Hillel.
JSON — это текстовый формат данных, основанный на JavaScript. Такой формат данных часто используется для интеграций с внешними сервисами или используется для общения различных модулей приложения, поэтому каждому программисту важно знать, как работать с таким форматом данных.
Работа с JSON состоит из процессов сериализации и десериализации. Это означает следующее:
- Сериализации — когда мы конвертируем наши данные в JSON
- Десериализации — когда из JSON строки получаем POJO объект
Для удобной, быстрой и комфортной работы существует множество библиотек, таких как Gson, Jackson и т.д. В этой статье мы рассмотрим работу с Jackson, JSON сериализацию и десериализацию.
Для этого нам необходимо добавить следующую зависимость в наш pom.xml файл.
com.fasterxml.jackson.core jackson-databind 2.12.4
Сериализация Java
Для лучшего понимания рассмотрим пример простой программы:
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Arrays; import java.util.List; public class SerializationExample < public static void main(String[] args) throws JsonProcessingException < ObjectMapper objectMapper = new ObjectMapper(); Certificate certificateOracle = new Certificate(); certificateOracle.name = "ORACLE"; certificateOracle.year = 2000; Certificate certificateSun = new Certificate(); certificateSun.name = "SUN"; certificateSun.year = 2015; Department department = new Department(); department.setName("Computer Science"); Student student = new Student(); student.id = 2; student.department = department; student.name = "Ali Z"; student.certificates = Arrays.asList(certificateOracle, certificateSun); String json = objectMapper.writeValueAsString(student); System.out.println(json); >static class Student < private int id; private String name; @JsonProperty("dep") private Department department; private Listcertificates; public List getCertificates() < return certificates; >public void setCertificates(List certificates) < this.certificates = certificates; >public String getName() < return name; >public void setName(String name) < this.name = name; >public int getId() < return id; >public void setId(int id) < this.id = id; >public Department getDepartment() < return department; >public void setDepartment(Department department) < this.department = department; >@Override public String toString() < return "Student'; > > static class Department < private String name; public String getName() < return name; >public void setName(String name) < this.name = name; >> static class Certificate < private String name; private int year; public int getYear() < return year; >public void setYear(int year) < this.year = year; >public String getName() < return name; >public void setName(String name) < this.name = name; >> >
Результатом этой программы будет следующая строка:
В этом примере у нас есть следующие сущности (POJO объекты):
Student — класс, который описывает студента.
id — уникальный номер каждого студента.
name — имя нашего студента.
Department — описывает факультет, на котором обучается наш студент.
Certificate — грамоты и награды, которые получил наш студент.
- По умолчанию, если мы никак не аннотируем класс, то Jackson даст JSON поле название переменной. Для того, чтобы наше JSON поле имело другое название, необходимо использовать аннотацию @JsonProperty, где в качестве параметра передать название.
- Jackson также может сериализовать List объектов в массива JSON.
Десериализация в Jackson
Попробуем десериализовать следующую JSON строку:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; public class DeserializationExample < public static void main(String[] args) throws JsonProcessingException < ObjectMapper objectMapper = new ObjectMapper(); String json = "," + "" + "]" + ">"; Student student = objectMapper.readValue(json, Student.class); System.out.println(student); > @JsonIgnoreProperties(ignoreUnknown = true) static class Student < private int id; private String name; @JsonProperty("dep") private Department department; private Listcertificates; public List getCertificates() < return certificates; >public void setCertificates(List certificates) < this.certificates = certificates; >public String getName() < return name; >public void setName(String name) < this.name = name; >public int getId() < return id; >public void setId(int id) < this.id = id; >public Department getDepartment() < return department; >public void setDepartment(Department department) < this.department = department; >@Override public String toString() < return "Student'; > > static class Department < private String name; public String getName() < return name; >public void setName(String name) < this.name = name; >> static class Certificate < private String name; private int year; public int getYear() < return year; >public void setYear(int year) < this.year = year; >public String getName() < return name; >public void setName(String name) < this.name = name; >> >
Как вы заметили, наш JSON не содержит информации по отделению студента, для того, чтобы Jackson не выдавал ошибку при десериализации JSON, необходимо пометить класс аннотацией @JsonIgnoreProperties(ignoreUnknown = true), или же задать глобальную конфигурацию следующим образом:
ObjectMapper objectMapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
Java Software Engineer в Devexperts, Преподаватель Компьютерной школы Hillel.
Java сериализация в JSON и обратно c Jackson
JSON — это текстовый формат данных, основанный на JavaScript. Такой формат данных часто используется для интеграций с внешними сервисами или используется для общения различных модулей приложения. Поэтому каждому программисту важно знать, как работать с таким форматом данных.
Работа с JSON состоит из процессов:
Сериализации — когда мы конвертируем наши данные в JSON.
Десериализации — когда из JSON строки получаем POJO объект.
Для удобной, быстрой и комфортной работы существует множество библиотек, таких как Gson, Jackson и т.д. В данном уроке мы рассмотрим работу с Jackson.
Для этого нам необходимо добавить следующую зависимость в наш pom.xml файл.
com.fasterxml.jackson.core jackson-databind 2.12.4
Сериализация
Для лучшего понимания рассмотрим пример простой программы:
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Arrays; import java.util.List; public class SerializationExample < public static void main(String[] args) throws JsonProcessingException < ObjectMapper objectMapper = new ObjectMapper(); Certificate certificateOracle = new Certificate(); certificateOracle.name = "ORACLE"; certificateOracle.year = 2000; Certificate certificateSun = new Certificate(); certificateSun.name = "SUN"; certificateSun.year = 2015; Department department = new Department(); department.setName("Computer Science"); Student student = new Student(); student.id = 2; student.department = department; student.name = "Ali Z"; student.certificates = Arrays.asList(certificateOracle, certificateSun); String json = objectMapper.writeValueAsString(student); System.out.println(json); >static class Student < private int id; private String name; @JsonProperty("dep") private Department department; private Listcertificates; public List getCertificates() < return certificates; >public void setCertificates(List certificates) < this.certificates = certificates; >public String getName() < return name; >public void setName(String name) < this.name = name; >public int getId() < return id; >public void setId(int id) < this.id = id; >public Department getDepartment() < return department; >public void setDepartment(Department department) < this.department = department; >@Override public String toString() < return "Student'; > > static class Department < private String name; public String getName() < return name; >public void setName(String name) < this.name = name; >> static class Certificate < private String name; private int year; public int getYear() < return year; >public void setYear(int year) < this.year = year; >public String getName() < return name; >public void setName(String name) < this.name = name; >> >
Результатом этой программы будет следующая строка:
В этом примере у нас есть следующие сущности (POJO объекты):
Student — класс, который описывает студента.
id — уникальный номер каждого студента.
name — имя нашего студента.
Department — описывает факультет, на котором обучается наш студент.
Certificate — грамоты и награды, которые получил наш студент.
- По умолчанию если мы никак не аннотируем класс, то Jackson даст JSON поле название переменной. Для того, чтобы наше JSON поле имело другое название, необходимо использовать аннотацию @JsonProperty, где в качестве параметра передать название.
- Jackson также может сериализовать List объектов в массива JSON.
@android_its – android разработка на Java
Десериализация в Jackson
Попробуем десериализовать следующую JSON строку:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; public class DeserializationExample < public static void main(String[] args) throws JsonProcessingException < ObjectMapper objectMapper = new ObjectMapper(); String json = "," + "" + "]" + ">"; Student student = objectMapper.readValue(json, Student.class); System.out.println(student); > @JsonIgnoreProperties(ignoreUnknown = true) static class Student < private int id; private String name; @JsonProperty("dep") private Department department; private Listcertificates; public List getCertificates() < return certificates; >public void setCertificates(List certificates) < this.certificates = certificates; >public String getName() < return name; >public void setName(String name) < this.name = name; >public int getId() < return id; >public void setId(int id) < this.id = id; >public Department getDepartment() < return department; >public void setDepartment(Department department) < this.department = department; >@Override public String toString() < return "Student'; > > static class Department < private String name; public String getName() < return name; >public void setName(String name) < this.name = name; >> static class Certificate < private String name; private int year; public int getYear() < return year; >public void setYear(int year) < this.year = year; >public String getName() < return name; >public void setName(String name) < this.name = name; >> >
Как вы заметили, наш JSON не содержит информации по отделению студента, для того, чтобы Jackson не выдавал ошибку при десериализации JSON, необходимо пометить класс аннотацией @JsonIgnoreProperties(ignoreUnknown = true), или же задать глобальную конфигурацию следующим образом:
ObjectMapper objectMapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
@JsonPropertyOrder позволяет сохранить определенный порядок при сериализации объекта JSON.
Пример без @JsonPropertyOrder
import java.io.IOException; import com.fasterxml.jackson.databind.ObjectMapper; public class JacksonTester < public static void main(String args[])< ObjectMapper mapper = new ObjectMapper(); try < Student student = new Student("Mark", 1); String jsonString = mapper .writerWithDefaultPrettyPrinter() .writeValueAsString(student); System.out.println(jsonString); >catch (IOException e) < e.printStackTrace(); >> > class Student < private String name; private int rollNo; public Student(String name, int rollNo) < this.name = name; this.rollNo = rollNo; >public String getName() < return name; >public int getRollNo() < return rollNo; >>
Вывод
Пример @JsonPropertyOrder
import java.io.IOException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonPropertyOrder; public class JacksonTester < public static void main(String args[])< ObjectMapper mapper = new ObjectMapper(); try < Student student = new Student("Mark", 1); String jsonString = mapper .writerWithDefaultPrettyPrinter() .writeValueAsString(student); System.out.println(jsonString); >catch (IOException e) < e.printStackTrace(); >> > @JsonPropertyOrder(< "rollNo", "name" >) class Student < private String name; private int rollNo; public Student(String name, int rollNo)< this.name = name; this.rollNo = rollNo; >public String getName() < return name; >public int getRollNo() < return rollNo; >>
Вывод программы.
< "name" : "Mark", "rollNo" : 1 >Jackson Аннотации – @JsonValue @JsonValue позволяет сериализовать весь объект, используя его единственный метод. Пример @JsonValue import java.io.IOException; import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.databind.ObjectMapper; public class JacksonTester < public static void main(String args[])< ObjectMapper mapper = new ObjectMapper(); try < Student student = new Student("Mark", 1); String jsonString = mapper .writerWithDefaultPrettyPrinter() .writeValueAsString(student); System.out.println(jsonString); >catch (IOException e) < e.printStackTrace(); >> > class Student < private String name; private int rollNo; public Student(String name, int rollNo)< this.name = name; this.rollNo = rollNo; >public String getName() < return name; >public int getRollNo() < return rollNo; >@JsonValue public String toString()< return "< name : " + name + " >"; > > Вывод "< name : Mark >"