Ohjelmointi

Java XML ja JSON: Asiakirjojen käsittely Java SE: lle, osa 2: JSON-B

Tässä artikkelissa jatkamme XML: n ja JSON: n tutkimista Java 11: ssä ja sen jälkeen.

Tässä artikkelissa esitellään JSON-B, JSON Binding API for Java. Nopean yleiskatsauksen ja asennusohjeen jälkeen näytän sinulle, miten JSON-B: tä käytetään Java-objektien, taulukoiden ja kokoelmien sarjallisuuteen ja deserialisointiin; kuinka mukauttaa sarjallisuus ja deserialisaatio JSON-B: n avulla; ja kuinka JSON-B-sovittimia käytetään lähdeobjektien muuntamiseen kohdeobjekteiksi sarjoituksen tai deserialisoinnin aikana.

Tämän artikkelin materiaali on täysin uutta, mutta sitä voidaan pitää uuden luvun (luku 13) lisänä uudelle kirjani, jonka julkaisi äskettäin Apress: Java XML ja JSON, toinen painos.

Tietoja kirjasta: Java XML ja JSON

Kuten kerroin edellisessä artikkelissani, Apress on juuri julkaissut kirjani toisen painoksen, Java XML ja JSON. On ollut ilo kirjoittaa koko kirja XML: stä ja JSONista, kahdesta tekniikasta, joita pidän enemmän täydentävinä kuin kilpailevina. Kun kirja on julkaistu, lisäsin uusia esimerkkejä luvulle 6: XML-asiakirjojen muuntaminen XSLT: llä ja luvulle 11: JSON: n käsitteleminen Jacksonin kanssa. Viimeinen artikkeli "Java XML ja JSON: Asiakirjojen käsittely Java SE: lle, osa 1" esitteli erilaisia ​​asiakirjojen muunnos- ja käsittelytekniikoita käyttäen SAXONia ja Jacksonia. Muista tutustua kyseiseen artikkeliin saadaksesi lisätietoja näistä tekniikoista.

Hanki koodi

Lataa lähdekoodi tässä opetusohjelmassa käytetyistä esimerkeistä.

Mikä on JSON-B?

JSON-B on standardi sidontakerros ja API Java-objektien muuntamiseksi JSON-asiakirjoiksi ja niistä. Se on samanlainen kuin Java Architecture for XML Binding (JAXB), jota käytetään Java-objektien muuntamiseen XML: ään ja sieltä.

JSON-B on rakennettu JSON-P: n, JSON Processing -sovellusliittymän päälle, jota käytetään JSON-asiakirjojen jäsentämiseen, luomiseen, kyselyihin ja muuntamiseen. Java Specification Request (JSR) 367 esitteli JSON-B: n yli vuoden kuluttua JSON-P: n JSR 353: n, JSR 353: n, viimeisestä julkaisemisesta.

JSON-B-sovellusliittymä

Java API for JSON Binding (JSON-B) -sivusto esittelee JSON-B: n ja tarjoaa pääsyn erilaisiin resursseihin, mukaan lukien API-dokumentaatio. Asiakirjojen mukaan JSON-B-moduuli tallentaa kuusi pakettia:

  • javax.json.bind: Määrittää lähtökohdan Java-objektien sitomiseen JSON-asiakirjoihin.
  • javax.json.bind.adapter: Määrittää sovittimeen liittyvät luokat.
  • javax.json.bind.annotation: Määrittää merkinnät Java-ohjelmaelementtien ja JSON-dokumenttien välisen kartoituksen mukauttamiseksi.
  • javax.json.bind.config: Määrittää strategiat ja käytännöt Java-ohjelmaelementtien ja JSON-dokumenttien välisen kartoituksen mukauttamiseksi.
  • javax.json.bind.serializer: Määrittää käyttöliittymät mukautettujen sarja- ja deserialisaattoreiden luomiseen.
  • javax.json.bind.spi: Määrittää palveluntarjoajan käyttöliittymän (SPI) mukautettujen laitteiden liittämistä varten JsonbRakentajas.

