Java сериализация в JSON и обратно c Jackson
t.me/javatgJSON — это текстовый формат данных, основанный на JavaScript. Такой формат данных часто используется для интеграций с внешними сервисами или используется для общения различных модулей приложения. Поэтому каждому программисту важно знать, как работать с таким форматом данных.
Работа с JSON состоит из процессов:
Сериализации — когда мы конвертируем наши данные в JSON.
Десериализации — когда из JSON строки получаем POJO объект.
Для удобной, быстрой и комфортной работы существует множество библиотек, таких как Gson, Jackson и т.д. В данном уроке мы рассмотрим работу с Jackson.
Для этого нам необходимо добавить следующую зависимость в наш pom.xml файл.
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.4</version> </dependency>
Сериализация
Для лучшего понимания рассмотрим пример простой программы:
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 List<Certificate> certificates;
public List<Certificate> getCertificates() {
return certificates;
}
public void setCertificates(List<Certificate> 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{"
+ "name='" + name + '\'' + ", id='" + id + '\''
+ '}';
}
}
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;
}
}
}
Результатом этой программы будет следующая строка:
{
"id" : 2,
"name" : "Ali Z",
"certificates" : [ {
"name" : "ORACLE",
"year" : 2000
}, {
"name" : "SUN",
"year" : 2015
} ],
"dep" : {
"name" : "Computer Science"
}
}
В этом примере у нас есть следующие сущности (POJO объекты):
Student — класс, который описывает студента.
id — уникальный номер каждого студента.
name — имя нашего студента.
Department — описывает факультет, на котором обучается наш студент.
Certificate — грамоты и награды, которые получил наш студент.
- По умолчанию если мы никак не аннотируем класс, то Jackson даст JSON поле название переменной. Для того, чтобы наше JSON поле имело другое название, необходимо использовать аннотацию @JsonProperty, где в качестве параметра передать название.
- Jackson также может сериализовать List объектов в массива JSON.
@android_its – android разработка на Java
Десериализация в Jackson
Попробуем десериализовать следующую JSON строку:
{"id":2,"name":"Ali Z","certificates":[{"name":"ORACLE","year":2000},{"name":"SUN","year":2015}]}
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 = "{\"id\":2,
\"name\":\"Ali Z\"," +
"\"certificates\":[" +
"{\"name\":\"ORACLE\",\"year\":2000}," +
"{\"name\":\"SUN\",\"year\":2015}" +
"]" +
"}";
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 List<Certificate> certificates;
public List<Certificate> getCertificates() {
return certificates;
}
public void setCertificates(List<Certificate> 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{"
+ "name='" + name + '\'' + ", id='" + id + '\''
+ '}';
}
}
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;
}
}
Вывод
{
"name" : "Mark",
"rollNo" : 1
}
Пример @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 }"
@javatg – Java телеграм канал