Java XML und JSON: Dokumentverarbeitung für Java SE, Teil 2: JSON-B
In diesem Artikel werden wir XML und JSON in Java 11 und darüber hinaus weiter untersuchen.
Beispiele in diesem Artikel führen Sie in JSON-B ein, die JSON-Bindungs-API für Java. Nach einem kurzen Überblick und einer Installationsanleitung werde ich Ihnen zeigen, wie Sie mit JSON-B Java-Objekte, Arrays und Sammlungen serialisieren und deserialisieren. Anpassen der Serialisierung und Deserialisierung mit JSON-B; und wie man JSON-B-Adapter verwendet, um Quellobjekte während der Serialisierung oder Deserialisierung in Zielobjekte zu konvertieren.
Das Material für diesen Artikel ist völlig neu, könnte aber als zusätzliches Kapitel (Kapitel 13) für mein neues Buch angesehen werden, das kürzlich von Apress veröffentlicht wurde: Java XML und JSON, Second Edition .
Über das Buch: Java XML und JSON
Wie ich bereits in meinem vorherigen Artikel erwähnt habe, hat Apress gerade die zweite Ausgabe meines Buches Java XML und JSON veröffentlicht . Es war mir eine Freude, ein ganzes Buch über XML und JSON zu schreiben, zwei Technologien, die ich für komplementärer als wettbewerbsfähig halte. Nach der Veröffentlichung des Buches habe ich neue Beispiele für Kapitel 6: Transformieren von XML-Dokumenten mit XSLT und für Kapitel 11: Verarbeiten von JSON mit Jackson hinzugefügt. In meinem letzten Artikel "Java XML und JSON: Dokumentverarbeitung für Java SE, Teil 1" wurden verschiedene Techniken zur Transformation und Verarbeitung von Dokumenten unter Verwendung von SAXON und Jackson vorgestellt. Lesen Sie unbedingt diesen Artikel, um mehr über diese Techniken zu erfahren.
Holen Sie sich den Code
Laden Sie den Quellcode herunter, um Beispiele für dieses Tutorial zu erhalten.
Was ist JSON-B?
JSON-B ist eine Standardbindungsschicht und API zum Konvertieren von Java-Objekten in und aus JSON-Dokumenten. Es ähnelt der Java-Architektur für XML-Bindung (JAXB), mit der Java-Objekte in und aus XML konvertiert werden.
JSON-B basiert auf JSON-P, der JSON-Verarbeitungs-API, die zum Parsen, Generieren, Abfragen und Transformieren von JSON-Dokumenten verwendet wird. JSON-B wurde mehr als ein Jahr nach der endgültigen Veröffentlichung von JSR 353, dem JSR für JSON-P, durch Java Specification Request (JSR) 367 eingeführt.
Die JSON-B-API
Die JSON-B-Website (Java API for JSON Binding) führt JSON-B ein und bietet Zugriff auf verschiedene Ressourcen, einschließlich der API-Dokumentation. Gemäß der Dokumentation speichert das JSON-B-Modul sechs Pakete:
javax.json.bind
: Definiert den Einstiegspunkt zum Binden von Java-Objekten an JSON-Dokumente.javax.json.bind.adapter
: Definiert adapterbezogene Klassen.javax.json.bind.annotation
: Definiert Anmerkungen zum Anpassen der Zuordnung zwischen Java-Programmelementen und JSON-Dokumenten.javax.json.bind.config
: Definiert Strategien und Richtlinien zum Anpassen der Zuordnung zwischen Java-Programmelementen und JSON-Dokumenten.javax.json.bind.serializer
: Definiert Schnittstellen zum Erstellen benutzerdefinierter Serializer und Deserializer.javax.json.bind.spi
: Definiert eine Service Provider-Schnittstelle (SPI) zum Einstecken von benutzerdefiniertenJsonbBuilder
s.
Die JSON-B-Website enthält außerdem einen Link zu Yasson, einem Java-Framework, das eine Standardbindungsebene zwischen Java-Klassen und JSON-Dokumenten bereitstellt, sowie eine offizielle Referenzimplementierung der JSON-Bindungs-API.
JSON-B und Java EE 8
Wie JSON-P wurde JSON-B ursprünglich für die Aufnahme in Java SE in Betracht gezogen, wurde jedoch stattdessen in die Java EE 8-Version aufgenommen. Sie können jedoch weiterhin mit JSON-B in einem Java SE-Kontext arbeiten.
Laden Sie JSON-B herunter und installieren Sie es
JSON-B 1.0 ist die aktuelle Version zum Zeitpunkt des Schreibens. Sie können die Yasson-Referenzimplementierung dieser Bibliothek aus dem Maven-Repository beziehen. Sie müssen die folgenden JAR-Dateien herunterladen:
- Javax JSON Bind API 1.0: Enthält alle JSON-B-Klassendateien. Ich habe heruntergeladen
javax.json.bind-api-1.0.jar
. - Yasson: Enthält die Eclipse-basierte Referenzimplementierung von JSON-B. Ich habe heruntergeladen
yasson-1.0.3.jar
. - JSR 374 (JSON-Verarbeitung) Standardanbieter: Enthält alle JSON-P 1.0-Klassendateien zusammen mit den Glassfish-Standardanbieter-Klassendateien. Ich habe heruntergeladen
javax.json-1.1.4.jar
.
Fügen Sie diese JAR-Dateien zu Ihrem Klassenpfad hinzu, wenn Sie Code kompilieren und ausführen, der diese Bibliotheken verwendet:
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
Serialisieren und Deserialisieren von Java-Objekten mit JSON-B
Das javax.json.bind
Paket enthält die Jsonb
und JsonbBuilder
-Schnittstellen, die als Einstiegspunkt für diese Bibliothek dienen:
Jsonb
bietet überladenetoJson()
Methoden zum Serialisieren von Bäumen von Java-Objekten in JSON-Dokumente undfromJson()
Methoden zum Deserialisieren von JSON-Dokumenten in Bäume von Java-Objekten.JsonbBuilder
bietetnewBuilder()
und andere Methoden zum Abrufen eines neuen Buildersbuild()
sowiecreate()
Methoden zum Zurückgeben neuerJsonb
Objekte.
Das folgende Codebeispiel zeigt die grundlegende Verwendung der Typen Jsonb
und JsonBuilder
:
// 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);
Dieses Beispiel aufruft Jsonb
‚s String toJson(Object object)
Methode ein Java - Objekt zu serialisiert, ( Employee
). Dieser Methode wird das Stammverzeichnis des Java-Objektbaums zur Serialisierung übergeben. Wenn null
bestanden wird, toJson()
wirft java.lang.NullPointerException
. Es wird ausgelöst, javax.json.bind.JsonbException
wenn während der Serialisierung ein unerwartetes Problem (z. B. ein E / A-Fehler) auftritt.
Dieses Codefragment ruft auch Jsonb
‚s T fromJson(String str, Class type)
generische Methode, die für die Deserialisierung verwendet wird. Dieser Methode wird das auf Zeichenfolgen basierende JSON-Dokument zum Deserialisieren und der Typ des Stammobjekts des resultierenden Java-Objektbaums übergeben, das zurückgegeben wird. Diese Methode löst aus, NullPointerException
wenn sie null
an einen der Parameter übergeben wird. Es wird ausgelöst, JsonbException
wenn während der Deserialisierung ein unerwartetes Problem auftritt.
Ich habe das Codefragment aus einer JSONBDemo
Anwendung extrahiert, die eine grundlegende Demonstration von JSON-B bietet. Listing 1 zeigt den Quellcode für diese Demo.
Listing 1. JSONBDemo.java (Version 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()
Erstellt zuerst ein Jsonb
Objekt, gefolgt von einem Employee
Objekt. Anschließend wird toJson()
aufgerufen, das Employee
Objekt in ein JSON-Dokument zu serialisieren , das in einer Zeichenfolge gespeichert ist. main()
Ruft nach dem Drucken dieses Dokuments fromJson()
mit der vorherigen Zeichenfolge und Employee
dem java.lang.Class
Objekt auf, um das JSON-Dokument für ein anderes Employee
Objekt zu deserialisieren , das anschließend gedruckt wird.
Listing 2 zeigt Employee
den Quellcode.
Listing 2. Employee.java (Version 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(); } }
Stellen Sie die Listen 1 und 2 wie folgt zusammen:
javac -cp javax.json.bind-api-1.0.jar;. JSONBDemo.java
Führen Sie die Anwendung wie folgt aus:
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()
throwsJsonbException
in the absence of apublic 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
Weitere Typen wie java.math.BigInteger
, java.util.Date
und java.time.LocalDate
werden unterstützt. In der JSON-B-Spezifikation finden Sie eine vollständige Liste der unterstützten Typen.
Serialisieren und Deserialisieren von Arrays und Sammlungen mit JSON-B
Der vorherige Abschnitt befasste sich mit der Serialisierung und Deserialisierung einzelner Java-Objekte. JSON-B unterstützt auch die Möglichkeit, Objektarrays und -sammlungen zu serialisieren und zu deserialisieren. Listing 3 bietet eine Demonstration.
Listing 3. JSONBDemo.java (Version 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); } }
Listing 3 ist eine einfache Erweiterung von Listing 1 und verwendet dieselbe Employee
Klasse wie Listing 2. Darüber hinaus ruft dieses Codebeispiel dasselbe toJson()
und dieselben fromJson()
Methoden auf.