Java XML i JSON: Obrada dokumenata za Java SE, 2. dio: JSON-B

U ovom ćemo članku nastaviti istraživati ​​XML i JSON u Javi 11 i novijim verzijama.

Primjeri u ovom članku upoznat će vas s JSON-B, JSON Binding API-jem za Javu. Nakon kratkog pregleda i uputa za instalaciju, pokazat ću vam kako koristiti JSON-B za serializaciju i deserializaciju Java objekata, nizova i zbirki; kako prilagoditi serializaciju i deserializaciju pomoću JSON-B; i kako koristiti JSON-B adaptere za pretvaranje izvornih objekata u ciljne objekte tijekom serializacije ili deserializacije.

Materijal za ovaj članak potpuno je nov, ali mogao bi se smatrati dodatnim poglavljem (poglavlje 13) za moju novu knjigu, nedavno objavljenu u izdanju Apress: Java XML i JSON, drugo izdanje .

O knjizi: Java XML i JSON

Kao što sam podijelio u svom prethodnom članku, Apress je upravo objavio drugo izdanje moje knjige, Java XML i JSON . Bilo mi je zadovoljstvo napisati cijelu knjigu o XML-u i JSON-u, dvije tehnologije koje smatram više komplementarnima nego konkurentnim. Nakon objavljivanja knjige, dodao sam nove primjere za poglavlje 6: Transformacija XML dokumenata s XSLT-om i za poglavlje 11: Obrada JSON-a s Jacksonom. Moj posljednji članak "Java XML i JSON: Obrada dokumenata za Java SE, 1. dio" predstavio je razne tehnike transformacije i obrade dokumenata koristeći SAXON i Jackson. Svakako pogledajte taj članak da biste saznali više o tim tehnikama.

Uzmi kod

Preuzmite izvorni kod za primjere korištene u ovom vodiču.

Što je JSON-B?

JSON-B je standardni vezni sloj i API za pretvaranje Java objekata u i iz JSON dokumenata. Slična je Java arhitekturi za XML vezivanje (JAXB), koja se koristi za pretvaranje Java objekata u i iz XML-a.

JSON-B je izgrađen na vrhu JSON-P, JSON API-ja za obradu koji se koristi za raščlanjivanje, generiranje, postavljanje upita i transformiranje JSON dokumenata. JSON-B uveden je Java Specification Request (JSR) 367 više od godinu dana nakon konačnog izdanja JSR 353, JSR za JSON-P.

API JSON-B

Web mjesto Java API za JSON Binding (JSON-B) uvodi JSON-B i omogućuje pristup različitim resursima, uključujući API dokumentaciju. Prema dokumentaciji, JSON-B modul pohranjuje šest paketa:

  • javax.json.bind: Definira ulaznu točku za vezivanje Java objekata za JSON dokumente.
  • javax.json.bind.adapter: Definira klase povezane s adapterima.
  • javax.json.bind.annotation: Definira napomene za prilagodbu mapiranja između elemenata Java programa i JSON dokumenata.
  • javax.json.bind.config: Definira strategije i politike za prilagođavanje mapiranja između elemenata Java programa i JSON dokumenata.
  • javax.json.bind.serializer: Definira sučelja za stvaranje prilagođenih serializatora i deserializatora.
  • javax.json.bind.spi: Definira sučelje davatelja usluga (SPI) za priključivanje prilagođenih JsonbBuilders.

Web mjesto JSON-B također nudi vezu do Yassona, Java okvira koji pruža standardni sloj vezanja između Java klasa i JSON dokumenata, te službenu referentnu provedbu JSON Binding API-ja.

JSON-B i Java EE 8

Poput JSON-P, i ​​JSON-B se prvotno razmatrao za uključivanje u Java SE, ali je umjesto toga uključen u izdanje Java EE 8. Međutim, i dalje možete raditi s JSON-B u kontekstu Java SE.

Preuzmite i instalirajte JSON-B

JSON-B 1.0 je trenutna verzija u vrijeme pisanja ovog članka. Yassonovu referentnu implementaciju ove knjižnice možete dobiti iz spremišta Maven. Morat ćete preuzeti sljedeće JAR datoteke:

  • Javax JSON Bind API 1.0: Sadrži sve datoteke klase JSON-B. Preuzeo sam javax.json.bind-api-1.0.jar.
  • Yasson: Sadrži referentnu implementaciju JSON-B temeljenu na Eclipseu. Preuzeo sam yasson-1.0.3.jar.
  • Zadani davatelj JSR 374 (obrada JSON-a): Sadrži sve datoteke klase JSON-P 1.0 zajedno sa zadanim datotekama klase pružatelja Glassfish. Preuzeo sam javax.json-1.1.4.jar.

Dodajte ove JAR datoteke u svoju put predavanja prilikom sastavljanja i pokretanja koda koji koristi ove knjižnice:

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

Serijalizacija i deserializacija Java objekata s JSON-B

javax.json.bindPaket pruža Jsonbi JsonbBuildersučelja, koje služe kao entrypoint ovoj knjižnici:

  • Jsonbpruža preopterećene toJson()metode za serializiranje stabala Java objekata na JSON dokumente i fromJson()metode za deserializaciju JSON dokumenata na stabla Java objekata.
  • JsonbBuilderpruža newBuilder()i druge metode za dobivanje novog graditelja, i build()i create()metode za vraćanje novih Jsonbobjekata.

Sljedeći kod primjer pokazuje osnovnu uporabu od Jsonbte JsonBuildervrste:

// 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);

Ovaj primjer se poziva Jsonb„s String toJson(Object object)postupak serijalizacija Java objekt ( Employee). Ova metoda se prenosi korijenom Java stabla objekata radi serializacije. Ako nullje prošao, toJson()baca java.lang.NullPointerException. Baca javax.json.bind.JsonbExceptionkada se tijekom serializacije dogodi neočekivani problem (poput I / O pogreške).

Ovaj kod fragment također priziva Jsonb„s T fromJson(String str, Class type)generički postupak koji se koristi za Deserialization. Ovoj se metodi prenosi JSON dokument zasnovan na nizu radi deserializacije i vrste rezultirajućeg korijenskog objekta stabla Java objekata koji se vraća. Ova metoda baca NullPointerExceptionkada nullse proslijedi bilo kojem parametru; baca JsonbExceptionkad se tijekom deserializacije dogodi neočekivani problem.

Izdvojio sam fragment koda iz JSONBDemoaplikacije koja pruža osnovnu demonstraciju JSON-B. Popis 1 predstavlja izvorni kôd za ovu demonstraciju.

Popis 1. JSONBDemo.java (verzija 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()prvo stvara Jsonbobjekt nakon kojeg slijedi Employeeobjekt. Zatim poziva toJson()na serializaciju Employeeobjekta u JSON dokument koji je pohranjen u nizu. Nakon ispisa ovog dokumenta, main()poziva fromJson()s prethodnom nizu i Employee„s java.lang.Classpredmetom kako bi deserialize JSON dokument na drugi Employeeobjekt, koji se potom ispisuje.

Popis 2 predstavlja Employeeizvorni kod.

Popis 2. Employee.java (verzija 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(); } }

Sastavite popise 1 i 2 kako slijedi:

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

Pokrenite aplikaciju na sljedeći način:

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

Dodatne vrste, kao što su java.math.BigInteger, java.util.Datei java.time.LocalDatepodržani. Potpuni popis podržanih vrsta potražite u specifikaciji JSON-B.

Serijalizacija i deserializacija nizova i kolekcija s JSON-B

Prethodni se odjeljak usredotočio na serializiranje i deserializiranje pojedinačnih Java objekata. JSON-B također podržava mogućnost serializacije i deserializacije nizova objekata i kolekcija. Popis 3 daje demonstraciju.

Popis 3. JSONBDemo.java (verzija 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); } }

Popis 3 jednostavno je proširenje popisa 1 i koristi istu Employeeklasu predstavljenu na popisu 2. Osim toga, ovaj primjer koda poziva iste toJson()i fromJson()metode.