Преобразование объекта Java (POJO) в JSON и обратно с помощью Gson

Введение Формат JSON - один из самых популярных способов сериализации данных. Умение читать и писать - важный навык для любого программиста. Есть несколько библиотек Java, которые могут анализировать JSON, но в этом руководстве мы сосредоточимся на проекте с открытым исходным кодом, разработанном Google, который называется GSON. GSON - это легкая библиотека Java, которая обеспечивает функции сериализации / десериализации. Что отличает GSON от других, так это его поддержка универсальных типов, которая ограничена некоторыми, но не

Вступление

Формат JSON - один из самых популярных способов сериализации данных. Умение читать и писать - важный навык для любого программиста. Есть несколько библиотек Java, которые могут анализировать JSON, но в этом руководстве мы сосредоточимся на проекте с открытым исходным кодом, разработанном Google, который называется GSON.

GSON - это легкая библиотека Java, которая обеспечивает функции сериализации / десериализации. Что отличает GSON от других, так это его поддержка универсальных типов , которая ограничена некоторыми, но не всеми альтернативными библиотеками.

Примечание. Если вы не знакомы с универсальными шаблонами и почему это так важно, не стесняйтесь читать наше Руководство по пониманию универсальных шаблонов Java .

Поскольку мы работаем с внешней библиотекой, давайте добавим зависимость. Если вы используете Maven, вы можете добавить его с помощью:

 <dependency> 
 <groupId>com.google.code.gson</groupId> 
 <artifactId>gson</artifactId> 
 <version>${version}</version> 
 </dependency> 

Или, если вы используете Gradle, вы можете добавить:

 compile group: 'com.google.code.gson', name: 'gson', version: ${version} 

Создание настраиваемого класса

Давайте создадим собственный класс, который мы сначала сериализуем в JSON, а затем десериализуем из JSON - Student :

 public class Student { 
 private String firstName; 
 private String lastName; 
 private int studentID; 
 private String email; 
 private List<String> courses; 
 private FINANCE_TYPE financeType; 
 
 // Getters, setters, constructor, toString() 
 } 

Для нашего Student у нас дополнительно есть перечисление, показывающее, есть ли у них бюджет ( SUBSIDIZED ) или нет ( UNSUBSIDIZED ):

 public enum FINANCE_TYPE { 
 SUBSIDIZED, UNSUBSIDIZED 
 } 

Преобразование объекта Java в объект JSON с помощью GSON

Теперь, когда мы определили наш класс, давайте создадим его экземпляр и сериализуем его в эквивалентное ему представление JSON. Мы сделаем это с помощью метода toJson() который принимает объект в качестве аргумента и возвращает JSON-представление этого объекта:

 // Defining courses 
 List<String> physicsCourses = Arrays.asList("Physics 8.01", "Physics 8.012"); 
 List<String> musicCourses = Arrays.asList("Jazz", "Blues"); 
 
 // Instantiating students 
 Student max = new Student("Max", "Tegmark", 1254, " [email protected] ", physicsCourses, FINANCE_TYPE.SUBSIDIZED); 
 Student amy = new Student("Amy", "Winehouse", 1328, " [email protected] ", musicCourses, FINANCE_TYPE.SUBSIDIZED); 
 
 // Instantiating Gson 
 Gson gson = new Gson(); 
 
 // Converting POJO to JSON 
 String maxJson = gson.toJson(max); 
 String amyJson = gson.toJson(amy); 
 
 System.out.println(maxJson); 
 System.out.println(amyJson); 

Это преобразует наши POJO в строки JSON, которые при печати приводят к:

 {"firstName":"Max","lastName":"Tegmark","studentID":1254,"email":" [email protected] ","courses":["Physics 8.01","Physics 8.012"],"financeType":"SUBSIDIZED"} 
 {"firstName":"Amy","lastName":"Winehouse","studentID":1328,"email":" [email protected] ","courses":["Jazz","Blues"],"financeType":"SUBSIDIZED"} 

Преобразование строки JSON в объект Java

Чтобы отменить этот процесс и сопоставить объект JSON с POJO, мы будем использовать метод fromJson() . Он принимает строку JSON или Reader и класс или TypeToken .

Давайте сначала посмотрим на первое:

 String maxJson = "{\"firstName\":\"Max\",\"lastName\":\"Tegmark\",\"studentID\":1254,\"email\":\" [email protected] \",\"courses\":[\"Physics 8.01\",\"Physics 8.012\"],\"financeType\":\"SUBSIDIZED\"}"; 
 
 Gson gson = new Gson(); 
 Student max = gson.fromJson(maxJson, Student.class); 
 
 System.out.println(max); 

Это создает экземпляр max и заполняет его данными из объекта JSON:

 Student{firstName='Max', lastName='Tegmark', studentID=1254, email=' [email protected] ', courses=[Physics 8.01, Physics 8.012], financeType=SUBSIDIZED} 

Преобразование файла JSON в объект Java

Теперь мы можем не работать с JSON в формате String - нам часто приходится читать файлы JSON. Метод fromJson() принимает Reader , который мы также можем использовать для предоставления данных JSON.

Давайте переместим данные Эми в файл amy.json

 { 
 "firstName":"Amy", 
 "lastName":"Winehouse", 
 "studentID":1328, 
 "email":" [email protected] ", 
 "courses":[ 
 "Jazz", 
 "Blues" 
 ], 
 "financeType":"SUBSIDIZED" 
 } 

