Programmering

Java XML og JSON: Dokumentbehandling til Java SE, del 2: JSON-B

I denne artikel vil vi fortsætte med at udforske XML og JSON i Java 11 og senere.

Eksempler i denne artikel introducerer dig til JSON-B, JSON Binding API til Java. Efter en hurtig oversigt og installationsinstruktion viser jeg dig, hvordan du bruger JSON-B til at serialisere og deserialisere Java-objekter, arrays og samlinger; hvordan man tilpasser serialisering og deserialisering ved hjælp af JSON-B; og hvordan man bruger JSON-B-adaptere til at konvertere kildeobjekter til målobjekter under serialisering eller deserialisering.

Materialet til denne artikel er helt nyt, men kan betragtes som et yderligere kapitel (kapitel 13) til min nye bog, der for nylig blev udgivet af Apress: Java XML og JSON, anden udgave.

Om bogen: Java XML og JSON

Som jeg delte i min tidligere artikel, har Apress netop offentliggjort den anden udgave af min bog, Java XML og JSON. Det har været en fornøjelse at skrive en hel bog om XML og JSON, to teknologier, som jeg anser for mere komplementære end konkurrencedygtige. Efter udgivelsen af ​​bogen tilføjede jeg nye eksempler til kapitel 6: Transformering af XML-dokumenter med XSLT og til kapitel 11: Behandling af JSON med Jackson. Min sidste artikel "Java XML og JSON: Dokumentbehandling til Java SE, del 1" introducerede en række forskellige dokumenttransformations- og behandlingsteknikker ved hjælp af SAXON og Jackson. Sørg for at tjekke den artikel for at lære mere om disse teknikker.

Få koden

Download kildekoden for eksempler, der bruges i denne vejledning.

Hvad er JSON-B?

JSON-B er et standardbindingslag og API til konvertering af Java-objekter til og fra JSON-dokumenter. Det ligner Java Architecture for XML Binding (JAXB), som bruges til at konvertere Java-objekter til og fra XML.

JSON-B er bygget oven på JSON-P, JSON Processing API, der bruges til parsing, generering, forespørgsel og transformation af JSON-dokumenter. JSON-B blev introduceret af Java Specification Request (JSR) 367 mere end et år efter den endelige frigivelse af JSR 353, JSR for JSON-P.

JSON-B API

Webstedet Java API for JSON Binding (JSON-B) introducerer JSON-B og giver adgang til forskellige ressourcer, herunder API-dokumentation. Ifølge dokumentationen gemmer JSON-B-modulet seks pakker:

  • javax.json.bind: Definerer indgangspunktet for binding af Java-objekter til JSON-dokumenter.
  • javax.json.bind.adapter: Definerer adapterrelaterede klasser.
  • javax.json.bind.annotation: Definerer kommentarer til tilpasning af kortlægningen mellem Java-programelementer og JSON-dokumenter.
  • javax.json.bind.config: Definerer strategier og politikker til tilpasning af kortlægningen mellem Java-programelementer og JSON-dokumenter.
  • javax.json.bind.serializer: Definerer grænseflader til oprettelse af brugerdefinerede serialiseringer og deserialiseringer.
  • javax.json.bind.spi: Definerer en Service Provider Interface (SPI) til tilslutning af brugerdefineret JsonbBuilders.

JSON-B-webstedet giver også et link til Yasson, en Java-ramme, der giver et standardbindingslag mellem Java-klasser og JSON-dokumenter og en officiel referenceimplementering af JSON Binding API.

JSON-B og Java EE 8

Ligesom JSON-P blev JSON-B oprindeligt betragtet som optagelse i Java SE, men blev i stedet inkluderet i Java EE 8-udgivelsen. Du kan dog stadig arbejde med JSON-B i en Java SE-sammenhæng.

Download og installer JSON-B

JSON-B 1.0 er den aktuelle version i skrivende stund. Du kan få Yasson-referenceimplementeringen af ​​dette bibliotek fra Maven-arkivet. Du skal downloade følgende JAR-filer:

  • Javax JSON Bind API 1.0: Indeholder alle JSON-B klassefiler. Jeg downloadede javax.json.bind-api-1.0.jar.
  • Yasson: Indeholder den Eclipse-baserede referenceimplementering af JSON-B. Jeg downloadede yasson-1.0.3.jar.
  • JSR 374 (JSON Processing) Standardudbyder: Indeholder alle JSON-P 1.0-klassefiler sammen med Glassfish-standardudbyders klassefiler. Jeg downloadede javax.json-1.1.4.jar.

Føj disse JAR-filer til din klassesti, når du kompilerer og kører kode, der bruger disse biblioteker:

javac -cp javax.json.bind-api-1.0.jar ;. hovedkildefil java -cp javax.json.bind-api-1.0.jar; yasson-1.0.3.jar; javax.json-1.1.4.jar ;. hovedklassefil

Serialisering og deserialisering af Java-objekter med JSON-B

Det javax.json.bind pakken giver Jsonb og JsonbBuilder grænseflader, der fungerer som indgang til dette bibliotek:

  • Jsonb giver overbelastet toJson () metoder til serialisering af træer af Java-objekter til JSON-dokumenter, og fraJson () metoder til deserialisering af JSON-dokumenter til træer af Java-objekter.
  • JsonbBuilder giver newBuilder () og andre metoder til at skaffe en ny bygherre, og bygge () og skab() metoder til returnering af nye Jsonb genstande.

Følgende kodeeksempel viser den grundlæggende brug af Jsonb og JsonBuilder typer:

// Opret en ny Jsonb-instans ved hjælp af standard JsonbBuilder-implementeringen. Jsonb jsonb = JsonbBuilder.create (); // Opret et medarbejderobjekt fra en hypotetisk medarbejderklasse. Medarbejdermedarbejder = ... // Konverter medarbejderobjektet til et JSON-dokument gemt i en streng. String jsonEmployee = jsonb.toJson (medarbejder); // Konverter det tidligere oprettede JSON-dokument til et medarbejderobjekt. Medarbejdermedarbejder2 = jsonb.fromJson (jsonEmployee, Employee.class);

Dette eksempel påberåber sig Jsonb's String toJson (Objektobjekt) metode til at serieisere et Java-objekt, (Medarbejder). Denne metode sendes til roden af ​​Java-objekttræet for at serieiseres. Hvis nul er bestået, toJson () kaster java.lang.NullPointerException. Det kaster javax.json.bind.JsonbException når der opstår et uventet problem (såsom en I / O-fejl) under serialisering.

Dette kodefragment påberåber sig også Jsonb's T fromJson (strengstreng, klassetype) generisk metode, der bruges til deserialisering. Denne metode sendes det strengbaserede JSON-dokument til deserialisering og typen af ​​det resulterende Java-objekttræs rodobjekt, som returneres. Denne metode kaster NullPointerException hvornår nul videregives til begge parametre; kaster det JsonbUndtagelse når der opstår et uventet problem under deserialisering.

Jeg uddragede kodefragmentet fra en JSONBDemo applikation, der giver en grundlæggende demonstration af JSON-B. Liste 1 viser kildekoden til denne demo.

Liste 1. JSONBDemo.java (version 1)

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

hoved () opretter først en Jsonb objekt efterfulgt af et Medarbejder objekt. Derefter kalder det toJson () at serieisere Medarbejder modsætter sig et JSON-dokument, der er gemt i en streng. Efter udskrivning af dette dokument hoved () påberåber sig fraJson () med den forrige streng og Medarbejder's java.lang.Klasse gør indsigelse mod at deserialisere JSON-dokumentet til et andet Medarbejder objekt, der efterfølgende udskrives.

Notering 2 gaver Medarbejderkildekode.

Liste 2. Medarbejder.java (version 1)

importere java.time.LocalDate; offentlig klassemedarbejder {privat streng fornavn; privat streng efternavn; privat int ssn; privat boolsk isMægtet; private LocalDate fødselsdato; privat LocalDate hireDate; privat StringBuffer sb = ny StringBuffer (); offentlig medarbejder () {} offentlig medarbejder (streng fornavn, streng efternavn, int ssn, boolsk isMarried, LocalDate birthDate, LocalDate hireDate) {this.firstName = firstName; this.lastName = efternavn; this.ssn = ssn; this.isMarried = isMarried; this.birthDate = fødselsdato; this.hireDate = hireDate; } offentlig streng getFirstName () {return firstName; } offentlig streng getLastName () {returner efternavn; } public int getSSN () {return ssn; } public boolean isMarried () {return isMarried; } offentlig LocalDate getBirthDate () {returner fødselsdato; } offentlig LocalDate getHireDate () {return hireDate; } public void setFirstName (String firstName) {this.firstName = firstName; } public void setLastName (streng efternavn) {this.lastName = efternavn; } offentligt ugyldigt 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 ("Fornavn ["); sb.append (fornavn); sb.append ("], Efternavn ["); sb.append (efternavn); sb.append ("], SSN ["); sb.append (ssn); sb.append ("], Gift ["); sb.append (isMarried); sb.append ("], fødselsdato ["); sb.append (fødselsdato); sb.append ("], Hiredate ["); sb.append (hireDate); sb.append ("]"); returner sb.toString (); }}

Kompilér lister 1 og 2 som følger:

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

Kør applikationen som følger:

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

Du skal overholde følgende output (spredt på flere linjer for læsbarhed):

{"SSN": 123456789, "birthDate": "1980-12-23", "firstName": "John", "hireDate": "2002-08-14", "lastName": "Doe", "gift" : falsk} Fornavn [John], Efternavn [Doe], SSN [123456789], Gift [falsk], Fødselsdato [1980-12-23], Hiredate [2002-08-14] 

Regler for arbejde med JSON-B

Mens jeg spillede med denne applikation, observerede jeg nogle interessante adfærd, der fik mig til at formulere følgende regler vedrørende Medarbejder:

  • Klassen skal være offentlig; Ellers kastes en undtagelse.
  • toJson () vil ikke række felter med ikke-offentlig getter metoder.
  • fraJson () vil ikke deserialisere felter med ikke-offentlig setter metoder.
  • fraJson () kaster JsonbUndtagelse i fravær af en offentligt dokument konstruktør.

For at konvertere problemfrit mellem Java-objektfelter og JSON-data problemfrit, skal JSON-B understøtte forskellige Java-typer. For eksempel understøtter JSON-B følgende grundlæggende Java-typer:

  • java.lang.Boolean
  • java.lang.Byte
  • java.lang. karakter
  • java.lang. dobbelt
  • java.lang.Float
  • java.lang. heltal
  • java.lang. lang
  • java.lang. kort
  • java.lang.Streng

Yderligere typer såsom java.math.BigInteger, java.util.Dateog java.time.LocalDate understøttes. Tjek JSON-B-specifikationen for en komplet liste over understøttede typer.

Serialisering og deserialisering af arrays og samlinger med JSON-B

Det forrige afsnit fokuserede på serialisering og deserialisering af enkelte Java-objekter. JSON-B understøtter også muligheden for at serialisere og deserialisere objektarrays og samlinger. Liste 3 giver en demonstration.

Liste 3. JSONBDemo.java (version 2)

importere java.time.LocalDate; importere java.util.ArrayList; importere java.util.Arrays; importere java.util.List; import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; offentlig klasse JSONBDemo {public static void main (String [] args) {arrayDemo (); listDemo (); } // Serialiser og deserialiser en række medarbejderobjekter. statisk ugyldigt arrayDemo () {Jsonb jsonb = JsonbBuilder.create (); Medarbejder [] medarbejdere = {ny medarbejder ("John", "Doe", 123456789, falsk, LocalDate.of (1980, 12, 23), LocalDate.of (2002, 8, 14)), ny medarbejder ("Jane" , "Smith", 987654321, true, LocalDate.of (1982, 6, 13), LocalDate.of (2001, 2, 9))}; String jsonEmployees = jsonb.toJson (medarbejdere); System.out.println (jsonMedarbejdere); System.out.println (); medarbejdere = null; medarbejdere = jsonb.fromJson (jsonEmployees, Employee []. class); for (Medarbejdermedarbejder: medarbejdere) {System.out.println (medarbejder); System.out.println (); }} // Serialiser og deserialiser en liste over medarbejderobjekter. statisk ugyldig listeDemo () {Jsonb jsonb = JsonbBuilder.create (); Liste medarbejdere = Arrays.asList (ny medarbejder ("John", "Doe", 123456789, false, LocalDate.of (1980, 12, 23), LocalDate.of (2002, 8, 14)), ny medarbejder ("Jane "," Smith ", 987654321, true, LocalDate.of (1982, 6, 13), LocalDate.of (1999, 7, 20)); String jsonEmployees = jsonb.toJson (medarbejdere); System.out.println (jsonMedarbejdere); System.out.println (); medarbejdere = null; medarbejdere = jsonb.fromJson (jsonEmployees, new ArrayList () {}. getClass (). getGenericSuperclass ()); System.out.println (medarbejdere); }}

Listing 3 er en simpel udvidelse af Listing 1 og bruger den samme Medarbejder klasse præsenteret i liste 2. Derudover kalder dette kodeeksempel det samme toJson () og fraJson () metoder.