JSON-B-verkkosivusto tarjoaa myös linkin Yassoniin, Java-kehykseen, joka tarjoaa standardin sidontakerroksen Java-luokkien ja JSON-asiakirjojen välille, sekä JSON Binding -sovellusliittymän virallisen viitteellisen toteutuksen.

JSON-B ja Java EE 8

Kuten JSON-P, JSON-B: tä harkittiin alun perin sisällytettäväksi Java SE: hen, mutta se sisältyi sen sijaan Java EE 8 -julkaisuun. Voit silti työskennellä JSON-B: n kanssa Java SE -yhteydessä.

Lataa ja asenna JSON-B

JSON-B 1.0 on nykyinen versio kirjoitushetkellä. Voit hankkia tämän kirjaston Yasson-viitetoteutuksen Maven-arkistosta. Sinun on ladattava seuraavat JAR-tiedostot:

  • Javax JSON Bind API 1.0: Sisältää kaikki JSON-B-luokan tiedostot. Latasin javax.json.bind-api-1.0.jar.
  • Yasson: Sisältää JSON-B: n Eclipse-pohjaisen viitetoteutuksen. Latasin yasson-1.0.3.jar.
  • JSR 374 (JSON-käsittely) oletustoimittaja: Sisältää kaikki JSON-P 1.0 -luokitiedostot yhdessä Glassfish-oletuspalveluntarjoajien luokkatiedostojen kanssa. Latasin javax.json-1.1.4.jar.

Lisää nämä JAR-tiedostot luontopolulle, kun käännät ja suoritat koodia, joka käyttää näitä kirjastoja:

javac -cp javax.json.bind-api-1.0.jar ;. päälähdetiedosto java -cp javax.json.bind-api-1.0.jar; yasson-1.0.3.jar; javax.json-1.1.4.jar ;. pääluokkatiedosto

Java-objektien sarjallisuus ja deserialisointi JSON-B: llä

javax.json.bind paketti tarjoaa Jsonb ja JsonbRakentaja käyttöliittymät, jotka toimivat tämän kirjaston lähtökohtana:

  • Jsonb tarjoaa ylikuormitetun toJson () - menetelmät Java - objektien puiden sarjalliseksi JSON - asiakirjoiksi ja lähettäjäJson () menetelmät JSON-asiakirjojen deserialisoimiseksi Java-objektien puiksi.
  • JsonbRakentaja tarjoaa newBuilder () ja muut menetelmät uuden rakentajan hankkimiseksi, ja rakentaa() ja luoda() menetelmät uuden palauttamiseksi Jsonb esineitä.

Seuraava koodiesimerkki havainnollistaa Jsonb ja JsonBuilder tyypit:

// Luo uusi Jsonb-ilmentymä käyttämällä JsonbBuilder-oletustoteutusta. Jsonb jsonb = JsonbBuilder.create (); // Luo työntekijä-objekti hypoteettisesta työntekijäluokasta. Employee worker = ... // Muunna Employee-objekti merkkijonoon tallennetuksi JSON-dokumentiksi. Merkkijono jsonEmployee = jsonb.toJson (työntekijä); // Muunna aiemmin luotu JSON-asiakirja työntekijä-objektiksi. Työntekijä2 = jsonb. fromJson (jsonEmployee, Employee.class);

Tämä esimerkki käyttää Jsonbon Merkkijono toJson (objektiobjekti) menetelmä Java-objektin sarjalliseksi, (Työntekijä). Tämä menetelmä välitetään Java-objektipuun juuresta sarjoitettavaksi. Jos tyhjä on läpäisty, toJson () heittää java.lang.NullPointerException. Se heittää javax.json.bind.JsonbException kun odottamaton ongelma (kuten I / O-virhe) esiintyy sarjoituksen aikana.

Tämä koodinpätkä myös käynnistää Jsonbon J from Json (String str, luokan tyyppi) yleinen menetelmä, jota käytetään deserialisaatioon. Tämä menetelmä välitetään merkkijonopohjainen JSON-asiakirja deserialisoitavaksi ja tuloksena olevan Java-objektipuun juuriobjektin tyyppi, joka palautetaan. Tämä menetelmä heittää NullPointerException kun tyhjä välitetään jommallekummalle parametrille; se heittää JsonbException kun odottamaton ongelma ilmenee deserialisaation aikana.

