Pemetaan Java-XML menjadi mudah dengan JAXB 2.0

Arsitektur Java untuk XML Binding menyediakan cara yang kuat dan praktis untuk bekerja dengan konten XML dari dalam aplikasi Java. JAXB 2.0 yang baru dirilis menawarkan banyak fitur baru, termasuk dukungan penuh dari semua fitur XML Schema, kelas yang dihasilkan jauh lebih sedikit, kelas yang dihasilkan lebih mudah dimanipulasi, dan mekanisme validasi yang lebih fleksibel.

Untuk memahami cara memproses dokumen XML di Java dengan JAXB 2.0, kita perlu melihat dua komponen utama JAXB:

  • Compiler pengikat, yang mengikat skema XML yang diberikan ke sekumpulan kelas Java yang dihasilkan
  • Framework waktu proses pengikatan, yang menyediakan fungsionalitas unmarshalling, marshalling, dan validasi

Compiler pengikat JAXB (atau xbj) memungkinkan Anda menghasilkan kelas Java dari skema XML yang diberikan. Compiler pengikat JAXB mengubah skema XML menjadi kumpulan kelas Java yang cocok dengan struktur yang dijelaskan dalam skema XML. Kelas-kelas ini dianotasi dengan anotasi JAXB khusus, yang menyediakan kerangka waktu proses dengan pemetaan yang dibutuhkan untuk memproses dokumen XML yang sesuai.

Kerangka kerja waktu proses yang mengikat menyediakan mekanisme yang efisien dan mudah digunakan untuk mengurai (atau membaca) dan menyusun (atau menulis) dokumen XML. Ini memungkinkan Anda mengubah dokumen XML menjadi hierarki objek Java (unmarshalling) atau, sebaliknya, mengubah hierarki objek Java ke dalam format XML (marshalling). Istilah marshalling secara tradisional mengacu pada penempatan pasukan dengan cara yang sesuai. Dalam jaringan, ini mengacu pada penempatan item data ke dalam buffer sebelum mengirimkannya melalui saluran komunikasi.

Gabungan, kedua komponen ini menghasilkan teknologi yang memungkinkan pengembang Java dengan mudah memanipulasi data XML dalam bentuk objek Java, tanpa harus mengetahui detail seluk beluk Simple API for XML Processing (SAX) atau Document Object Model (DOM) , atau bahkan seluk-beluk Skema XML.

Prasyarat JAXB

Untuk memulai dengan JAXB 2.0 Anda membutuhkan:

  • Platform Java, Edisi Standar 5: JAXB 2.0 sangat bergantung pada fitur-fitur Java SE 5, seperti anotasi dan generik
  • Implementasi JAXB 2.0

Artikel ini ditulis menggunakan kandidat rilis implementasi referensi GlassFish JAXB.

Hasilkan kelas Java menggunakan kompiler JAXB

Compiler JAXB mengikat skema XML ke sekumpulan kelas Java. Skema XML adalah dokumen XML yang mendeskripsikan, dengan sangat tepat, elemen dan atribut yang diotorisasi dalam jenis dokumen XML tertentu. Dalam contoh ini, kami menggunakan sistem pemesanan kursus pelatihan yang dapat menerima pesanan dalam format XML. Urutan tipikal terlihat seperti ini:

    10 Coyote Avenue, Arizona, USA     

Skema XML yang sesuai menjelaskan bagaimana kursus pelatihan dipesan, dan berisi rincian kursus yang dipesan, siswa yang terdaftar, perusahaan yang membuat pemesanan, dan sebagainya. Deskripsi skema XML sangat ketat dan dapat menyertakan detail seperti jumlah elemen yang diizinkan dalam daftar objek (kardinalitas), atribut opsional dan wajib, dan banyak lagi. Skema untuk pemesanan kursus pelatihan (disebut course-booking.xsd) ditampilkan di sini:

