Java XML dan JSON: Pemrosesan dokumen untuk Java SE, Bagian 2: JSON-B

Pada artikel ini, kami akan terus menjelajahi XML dan JSON di Java 11 dan seterusnya.

Contoh dalam artikel ini akan memperkenalkan Anda pada JSON-B, JSON Binding API untuk Java. Setelah gambaran singkat dan instruksi instalasi, saya akan menunjukkan kepada Anda bagaimana menggunakan JSON-B untuk membuat serial dan deserialisasi objek Java, array, dan koleksi; cara menyesuaikan serialisasi dan deserialisasi menggunakan JSON-B; dan cara menggunakan adaptor JSON-B untuk mengonversi objek sumber ke objek target selama serialisasi atau deserialisasi.

Materi untuk artikel ini benar-benar baru, tetapi dapat dianggap sebagai bab tambahan (Bab 13) untuk buku baru saya, yang baru-baru ini diterbitkan oleh Apress: Java XML dan JSON, Edisi Kedua .

Tentang buku: Java XML dan JSON

Seperti yang saya bagikan di artikel saya sebelumnya, Apress baru saja menerbitkan edisi kedua buku saya, Java XML dan JSON . Senang sekali bisa menulis seluruh buku tentang XML dan JSON, dua teknologi yang saya anggap lebih saling melengkapi daripada kompetitif. Setelah buku diterbitkan, saya menambahkan contoh baru untuk Bab 6: Mengubah dokumen XML dengan XSLT, dan untuk Bab 11: Memproses JSON dengan Jackson. Artikel terakhir saya, "Java XML dan JSON: Pemrosesan dokumen untuk Java SE, Bagian 1" memperkenalkan berbagai transformasi dokumen dan teknik pemrosesan menggunakan SAXON dan Jackson. Pastikan untuk membaca artikel itu untuk mempelajari lebih lanjut tentang teknik ini.

Dapatkan kodenya

Unduh kode sumber untuk contoh yang digunakan dalam tutorial ini.

Apa itu JSON-B?

JSON-B adalah lapisan pengikat standar dan API untuk mengonversi objek Java ke dan dari dokumen JSON. Ini mirip dengan Java Architecture for XML Binding (JAXB), yang digunakan untuk mengonversi objek Java ke dan dari XML.

JSON-B dibangun di atas JSON-P, API Pemrosesan JSON yang digunakan untuk mem-parsing, membuat, membuat kueri, dan mengubah dokumen JSON. JSON-B diperkenalkan oleh Java Specification Request (JSR) 367 lebih dari setahun setelah rilis final JSR 353, JSR untuk JSON-P.

API JSON-B

Situs web Java API for JSON Binding (JSON-B) memperkenalkan JSON-B dan menyediakan akses ke berbagai sumber daya, termasuk dokumentasi API. Menurut dokumentasi, modul JSON-B menyimpan enam paket:

  • javax.json.bind: Mendefinisikan titik masuk untuk mengikat objek Java ke dokumen JSON.
  • javax.json.bind.adapter: Mendefinisikan kelas yang berhubungan dengan adaptor.
  • javax.json.bind.annotation: Mendefinisikan anotasi untuk menyesuaikan pemetaan antara elemen program Java dan dokumen JSON.
  • javax.json.bind.config: Mendefinisikan strategi dan kebijakan untuk menyesuaikan pemetaan antara elemen program Java dan dokumen JSON.
  • javax.json.bind.serializer: Mendefinisikan antarmuka untuk membuat serializers dan deserializers kustom.
  • javax.json.bind.spi: Mendefinisikan sebuah Service Provider Interface (SPI) untuk memasukkan custom JsonbBuilders.

Situs web JSON-B juga menyediakan tautan ke Yasson, kerangka kerja Java yang menyediakan lapisan pengikat standar antara kelas Java dan dokumen JSON, dan implementasi referensi resmi dari API Binding JSON.

JSON-B dan Java EE 8

Seperti JSON-P, JSON-B awalnya dipertimbangkan untuk dimasukkan dalam Java SE, tetapi malah disertakan dalam rilis Java EE 8. Anda masih dapat bekerja dengan JSON-B dalam konteks Java SE.

Unduh dan pasang JSON-B

JSON-B 1.0 adalah versi saat ini pada saat penulisan. Anda bisa mendapatkan implementasi referensi Yasson dari pustaka ini dari repositori Maven. Anda perlu mengunduh file JAR berikut:

  • Javax JSON Bind API 1.0: Berisi semua file kelas JSON-B. Saya mengunduh javax.json.bind-api-1.0.jar.
  • Yasson: Berisi implementasi referensi berbasis Eclipse dari JSON-B. Saya mengunduh yasson-1.0.3.jar.
  • JSR 374 (Pemrosesan JSON) Penyedia Default: Berisi semua file kelas JSON-P 1.0 bersama dengan file kelas penyedia default Glassfish. Saya mengunduh javax.json-1.1.4.jar.

Tambahkan file JAR ini ke classpath Anda saat menyusun dan menjalankan kode yang menggunakan pustaka berikut:

javac -cp javax.json.bind-api-1.0.jar;. main source file java -cp javax.json.bind-api-1.0.jar;yasson-1.0.3.jar;javax.json-1.1.4.jar;. main classfile

Serialisasi dan deserialisasi objek Java dengan JSON-B

The javax.json.bindpaket menyediakan Jsonbdan JsonbBuilderinterface, yang berfungsi sebagai entrypoint ke perpustakaan ini:

  • Jsonbmenyediakan toJson()metode kelebihan beban untuk menserialisasi pohon objek Java ke dokumen JSON, dan fromJson()metode untuk mendesentralisasi dokumen JSON ke hierarki objek Java.
  • JsonbBuildermenyediakan newBuilder()dan metode lain untuk mendapatkan pembangun baru, build()dan create()metode untuk mengembalikan Jsonbobjek baru .

Contoh kode berikut menunjukkan penggunaan dasar Jsonbdan JsonBuildertipe:

// Create a new Jsonb instance using the default JsonbBuilder implementation. Jsonb jsonb = JsonbBuilder.create(); // Create an Employee object from a hypothetical Employee class. Employee employee = ... // Convert the Employee object to a JSON document stored in a string. String jsonEmployee = jsonb.toJson(employee); // Convert the previously-created JSON document to an Employee object. Employee employee2 = jsonb.fromJson(jsonEmployee, Employee.class);

Contoh ini memanggil Jsonb's String toJson(Object object)metode untuk cerita bersambung objek Jawa, ( Employee). Metode ini melewati akar pohon objek Java untuk membuat serial. Jika nulllolos, toJson()lempar java.lang.NullPointerException. Itu melempar javax.json.bind.JsonbExceptionketika masalah tak terduga (seperti kesalahan I / O) terjadi selama serialisasi.

Fragmen kode ini juga memanggil Jsonb's T fromJson(String str, Class type)metode generik, yang digunakan untuk deserialization. Metode ini meneruskan dokumen JSON berbasis string ke deserialisasi dan jenis objek akar pohon objek Java yang dihasilkan, yang dikembalikan. Metode ini melempar NullPointerExceptionketika nullditeruskan ke salah satu parameter; itu melempar JsonbExceptionketika masalah tak terduga terjadi selama deserialization.

Saya mengutip fragmen kode dari JSONBDemoaplikasi yang menyediakan demonstrasi dasar JSON-B. Kode 1 menyajikan kode sumber untuk demo ini.

Daftar 1. JSONBDemo.java (versi 1)

import java.time.LocalDate; import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; public class JSONBDemo { public static void main(String[] args) { Jsonb jsonb = JsonbBuilder.create(); Employee employee = new Employee("John", "Doe", 123456789, false, LocalDate.of(1980, 12, 23), LocalDate.of(2002, 8, 14)); String jsonEmployee = jsonb.toJson(employee); System.out.println(jsonEmployee); System.out.println(); Employee employee2 = jsonb.fromJson(jsonEmployee, Employee.class); System.out.println(employee2); } }

main()pertama membuat Jsonbobjek diikuti oleh Employeeobjek. Itu kemudian memanggil toJson()untuk membuat serial Employeeobjek ke dokumen JSON yang disimpan dalam string. Setelah mencetak dokumen ini, main()memanggil fromJson()dengan string sebelumnya dan Employee's java.lang.Classobjek untuk deserialize dokumen JSON lain Employeeobjek, yang kemudian dicetak.

Kode 2 menyajikan Employeekode sumber.

Daftar 2. Employee.java (versi 1)

import java.time.LocalDate; public class Employee { private String firstName; private String lastName; private int ssn; private boolean isMarried; private LocalDate birthDate; private LocalDate hireDate; private StringBuffer sb = new StringBuffer(); public Employee() {} public Employee(String firstName, String lastName, int ssn, boolean isMarried, LocalDate birthDate, LocalDate hireDate) { this.firstName = firstName; this.lastName = lastName; this.ssn = ssn; this.isMarried = isMarried; this.birthDate = birthDate; this.hireDate = hireDate; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getSSN() { return ssn; } public boolean isMarried() { return isMarried; } public LocalDate getBirthDate() { return birthDate; } public LocalDate getHireDate() { return hireDate; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setLastName(String lastName) { this.lastName = lastName; } public void setSSN(int ssn) { this.ssn = ssn; } public void setIsMarried(boolean isMarried) { this.isMarried = isMarried; } public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; } public void setHireDate(LocalDate hireDate) { this.hireDate = hireDate; } @Override public String toString() { sb.setLength(0); sb.append("First name ["); sb.append(firstName); sb.append("], Last name ["); sb.append(lastName); sb.append("], SSN ["); sb.append(ssn); sb.append("], Married ["); sb.append(isMarried); sb.append("], Birthdate ["); sb.append(birthDate); sb.append("], Hiredate ["); sb.append(hireDate); sb.append("]"); return sb.toString(); } }

Susun Daftar 1 dan 2 sebagai berikut:

javac -cp javax.json.bind-api-1.0.jar;. JSONBDemo.java

Jalankan aplikasinya sebagai berikut:

java -cp javax.json.bind-api-1.0.jar;yasson-1.0.3.jar;javax.json-1.1.4.jar;. JSONBDemo

You should observe the following output (spread across multiple lines for readability):

{"SSN":123456789,"birthDate":"1980-12-23","firstName":"John","hireDate":"2002-08-14", "lastName":"Doe","married":false} First name [John], Last name [Doe], SSN [123456789], Married [false], Birthdate [1980-12-23], Hiredate [2002-08-14] 

Rules for working with JSON-B

While playing with this application, I observed some interesting behaviors that led me to formulate the following rules concerning Employee:

  • The class must be public; otherwise, an exception is thrown.
  • toJson() will not serialize fields with non-public getter methods.
  • fromJson() will not deserialize fields with non-public setter methods.
  • fromJson() throws JsonbException in the absence of a public noargument constructor.

In order to seamlessly convert between Java object fields and JSON data, JSON-B has to support various Java types. For example, JSON-B supports the following basic Java types:

  • java.lang.Boolean
  • java.lang.Byte
  • java.lang.Character
  • java.lang.Double
  • java.lang.Float
  • java.lang.Integer
  • java.lang.Long
  • java.lang.Short
  • java.lang.String

Jenis tambahan seperti java.math.BigInteger, java.util.Date, dan java.time.LocalDatedidukung. Lihat spesifikasi JSON-B untuk daftar lengkap jenis yang didukung.

Serialisasi dan deserialisasi array dan koleksi dengan JSON-B

Bagian sebelumnya berfokus pada serialisasi dan deserialisasi objek Java tunggal. JSON-B juga mendukung kemampuan untuk membuat serial dan deserialisasi array dan koleksi objek. Kode 3 memberikan demonstrasi.

Kode 3. JSONBDemo.java (versi 2)

import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; public class JSONBDemo { public static void main(String[] args) { arrayDemo(); listDemo(); } // Serialize and deserialize an array of Employee objects. static void arrayDemo() { Jsonb jsonb = JsonbBuilder.create(); Employee[] employees = { new Employee("John", "Doe", 123456789, false, LocalDate.of(1980, 12, 23), LocalDate.of(2002, 8, 14)), new Employee("Jane", "Smith", 987654321, true, LocalDate.of(1982, 6, 13), LocalDate.of(2001, 2, 9)) }; String jsonEmployees = jsonb.toJson(employees); System.out.println(jsonEmployees); System.out.println(); employees = null; employees = jsonb.fromJson(jsonEmployees, Employee[].class); for (Employee employee: employees) { System.out.println(employee); System.out.println(); } } // Serialize and deserialize a List of Employee objects. static void listDemo() { Jsonb jsonb = JsonbBuilder.create(); List employees = Arrays.asList(new Employee("John", "Doe", 123456789, false, LocalDate.of(1980, 12, 23), LocalDate.of(2002, 8, 14)), new Employee("Jane", "Smith", 987654321, true, LocalDate.of(1982, 6, 13), LocalDate.of(1999, 7, 20))); String jsonEmployees = jsonb.toJson(employees); System.out.println(jsonEmployees); System.out.println(); employees = null; employees = jsonb.fromJson(jsonEmployees, new ArrayList(){}. getClass().getGenericSuperclass()); System.out.println(employees); } }

Kode 3 adalah perpanjangan sederhana dari Kode 1, dan menggunakan Employeekelas yang sama seperti yang disajikan pada Properti 2. Selain itu, contoh kode ini memanggil metode toJson()dan yang sama fromJson().