Java сериализация в JSON и обратно c Jackson

JSON — это текстовый формат данных, основанный на 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 — грамоты и награды, которые получил наш студент.

  1. По умолчанию если мы никак не аннотируем класс, то Jackson даст JSON поле название переменной. Для того, чтобы наше JSON поле имело другое название, необходимо использовать аннотацию @JsonProperty, где в качестве параметра передать название.
  2. 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 телеграм канал

Источник

+1
0
+1
3
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *