Προγραμματισμός

Java XML και JSON: Επεξεργασία εγγράφων για Java SE, Μέρος 2: JSON-B

Σε αυτό το άρθρο, θα συνεχίσουμε να εξερευνούμε XML και JSON στην Java 11 και μετά.

Παραδείγματα σε αυτό το άρθρο θα σας παρουσιάσουν στο JSON-B, το JSON Binding API για Java. Μετά από μια γρήγορη επισκόπηση και οδηγίες εγκατάστασης, θα σας δείξω πώς να χρησιμοποιήσετε το JSON-B για να σειριοποιήσετε και να αποστειρώσετε αντικείμενα Java, πίνακες και συλλογές. πώς να προσαρμόσετε τη σειριοποίηση και την αποεστερίωση χρησιμοποιώντας το JSON-B; και πώς να χρησιμοποιήσετε προσαρμογείς JSON-B για τη μετατροπή αντικειμένων προέλευσης σε αντικείμενα στόχευσης κατά τη σειριοποίηση ή την αποεπιλογή.

Το υλικό για αυτό το άρθρο είναι εντελώς νέο, αλλά θα μπορούσε να θεωρηθεί ένα πρόσθετο κεφάλαιο (Κεφάλαιο 13) για το νέο μου βιβλίο, το οποίο εκδόθηκε πρόσφατα από την Apress: Java XML και JSON, Δεύτερη Έκδοση.

Σχετικά με το βιβλίο: Java XML και JSON

Όπως μοιράστηκα στο προηγούμενο άρθρο μου, η Apress μόλις δημοσίευσε τη δεύτερη έκδοση του βιβλίου μου, Java XML και JSON. Ήταν χαρά μου να γράψω ένα ολόκληρο βιβλίο για XML και JSON, δύο τεχνολογίες που θεωρώ πιο συμπληρωματικές παρά ανταγωνιστικές. Μετά τη δημοσίευση του βιβλίου, πρόσθεσα νέα παραδείγματα για το Κεφάλαιο 6: Μετασχηματισμός εγγράφων XML με XSLT και για το Κεφάλαιο 11: Επεξεργασία JSON με τον Τζάκσον. Το τελευταίο μου άρθρο, "Java XML και JSON: Επεξεργασία εγγράφων για το Java SE, Μέρος 1" εισήγαγε μια ποικιλία τεχνικών μετασχηματισμού και επεξεργασίας εγγράφων χρησιμοποιώντας τα SAXON και Jackson. Φροντίστε να δείτε αυτό το άρθρο για να μάθετε περισσότερα σχετικά με αυτές τις τεχνικές.

Λάβετε τον κωδικό

Κατεβάστε τον πηγαίο κώδικα για παραδείγματα που χρησιμοποιούνται σε αυτό το σεμινάριο.

Τι είναι το JSON-B;

JSON-Β είναι ένα τυπικό δεσμευτικό επίπεδο και API για τη μετατροπή αντικειμένων Java σε και από έγγραφα JSON. Είναι παρόμοιο με το Java Architecture for XML Binding (JAXB), το οποίο χρησιμοποιείται για τη μετατροπή αντικειμένων Java από και προς XML.

Το JSON-B είναι χτισμένο πάνω από το JSON-P, το JSON Processing API που χρησιμοποιείται για την ανάλυση, τη δημιουργία, την αναζήτηση και τη μετατροπή εγγράφων JSON. Το JSON-B εισήχθη από το Java Specification Request (JSR) 367 περισσότερο από ένα χρόνο μετά την τελική κυκλοφορία του JSR 353, το JSR για JSON-P.

Το API JSON-B

Ο ιστότοπος Java API for JSON Binding (JSON-B) παρουσιάζει το JSON-B και παρέχει πρόσβαση σε διάφορους πόρους, συμπεριλαμβανομένης της τεκμηρίωσης API. Σύμφωνα με την τεκμηρίωση, η μονάδα JSON-B αποθηκεύει έξι πακέτα:

  • javax.json.bind: Καθορίζει το σημείο εισόδου για τη δέσμευση αντικειμένων Java σε έγγραφα JSON.
  • javax.json.bind.adapter: Ορίζει τάξεις που σχετίζονται με τον προσαρμογέα.
  • javax.json.bind.annotation: Ορίζει σχολιασμούς για την προσαρμογή της αντιστοίχισης μεταξύ στοιχείων προγράμματος Java και εγγράφων JSON.
  • javax.json.bind.config: Καθορίζει στρατηγικές και πολιτικές για την προσαρμογή της αντιστοίχισης μεταξύ στοιχείων προγράμματος Java και εγγράφων JSON.
  • javax.json.bind.serializer: Καθορίζει διασυνδέσεις για τη δημιουργία προσαρμοσμένων σειριακοποιητών και deserializer.
  • javax.json.bind.spi: Ορίζει μια διεπαφή παρόχου υπηρεσιών (SPI) για σύνδεση σε προσαρμοσμένο JsonbBuilderμικρό.

Ο ιστότοπος JSON-B παρέχει επίσης έναν σύνδεσμο προς το Yasson, ένα πλαίσιο Java που παρέχει ένα τυπικό επίπεδο δέσμευσης μεταξύ τάξεων Java και εγγράφων JSON, και μια επίσημη εφαρμογή αναφοράς του JSON Binding API.

JSON-B και Java EE 8

Όπως το JSON-P, το JSON-B θεωρήθηκε αρχικά για συμπερίληψη στο Java SE, αλλά συμπεριλήφθηκε στην έκδοση Java EE 8. Ωστόσο, μπορείτε να εργαστείτε με το JSON-B σε περιβάλλον Java SE.

Λήψη και εγκατάσταση του JSON-B

Το JSON-B 1.0 είναι η τρέχουσα έκδοση κατά τη στιγμή της σύνταξης. Μπορείτε να αποκτήσετε την εφαρμογή αναφοράς Yasson αυτής της βιβλιοθήκης από το αποθετήριο Maven. Θα χρειαστεί να κατεβάσετε τα ακόλουθα αρχεία JAR:

  • Javax JSON Bind API 1.0: Περιέχει όλα τα αρχεία κλάσεων JSON-B. κατέβασα javax.json.bind-api-1.0.jar.
  • Yasson: Περιέχει την εφαρμογή αναφοράς που βασίζεται στο Eclipse του JSON-B. κατέβασα yasson-1.0.3.jar.
  • Προεπιλεγμένος πάροχος JSR 374 (Επεξεργασία JSON): Περιέχει όλα τα αρχεία κατηγορίας JSON-P 1.0 μαζί με τα προεπιλεγμένα αρχεία κατηγορίας παρόχου Glassfish. κατέβασα javax.json-1.1.4.jar.

Προσθέστε αυτά τα αρχεία JAR στο classpath σας κατά τη σύνταξη και εκτέλεση κώδικα που χρησιμοποιεί αυτές τις βιβλιοθήκες:

javac -cp javax.json.bind-api-1.0.jar ;. κύριο αρχείο προέλευσης java -cp javax.json.bind-api-1.0.jar; yasson-1.0.3.jar; javax.json-1.1.4.jar ;. κύριο classfile

Σειριοποίηση και αποεστερίωση αντικειμένων Java με JSON-B

ο javax.json.bind το πακέτο παρέχει το Τζόνμπ και JsonbBuilder διεπαφές, οι οποίες χρησιμεύουν ως σημείο εισόδου σε αυτήν τη βιβλιοθήκη:

  • Τζόνμπ παρέχει υπερφορτωμένο toJson () μέθοδοι για την σειριοποίηση δέντρων αντικειμένων Java σε έγγραφα JSON και από τον Json () μέθοδοι για την αποεστερίωση εγγράφων JSON σε δέντρα αντικειμένων Java.
  • JsonbBuilder παρέχει newBuilder () και άλλες μεθόδους για την απόκτηση ενός νέου δημιουργού, και χτίζω() και δημιουργώ() μέθοδοι για την επιστροφή νέων Τζόνμπ αντικείμενα.

Το ακόλουθο παράδειγμα κώδικα δείχνει τη βασική χρήση του Τζόνμπ και JsonBuilder τύποι:

// Δημιουργήστε μια νέα παρουσία Jsonb χρησιμοποιώντας την προεπιλεγμένη εφαρμογή JsonbBuilder. Jsonb jsonb = JsonbBuilder.create (); // Δημιουργήστε ένα αντικείμενο υπαλλήλου από μια υποθετική τάξη υπαλλήλων. Υπάλληλος υπαλλήλου = ... // Μετατρέψτε το αντικείμενο υπαλλήλου σε ένα έγγραφο JSON που είναι αποθηκευμένο σε μια συμβολοσειρά String jsonEm Employee = jsonb.toJson (υπάλληλος); // Μετατρέψτε το έγγραφο JSON που δημιουργήθηκε προηγουμένως σε ένα αντικείμενο υπαλλήλου. Υπάλληλος2 = jsonb.fromJson (jsonEm Employee, Employee.class);

Αυτό το παράδειγμα επικαλείται Τζόνμπ'μικρό String toJson (Αντικείμενο αντικειμένου) μέθοδος σειριοποίησης ενός αντικειμένου Java, (Υπάλληλος). Αυτή η μέθοδος περνά τη ρίζα του δέντρου αντικειμένου Java για σειριοποίηση. Αν μηδενικό Πέρασε, toJson () ρίχνει java.lang.NullPointerException. Ρίχνει javax.json.bind.JsonbException όταν προκύπτει ένα μη αναμενόμενο πρόβλημα (όπως σφάλμα I / O) κατά τη σειριοποίηση.

Αυτό το τμήμα κώδικα επικαλείται επίσης Τζόνμπ'μικρό T fromJson (String str, τύπος κλάσης) γενική μέθοδος, η οποία χρησιμοποιείται για την αποεστεροποίηση. Αυτή η μέθοδος περνά το έγγραφο JSON που βασίζεται σε συμβολοσειρά για αποεπιλογή και τον τύπο του ριζικού αντικειμένου του δέντρου αντικειμένου Java που προκύπτει, που επιστρέφεται. Αυτή η μέθοδος ρίχνει NullPointerException πότε μηδενικό μεταβιβάζεται σε οποιαδήποτε από τις παραμέτρους. ρίχνει JsonbException όταν προκύπτει ένα απροσδόκητο πρόβλημα κατά την αποεστερίωση.

Απόσπασα το κομμάτι κώδικα από ένα JSONBDemo εφαρμογή που παρέχει μια βασική επίδειξη του JSON-B. Η λίστα 1 παρουσιάζει τον πηγαίο κώδικα για αυτήν την επίδειξη.

Λίστα 1. JSONBDemo.java (έκδοση 1)

εισαγωγή java.time.LocalDate; εισαγωγή javax.json.bind.Jsonb; εισαγωγή javax.json.bind.JsonbBuilder; δημόσια τάξη JSONBDemo {public static void main (String [] args) {Jsonb jsonb = JsonbBuilder.create (); Υπάλληλος υπαλλήλου = νέος υπάλληλος ("John", "Doe", 123456789, false, LocalDate.of (1980, 12, 23), LocalDate.of (2002, 8, 14)); String jsonEm Employee = jsonb.toJson (υπάλληλος); System.out.println (jsonEm Employee); System.out.println (); Υπάλληλος2 = jsonb.fromJson (jsonEm Employee, Employee.class); System.out.println (υπάλληλος2); }}

κύριος() δημιουργεί πρώτα ένα Τζόνμπ αντικείμενο που ακολουθείται από ένα Υπάλληλος αντικείμενο. Στη συνέχεια καλεί toJson () για σειριοποίηση του Υπάλληλος αντικείμενο σε ένα έγγραφο JSON που είναι αποθηκευμένο σε μια συμβολοσειρά. Μετά την εκτύπωση αυτού του εγγράφου, κύριος() επικαλείται από τον Json () με την προηγούμενη συμβολοσειρά και Υπάλληλος'μικρό java.lang.Class αντικείμενο να αποστρατειοποιήσει το έγγραφο JSON σε άλλο Υπάλληλος αντικείμενο, το οποίο στη συνέχεια εκτυπώνεται.

Η λίστα 2 παρουσιάζει ΥπάλληλοςΟ πηγαίος κώδικας.

Λίστα 2. Employee.java (έκδοση 1)

εισαγωγή java.time.LocalDate; δημόσιος κλάδος Υπάλληλος {private String firstName; ιδιωτική συμβολοσειρά επώνυμο; ιδιωτικό int ssn; ιδιωτικό boolean isMarried; ιδιωτικό LocalDate BirthDate; ιδιωτικό LocalDate hireDate; ιδιωτικό StringBuffer sb = νέο StringBuffer (); δημόσιος υπάλληλος () {} δημόσιος υπάλληλος (String firstName, String lastName, int ssn, boolean isMarried, LocalDate BirthDate, LocalDate hireDate) {this.firstName = firstName; this.lastName = επώνυμο; αυτό.ssn = ssn; this.isMarried = isMarried; this.birthDate = ημερομηνία γέννησης; this.hireDate = hireDate; } δημόσια συμβολοσειρά getFirstName () {return firstName; } δημόσια συμβολοσειρά getLastName () {return lastName; } δημόσιο int getSSN () {return ssn; } δημόσια boolean isMarried () {return isMarried; } δημόσια LocalDate getBirthDate () {return BirthDate; } δημόσιο LocalDate getHireDate () {return hireDate; } public void setFirstName (συμβολοσειρά firstName) {this.firstName = firstName; } public void setLastName (συμβολοσειρά τελευταίο όνομα) {this.lastName = lastName; } δημόσιο άκυρο 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 ("Όνομα ["]; sb.append (όνομα πρώτου); sb.append ("], Επώνυμο ["); sb.append (επώνυμο); sb.append ("], SSN ["); sb.append (ssn); sb.append ("], Παντρεμένος ["); sb.append (isMarried); sb.append ("], ημερομηνία γέννησης ["); sb.append (ημερομηνία γέννησης); sb.append ("], Hiredate ["); sb.append (hireDate); sb.append ("]"); επιστροφή sb.toString (); }}

Συγκεντρώστε τις λίστες 1 και 2 ως εξής:

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

Εκτελέστε την εφαρμογή ως εξής:

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

Θα πρέπει να παρατηρήσετε την ακόλουθη έξοδο (διασκορπισμένη σε πολλές γραμμές για αναγνωσιμότητα):

{"SSN": 123456789, "BirthDate": "1980-12-23", "firstName": "John", "hireDate": "2002-08-14", "lastName": "Doe", "παντρεμένος" : false} Όνομα [John], επώνυμο [Doe], SSN [123456789], παντρεμένο [false], ημερομηνία γέννησης [1980-12-23], Hiredate [2002-08-14] 

Κανόνες για τη συνεργασία με το JSON-B

Παίζοντας με αυτήν την εφαρμογή, παρατήρησα μερικές ενδιαφέρουσες συμπεριφορές που με οδήγησαν στη διατύπωση των ακόλουθων κανόνων σχετικά Υπάλληλος:

  • Η τάξη πρέπει να είναι δημόσιο; Διαφορετικά, απορρίπτεται μια εξαίρεση.
  • toJson () δεν θα σειριοποιήσει πεδία με μηδημόσιο μεθόδους λήψης.
  • από τον Json () δεν θα αποστειρώσει πεδία με μηδημόσιο μέθοδοι ρύθμισης.
  • από τον Json () ρίχνει JsonbException απουσία α δημόσιο επιχείρημα κατασκευαστής.