Otin koodifragmentin a: sta JSONBDemo sovellus, joka tarjoaa JSON-B: n perustiedot. Listaus 1 esittää tämän esittelyn lähdekoodin.

Listaus 1. JSONBDemo.java (versio 1)

tuo java.time.LocalDate; tuo javax.json.bind.Jsonb; tuo javax.json.bind.JsonbBuilder; julkinen luokka JSONBDemo {public static void main (String [] args) {Jsonb jsonb = JsonbBuilder.create (); Työntekijä = uusi työntekijä ("John", "Doe", 123456789, false, LocalDate.of (1980, 12, 23), LocalDate.of (2002, 8, 14)); Merkkijono jsonEmployee = jsonb.toJson (työntekijä); System.out.println (jsonEmployee); System.out.println (); Työntekijä2 = jsonb. fromJson (jsonEmployee, Employee.class); System.out.println (työntekijä2); }}

main () ensin luo Jsonb esine, jota seuraa Työntekijä esine. Sitten se soittaa toJson () sarjallistaa Työntekijä vastustaa merkkijonoon tallennettua JSON-asiakirjaa. Tämän asiakirjan tulostamisen jälkeen main () vetoaa lähettäjäJson () edellisen merkkijonon kanssa ja Työntekijäon java.lang.luokka vastustaa JER-asiakirjan deserialisointia toiselle Työntekijä esine, joka myöhemmin tulostetaan.

Luettelossa 2 lahjaa Työntekijälähdekoodi.

Listaus 2. Employee.java (versio 1)

tuo java.time.LocalDate; julkinen luokka Työntekijä {yksityinen merkkijono etunimi; yksityinen merkkijono sukunimi; yksityinen int ssn; yksityinen totuusarvo on naimisissa; yksityinen LocalDate syntymäpäivä; yksityinen LocalDate hireDate; private StringBuffer sb = uusi StringBuffer (); public Employee () {} public Employee (String firstName, String lastName, int ssn, boolean isMarried, LocalDate birthDate, LocalDate hireDate) {this.esinimi = etunimi; this.sukunimi = sukunimi; tämä.ssn = ssn; this.isMarried = isMarried; this.syntymäpäivä = syntymäpäivä; this.hireDate = vuokraDate; } public String getFirstName () {return firstName; } public String getLastName () {return lastName; } public int getSSN () {return ssn; } julkinen totuusarvo onMarried () {return isMarried; } public LocalDate getBirthDate () {return birthDate; } public LocalDate getHireDate () {return hireDate; } public void setFirstName (Merkkijono etunimi) {this.firstName = etunimi; } public void setLastName (String sukunimi) {this.lastName = sukunimi; } public void setSSN (int ssn) {tämä.ssn = ssn; } public void setIsMarried (looginen isMarried) {this.isMarried = isMarried; } public void setBirthDate (LocalDate birthDate) {this.syntymäpäivä = syntymäpäivä; } public void setHireDate (LocalDate hireDate) {this.hireDate = vuokraDate; } @Override public String toString () {sb.setLength (0); sb.append ("Etunimi ["); sb.append (etunimi); sb.append ("], sukunimi ["); sb.append (sukunimi); sb.append ("], SSN ["); sb.append (ssn); sb.append ("], naimisissa ["); sb.append (isMarried); sb.append ("], syntymäpäivä ["); sb.append (syntymäpäivä); sb.append ("], Palkkaa ["); sb.append (hireDate); sb.append ("]"); return sb.toString (); }}

Kokoa luettelot 1 ja 2 seuraavasti:

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

Suorita sovellus seuraavasti:

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

Noudata seuraavaa lähtöä (luettavuuden vuoksi hajautettuna useille linjoille):

{"SSN": 123456789, "syntymäpäivä": "1980-12-23", "etunimi": "John", "hireDate": "14.8.2002", "sukunimi": "Doe", "naimisissa" : väärä} Etunimi [John], Sukunimi [Doe], SSN [123456789], Naimisissa [väärä], Syntymäpäivä [1980-12-23], Hiredate [14.8.2002] 

Säännöt JSON-B: n kanssa työskentelystä

Pelatessani tätä sovellusta huomasin mielenkiintoisia käyttäytymismalleja, jotka saivat minut muotoilemaan seuraavat säännöt Työntekijä:

  • Luokan on oltava julkinen; muuten heitetään poikkeus.
  • toJson () ei sarjoi kenttiä muilla kuinjulkinen parempia menetelmiä.
  • lähettäjäJson () ei deserialisoi kenttiä muilla kuinjulkinen setterimenetelmät.
  • lähettäjäJson () heittää JsonbException a. puuttuessa julkinen noargument rakentaja.

JSON-B: n on tuettava erilaisia ​​Java-tyyppejä voidakseen muuntaa saumattomasti Java-objektikentät ja JSON-tiedot. Esimerkiksi JSON-B tukee seuraavia Java-perustyyppejä:

  • java.lang.Boolean
  • java.lang.Byte
  • java.lang.Merkki
  • java.lang.Tupla
  • java.lang.Float
  • java.lang.I kokonaisluku
  • java.lang.pitkä
  • java.lang.Lyhyt
  • java.lang.String

Lisätyypit, kuten java.math.BigInteger, java.util.Päiväysja java.time.LocalDate ovat tuettuja. Täydellinen luettelo tuetuista tyypeistä on JSON-B-spesifikaatiossa.

Sarjojen ja deserialisoinnin taulukot ja kokoelmat JSON-B: llä

Edellisessä osassa keskityttiin yksittäisten Java-objektien sarjoitukseen ja deserialisointiin. JSON-B tukee myös kykyä sarjata ja deserialisoida objektiryhmät ja kokoelmat. Listaus 3 tarjoaa esittelyn.

Listing 3. JSONBDemo.java (versio 2)

tuo java.time.LocalDate; tuo java.util.ArrayList; tuo java.util.Arrays; tuo java.util.List; tuo javax.json.bind.Jsonb; tuo javax.json.bind.JsonbBuilder; julkinen luokka JSONBDemo {public static void main (String [] args) {arrayDemo (); listDemo (); } // Sarjaa ja deserialisoi joukko työntekijäobjekteja. staattinen void arrayDemo () {Jsonb jsonb = JsonbBuilder.create (); Työntekijä [] työntekijä = {uusi työntekijä ("John", "Doe", 123456789, false, LocalDate.of (1980, 12, 23), LocalDate.of (2002, 8, 14)), uusi työntekijä ("Jane" "Smith", 987654321, totta, LocalDate.of (1982, 6, 13), LocalDate.of (2001, 2, 9))}; Merkkijono jsonEmployees = jsonb.toJson (työntekijät); System.out.println (jsonEmployees); System.out.println (); työntekijät = nolla; työntekijät = jsonb. fromJson (jsonTyöntekijät, työntekijä []. luokka); for (Työntekijän työntekijä: työntekijät) {System.out.println (työntekijä); System.out.println (); }} // Sarjata ja poista luettelo työntekijä-objekteista. static void listDemo () {Jsonb jsonb = JsonbBuilder.create (); Luettelo työntekijöistä = Arrays.asList (uusi työntekijä ("John", "Doe", 123456789, false, LocalDate.of (1980, 12, 23), LocalDate.of (2002, 8, 14)), uusi työntekijä ("Jane "," Smith ", 987654321, tosi, LocalDate.of (1982, 6, 13), LocalDate.of (1999, 7, 20)); Merkkijono jsonEmployees = jsonb.toJson (työntekijät); System.out.println (jsonEmployees); System.out.println (); työntekijät = nolla; työntekijät = jsonb.fromJson (jsonEmployees, new ArrayList () {}. getClass (). getGenericSuperclass ()); System.out.println (työntekijät); }}

Listaus 3 on yksinkertainen Listaus 1: n laajennus ja käyttää samaa Työntekijä luokka esitetään luettelossa 2. Lisäksi tämä koodiesimerkki kutsuu samaa toJson () ja lähettäjäJson () menetelmiä.