Теперь мы можем использовать Reader , например FileReader для чтения этого файла и использовать его для ввода вместо String. Кроме того, вместо использования Student.class мы предоставляем Type . Этот Type извлекается из Gson в TypeToken , что значительно аналогично Джексона TypeReference :

 // Instantiate FileReader for amy.json 
 Reader input = new FileReader("./src/main/resources/amy.json"); 
 //Instantiate Gson 
 Gson gson = new Gson(); 
 // Create a Type via TypeToken for the Student class 
 Type type = new TypeToken<Student>(){}.getType(); 
 // Read the `input` and cast into `type` 
 Student amy = gson.fromJson(input, type); 
 // Print result 
 System.out.println(amy); 

Это, конечно же, также создает и заполняет наш POJO Student

 Student{firstName='Amy', lastName='Winehouse', studentID=1328, email=' [email protected] ', courses=[Jazz, Blues], financeType=SUBSIDIZED} 

Компактная и красивая печать

По умолчанию GSON печатает JSON в компактном формате, который мы уже видели ранее:

 {"firstName":"Max","lastName":"Tegmark","studentID":1254,"email":" [email protected] ","courses":["Physics 8.01","Physics 8.012"],"financeType":"SUBSIDIZED"} 
 {"firstName":"Amy","lastName":"Winehouse","studentID":1328,"email":" [email protected] ","courses":["Jazz","Blues"],"financeType":"SUBSIDIZED"} 

Между именами полей и их значениями, полями объектов и объектами в массивах нет пробелов. Кроме того, нет ни одной новой строки . Если скопировать как String - \n (новые строки) будут присутствовать, это компактное представление затруднительно для чтения.

Мы можем довольно легко включить красивую печать с помощью Gson. При Gson экземпляра Gson вместо вызова пустого конструктора по умолчанию мы можем использовать конструктор GsonBuilder() :

 Gson gson = new GsonBuilder().setPrettyPrinting().create(); 

Теперь мы можем использовать gson почти так же, как и раньше:

 Gson gson = new GsonBuilder().setPrettyPrinting().create(); 
 String amyJson = gson.toJson(amy); 
 System.out.println(amyJson); 

Хотя, на этот раз, при печати - строка JSON имеет довольно печать включена:

 { 
 "firstName": "Amy", 
 "lastName": "Winehouse", 
 "studentID": 1328, 
 "email": " [email protected] ", 
 "courses": [ 
 "Jazz", 
 "Blues" 
 ], 
 "financeType": "SUBSIDIZED" 
 } 

Именование полей JSON с помощью @SerializedName

Сериализация обычно используется для передачи данных между службами, в первую очередь через REST API. При работе с различными службами, командами или даже языками, которые обрабатывают данные, которые мы предоставляем, мы можем захотеть изменить сериализованные имена определенных полей, чтобы они соответствовали более широко принятым стандартам или стандартам определенной службы, которая будет обрабатывать предоставленные нами данные.

Например, мы могли бы предоставлять данные JSON из службы Java в службу Python. Соглашения об именах в Java соответствуют CamelCase , в то время как соглашения об именах в Python соответствуют нижнему lowercase_with_underscores для неконстант и классов.

Зная, что мы будем предоставлять наши данные службе или человеку, который может захотеть использовать другие соглашения, мы можем изменить сериализованные имена наших полей, чтобы они не совпадали с именами в нашем POJO, через аннотацию @SerializedName

 public class Student { 
 @SerializedName("first_name") 
 private String firstName; 
 @SerializedName("last_name") 
 private String lastName; 
 @SerializedName("student_id") 
 private int studentID; 
 @SerializedName("student_email") 
 private String email; 
 @SerializedName("student_courses") 
 private List<String> courses; 
 @SerializedName("student_finance_type") 
 private FINANCE_TYPE financeType; 
 
 // Getters, setters, constructor, toString() 
 } 

Теперь при сериализации эти имена будут использоваться вместо имен наших полей:

 String amyJson = gson.toJson(amy); 
 System.out.println(amyJson); 

Что приводит к:

 { 
 "first_name": "Amy", 
 "last_name": "Winehouse", 
 "student_id": 1328, 
 "student_email": " [email protected] ", 
 "student_courses": [ 
 "Jazz", 
 "Blues" 
 ], 
 "student_finance_type": "SUBSIDIZED" 
 } 

Это также работает и наоборот - если мы получим JSON с first_name а наш POJO Student first_name сопоставленный с firstName , мы десериализуем это просто отлично:

 String input = "{\"first_name\":\"Amy\",\"last_name\":\"Winehouse\",\"student_id\":1328,\"student_email\":\" [email protected] \",\"student_courses\":[\"Jazz\",\"Blues\"],\"student_finance_type\":\"SUBSIDIZED\"}"; 
 Gson gson = new Gson(); 
 Student amy = gson.fromJson(input, Student.class); 
 System.out.println(amy); 

Это приводит к:

 Student{firstName='Amy', lastName='Winehouse', studentID=1328, email=' [email protected] ', courses=[Jazz, Blues], financeType=SUBSIDIZED} 

Заключение

В этом руководстве мы рассмотрели, как преобразовать объект Java в объект JSON с помощью метода Gson toJson() , а также как преобразовать объект JSON в объект Java с помощью метода fromJson() .

Мы также изучили, как включить красивую печать, а также изменить сериализованные имена полей.

comments powered by Disqus