Προκειμένου να γίνει απρόσκοπτη μετατροπή μεταξύ πεδίων αντικειμένων Java και δεδομένων JSON, το JSON-B πρέπει να υποστηρίζει διάφορους τύπους Java. Για παράδειγμα, το JSON-B υποστηρίζει τους ακόλουθους βασικούς τύπους Java:

  • java.lang.Boolean
  • java.lang.Byte
  • java.lang.Character
  • java.lang. Διπλό
  • java.lang.Float
  • java.lang.Integer
  • java.lang.Long
  • java.lang.Short
  • java.lang.String

Πρόσθετοι τύποι όπως java.math.BigInteger, java.util. Ημερομηνία, και java.time.LocalDate υποστηρίζονται. Ρίξτε μια ματιά στις προδιαγραφές JSON-B για μια πλήρη λίστα υποστηριζόμενων τύπων.

Σειριοποίηση και αποεστερίωση συστοιχιών και συλλογών με το JSON-B

Η προηγούμενη ενότητα επικεντρώθηκε στη σειριοποίηση και την αποεστερίωση μεμονωμένων αντικειμένων Java. Το JSON-B υποστηρίζει επίσης τη δυνατότητα σειριοποίησης και αποεστερίωσης συστοιχιών και συλλογών αντικειμένων. Η λίστα 3 παρέχει μια επίδειξη.

Λίστα 3. JSONBDemo.java (έκδοση 2)

εισαγωγή java.time.LocalDate; εισαγωγή java.util.ArrayList; εισαγωγή java.util.Arrays; εισαγωγή java.util.List; εισαγωγή javax.json.bind.Jsonb; εισαγωγή javax.json.bind.JsonbBuilder; δημόσια τάξη JSONBDemo {public static void main (String [] args) {arrayDemo (); listDemo (); } // Σειριοποιήστε και αποστειρώστε μια σειρά αντικειμένων υπαλλήλων. static void arrayDemo () {Jsonb jsonb = JsonbBuilder.create (); Υπάλληλος [] υπαλλήλους = {νέος Υπάλληλος ("John", "Doe", 123456789, false, LocalDate.of (1980, 12, 23), LocalDate.of (2002, 8, 14)), νέος Υπάλληλος ("Jane" , "Smith", 987654321, true, LocalDate.of (1982, 6, 13), LocalDate.of (2001, 2, 9))}; String jsonEm Employees = jsonb.toJson (υπάλληλοι); System.out.println (jsonEm Employees); System.out.println (); υπάλληλοι = null; υπαλλήλους = jsonb.fromJson (jsonEm Employees, Employee []. class); για (Υπάλληλος: εργαζόμενος) {System.out.println (υπάλληλος); System.out.println (); }} // Σειριοποιήστε και αποστειρώστε μια λίστα αντικειμένων υπαλλήλων. static void listDemo () {Jsonb jsonb = JsonbBuilder.create (); Λίστα υπαλλήλων = Arrays.asList (νέος υπάλληλος ("John", "Doe", 123456789, false, LocalDate.of (1980, 12, 23), LocalDate.of (2002, 8, 14)), νέος υπάλληλος ("Jane "," Smith ", 987654321, true, LocalDate.of (1982, 6, 13), LocalDate.of (1999, 7, 20))); String jsonEm Employees = jsonb.toJson (υπάλληλοι); System.out.println (jsonEm Employees); System.out.println (); υπάλληλοι = null; υπαλλήλους = jsonb.fromJson (jsonEm Employees, new ArrayList () {}. getClass (). getGenericSuperclass ()); System.out.println (εργαζόμενοι); }}

Η Λίστα 3 είναι μια απλή επέκταση της Καταχώρισης 1 και χρησιμοποιεί την ίδια Υπάλληλος τάξη που παρουσιάζεται στην καταχώριση 2. Επιπλέον, αυτό το παράδειγμα κώδικα καλεί το ίδιο toJson () και από τον Json () μεθόδους.