Alat baris perintah xjcmenjalankan kompiler JAXB. Untuk menjalankan compiler JAXB terhadap skema kami, kami menjalankan perintah berikut:

 $xjc course-booking.xsd -p nz.co.equinox.training.domain.booking -d src/generated

Ini akan menghasilkan satu set kelas Java yang dianotasi dengan anotasi JAXB 2.0. Beberapa dari opsi yang lebih berguna dijelaskan di sini:

  • -d : Tempatkan file yang dihasilkan ke dalam direktori ini.
  • -p : Tempatkan file yang dihasilkan dalam paket ini.
  • -nv: Jangan lakukan validasi ketat pada skema input.
  • -httpproxy : Gunakan ini jika Anda berada di belakang proxy. Mengambil format [user[:password]@]proxyHost[:proxyPort].
  • -classpath : Tentukan classpath, jika perlu.
  • -readOnly: Menghasilkan file kode sumber hanya-baca, jika OS Anda mendukung ini.

Ada juga anttugas yang setara , yang membuatnya cukup mudah untuk diintegrasikan ke dalam proses build berbasis Ant atau Maven.

Daftar kelas yang dihasilkan ditampilkan di sini:

 CompanyType.java ContactType.java CourseBooking.java ObjectFactory.java StudentType.java

Pengguna versi JAXB sebelumnya mungkin memperhatikan bahwa ini adalah kumpulan kelas Java yang dianotasi dan didokumentasikan secara lengkap, bukan kumpulan antarmuka dan implementasi yang lebih rumit dari versi sebelumnya. Jadi, kita memiliki kelas yang lebih sedikit, dan kode yang lebih ringan dan lebih elegan. Dan, seperti yang akan Anda lihat di bagian selanjutnya, memanipulasi kelas-kelas ini mudah.

Membatalkan penyusunan dokumen XML

Unmarshalling adalah proses mengonversi dokumen XML menjadi sekumpulan objek Java yang sesuai. Membatalkan marshalling di JAXB 2.0 itu mudah. Pertama, Anda membuat JAXBContextobjek konteks. Objek konteks adalah titik awal untuk operasi marshalling, unmarshalling, dan validasi. Di sini Anda menentukan paket Java yang berisi kelas yang dipetakan JAXB:

 JAXBContext jaxbContext = JAXBContext.newInstance ("nz.co.equinox.training.domain.booking");

Untuk membatalkan tanda dokumen XML, Anda membuat Unmarshallerdari konteks, seperti yang ditunjukkan di sini:

 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

The unmarshallerProses dapat XML data dari berbagai sumber data: file, masukan sungai, URL, objek DOM, parser SAX, dan banyak lagi. Di sini kami menyediakan Fileobjek sederhana yang menunjuk ke dokumen XML kami. Pengembalian unmarshalleryang diketik JAXBElement, dari mana kita bisa mendapatkan objek yang tidak diatur dengan menggunakan getValue()metode:

JAXBElement bookingElement = (JAXBElement) unmarshaller.unmarshal( new File("src/test/resources/xml/booking.xml"));

CourseBooking booking = bookingElement.getValue();

Validasi dokumen

Validasi dokumen adalah proses untuk memastikan dokumen XML Anda sesuai dengan definisi yang diberikan dalam skema XML terkait. Ini adalah aspek penting dari setiap proyek yang melibatkan pertukaran XML, terutama jika XML berasal dari sistem lain. Validasi dokumen di JAXB 2.0 lebih mudah dan lebih fleksibel dibandingkan versi sebelumnya. Anda cukup melampirkan ValidatonEventHandlerke unmarshallersebelum membatalkan penyusunan dokumen XML, seperti yang ditunjukkan di sini:

 unmarshaller.setEventHandler(new BookingValidationEventHandler());

Penangan peristiwa validasi mengimplementasikan ValidationEventHandlerantarmuka dan handleEvent()metode, seperti yang ditunjukkan di sini:

public class BookingValidationEventHandler implements ValidationEventHandler{

public boolean handleEvent(ValidationEvent ve) {

if (ve.getSeverity()==ValidationEvent.FATAL_ERROR || ve .getSeverity()==ValidationEvent.ERROR){ ValidationEventLocator locator = ve.getLocator(); //Print message from valdation event System.out.println("Invalid booking document: " + locator.getURL()); System.out.println("Error: " + ve.getMessage()); //Output line and column number System.out.println("Error at column " + locator.getColumnNumber() + ", line " + locator.getLineNumber()); } return true; } }

Here we just print details of the error, but in a real application, some less trivial treatment might be appropriate. In some cases, you may even consider that the validation error is not a show-stopper and that it will not block the processing. By returning true, you tell the unmarshaller to continue the unmarshalling process: false would terminate the process with an appropriate exception.

Marshalling a document

Marshalling involves transforming your Java classes into XML format. In JAXB 2.0, creating and manipulating these Java classes is simple. In most cases, you can just treat them like ordinary Java classes, as shown here:

 CourseBooking booking = new CourseBooking(); booking.setCourseReference("UML-101"); booking.setTotalPrice(new BigDecimal(10000)); ...

Note that you can still use the ObjectFactory class similarly to how you used it in JAXB 1.0, as shown in the following listing. However, unlike JAXB 1.0, there are no interfaces or implementation classes: all domain objects are just annotated JavaBeans components.

 ObjectFactory factory = new ObjectFactory(); CourseBooking booking = factory.createCourseBooking(); ...

Although most XML data types map directly to normal Java classes, some special treatment is needed for certain data types, such as dates. In these cases, you must use the DatatypeFactory, as shown here:

 DatatypeFactory datatypes = DatatypeFactory.newInstance(); booking.setCourseDate(datatypes.newXMLGregorianCalendarDate(2006,06,15,0));

Once your domain object is initialized, use the JAXB context to create a Marshaller object and a typed JAXBElement. Creating the marshaller is simple:

 Marshaller marshaller = jaxbContext.createMarshaller();

Selanjutnya, Anda membuat JAXBElementobjek yang merangkum objek domain Anda. Ketikan JAXBElementsesuai dengan elemen root complexTypedari dokumen XML Anda. Kemudian gunakan ObjectFactorykelas yang dihasilkan sebagai berikut:

 JAXBElement bookingElement = (new ObjectFactory()).createBooking(booking);

Dalam contoh ini, kami menetapkan properti sehingga output akan diformat untuk digunakan manusia dan kemudian menulis ke output standar:

 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal( bookingElement, System.out );

Contoh kode lengkap ditampilkan di sini:

JAXBContext jaxbContext = JAXBContext.newInstance("nz.co.equinox.training.domain.booking");

CourseBooking booking = new CourseBooking(); booking.setCourseReference("UML-101"); booking.setTotalPrice(new BigDecimal(10000)); booking.setInvoiceReference("123456"); DatatypeFactory datatypes = DatatypeFactory.newInstance(); booking.setCourseDate(datatypes.newXMLGregorianCalendarDate(2006,06,15,0)); booking.setTotalPrice(new BigDecimal(10000)); booking.setInvoiceReference("123456"); booking.getStudent().add(new StudentType()); booking.getStudent().get(0).setFirstName("John"); booking.getStudent().get(0).setSurname("Smith"); booking.setCompany(new CompanyType()); booking.getCompany().setName("Clients inc."); booking.getCompany().setContact(new ContactType()); booking.getCompany().getContact().setName("Paul"); booking.getCompany().getContact().setEmail("[email protected]"); booking.getCompany().getContact().setTelephone("12345678"); booking.getCompany().setAddress("10 client street");

// Marshal to System.out Marshaller marshaller = jaxbContext.createMarshaller(); JAXBElement bookingElement = (new ObjectFactory()).createBooking(booking); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

marshaller.marshal( bookingElement, System.out );

Menjalankan kode ini akan menghasilkan sesuatu seperti ini: