Pemetaan Java-XML dipermudah dengan JAXB 2.0

Java Architecture for XML Binding memberikan cara yang kuat dan praktikal untuk bekerja dengan kandungan XML dari dalam aplikasi Java. JAXB 2.0 yang baru dikeluarkan menawarkan banyak ciri baru, termasuk sokongan penuh dari semua ciri Skema XML, kelas yang dihasilkan lebih sedikit, kelas yang dihasilkan lebih mudah dimanipulasi, dan mekanisme pengesahan yang lebih fleksibel.

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

  • Penyusun mengikat, yang mengikat skema XML yang diberikan kepada sekumpulan kelas Java yang dihasilkan
  • Rangka kerja runtime yang mengikat, yang menyediakan fungsi unmarshalling, marshalling, dan validation

Penyusun pengikat JAXB (atau xbj) membolehkan anda menghasilkan kelas Java dari skema XML yang diberikan. Penyusun pengikat JAXB mengubah skema XML menjadi kumpulan kelas Java yang sesuai dengan struktur yang dijelaskan dalam skema XML. Kelas-kelas ini diberi penjelasan dengan anotasi JAXB khas, yang menyediakan kerangka kerja dengan pemetaan yang diperlukan untuk memproses dokumen XML yang sesuai.

Rangka kerja runtime yang mengikat menyediakan mekanisme yang cekap dan mudah digunakan untuk mengorek dokumen (atau membaca) dan mengumpulkan (atau menulis) dokumen XML. Ini memungkinkan anda mengubah dokumen XML menjadi hierarki objek Java (unmarshalling) atau, sebaliknya, mengubah hierarki objek Java menjadi format XML (marshalling). Istilah marshalling secara tradisional merujuk kepada membuang pasukan dengan cara yang sesuai. Dalam jaringan, ini merujuk pada menempatkan item data ke dalam penyangga sebelum mengirimnya melalui saluran komunikasi.

Gabungan, kedua komponen ini menghasilkan teknologi yang membolehkan pembangun Java dengan mudah memanipulasi data XML dalam bentuk objek Java, tanpa perlu mengetahui perincian ringkas dari Simple API for XML Processing (SAX) atau Document Object Model (DOM) , atau bahkan kehalusan Skema XML.

Prasyarat JAXB

Untuk memulakan dengan JAXB 2.0, anda memerlukan:

  • Platform Java, Edisi Standard 5: JAXB 2.0 sangat bergantung pada ciri-ciri Java SE 5, seperti anotasi dan generik
  • Pelaksanaan JAXB 2.0

Artikel ini ditulis menggunakan calon pelepasan pelaksanaan rujukan GlassFish JAXB.

Hasilkan kelas Java menggunakan penyusun JAXB

Penyusun JAXB mengikat skema XML ke sekumpulan kelas Java. Skema XML adalah dokumen XML yang menerangkan, dengan tepat, elemen dan atribut yang dibenarkan dalam jenis dokumen XML tertentu. Dalam contoh ini, kami menggunakan sistem tempahan kursus latihan yang dapat menerima pesanan dalam format XML. Pesanan biasa kelihatan seperti ini:

    10 Coyote Avenue, Arizona, USA     

Skema XML yang sesuai menerangkan bagaimana kursus latihan ditempah, dan mengandungi perincian kursus yang ditempah, pelajar yang mendaftar, syarikat yang membuat tempahan, dan sebagainya. Huraian skema XML sangat ketat dan boleh merangkumi perincian seperti bilangan elemen yang dibenarkan dalam senarai objek (kardinaliti), atribut pilihan dan wajib, dan banyak lagi. Skema untuk tempahan kursus latihan (disebut course-booking.xsd) ditunjukkan di sini:

Alat baris perintah xjcmenjalankan penyusun JAXB. Untuk menjalankan penyusun 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 diberi anotasi JAXB 2.0. Beberapa pilihan yang lebih berguna dijelaskan di sini:

  • -d : Letakkan fail yang dihasilkan ke dalam direktori ini.
  • -p : Letakkan fail yang dihasilkan dalam pakej ini.
  • -nv: Jangan lakukan pengesahan skema input yang ketat.
  • -httpproxy : Gunakan ini jika anda berada di belakang proksi. Mengambil format [user[:password]@]proxyHost[:proxyPort].
  • -classpath : Nyatakan jalan kelas, jika perlu.
  • -readOnly: Menghasilkan fail kod sumber baca sahaja, jika OS anda menyokong ini.

Terdapat juga anttugas yang setara , yang menjadikannya sangat mudah untuk disatukan ke dalam proses pembuatan yang berasaskan Ant atau Maven.

Senarai kelas yang dihasilkan ditunjukkan di sini:

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

Pengguna JAXB versi sebelumnya mungkin menyedari bahawa ini adalah sekumpulan kelas Java yang teranotasi dan didokumentasikan sepenuhnya, dan bukannya set antara muka dan pelaksanaan versi sebelumnya yang lebih rumit. Oleh itu, kami mempunyai kelas yang kurang dihasilkan, dan kod yang lebih ringan dan lebih elegan. Dan, seperti yang akan anda lihat di bahagian seterusnya, memanipulasi kelas ini mudah.

Nyahpasang dokumen XML

Unmarshalling adalah proses menukar dokumen XML menjadi sekumpulan objek Java yang sesuai. Menyahpasang dalam JAXB 2.0 adalah mudah. Pertama, anda membuat JAXBContextobjek konteks. Objek konteks adalah titik permulaan untuk operasi marshalling, unmarshalling, dan validation. Di sini anda menentukan pakej Java yang mengandungi kelas yang dipetakan JAXB anda:

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

Untuk menyahpasang dokumen XML, anda membuat Unmarshallerdari konteks, seperti yang ditunjukkan di sini:

 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

Alat ini unmarshallerdapat memproses data XML dari pelbagai sumber data: fail, aliran input, URL, objek DOM, penghurai SAX, dan banyak lagi. Di sini kami menyediakan Fileobjek sederhana yang menunjukkan dokumen XML kami. Yang unmarshallermengembalikan bertaip JAXBElement, dari mana kita boleh mendapatkan objek unmarshalled kami dengan menggunakan getValue()kaedah:

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

CourseBooking booking = bookingElement.getValue();

Pengesahan dokumen

Pengesahan dokumen adalah proses memastikan dokumen XML anda sesuai dengan definisi yang diberikan dalam skema XML yang sesuai. Ini adalah aspek penting bagi setiap projek yang melibatkan pertukaran XML, terutama jika XML berasal dari sistem lain. Pengesahan dokumen dalam JAXB 2.0 lebih mudah dan lebih fleksibel daripada versi sebelumnya. Anda hanya boleh melampirkan ValidatonEventHandlerpada unmarshallersebelum membatalkan pemasangan dokumen XML, seperti yang ditunjukkan di sini:

 unmarshaller.setEventHandler(new BookingValidationEventHandler());

Pengendali acara pengesahan menerapkan ValidationEventHandlerantara muka dan handleEvent()kaedah, 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();

Seterusnya, anda membuat JAXBElementobjek yang merangkumi objek domain anda. Diketik JAXBElementsesuai dengan elemen akar complexTypedokumen XML anda. Kemudian gunakan ObjectFactorykelas yang dihasilkan seperti berikut:

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

Dalam contoh ini, kami menetapkan harta supaya output akan diformat untuk kegunaan manusia dan kemudian menulis ke output standard:

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

Contoh kod penuh ditunjukkan 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 kod ini akan menghasilkan sesuatu seperti ini: