Programmering

Java-XML-kartlegging er enkelt med JAXB 2.0

Java Architecture for XML Binding gir en kraftig og praktisk måte å jobbe med XML-innhold fra Java-applikasjoner. Den nylig utgitte JAXB 2.0 tilbyr mange nye funksjoner, inkludert full støtte for alle XML Schema-funksjoner, betydelig færre genererte klasser, genererte klasser som er lettere å manipulere og en mer fleksibel valideringsmekanisme.

For å forstå hvordan du behandler XML-dokumenter i Java med JAXB 2.0, må vi se på de to viktigste JAXB-komponentene:

  • Bindingskompilatoren, som binder et gitt XML-skjema til et sett med genererte Java-klasser
  • Det bindende kjøretidsrammeverket, som gir funksjonalitet for uoppdatering, rangering og validering

JAXB-bindende kompilator (eller xbj) lar deg generere Java-klasser fra et gitt XML-skjema. JAXB-bindende kompilatoren forvandler et XML-skjema til en samling Java-klasser som samsvarer med strukturen beskrevet i XML-skjemaet. Disse klassene er merket med spesielle JAXB-merknader, som gir kjøretidsrammeverket med kartleggingen det trenger for å behandle de tilsvarende XML-dokumentene.

Det bindende kjøretidsrammeverket gir en effektiv og brukervennlig mekanisme for unmarshalling (eller lesing) og marshalling (eller skriving) av XML-dokumenter. Den lar deg forvandle et XML-dokument til et hierarki av Java-objekter (unmarshalling), eller omvendt, transformere et Java-objekthierarki til XML-format (marshalling). Begrepet marshalling refererer tradisjonelt til å disponere tropper på en passende måte. I nettverk refererer det til å plassere dataelementer i en buffer før du sender dem over en kommunikasjonskanal.

Kombinert produserer disse to komponentene en teknologi som lar Java-utviklere enkelt manipulere XML-data i form av Java-objekter uten å måtte kjenne detaljene til Simple API for XML Processing (SAX) eller Document Object Model (DOM). , eller til og med finesser i XML-skjema.

JAXB forutsetninger

For å komme i gang med JAXB 2.0 trenger du:

  • Java Platform, Standard Edition 5: JAXB 2.0 er avhengig av funksjoner i Java SE 5, for eksempel merknader og generiske
  • En implementering av JAXB 2.0

Denne artikkelen ble skrevet ved hjelp av GlassFish JAXB referanse implementeringskandidat.

Generer Java-klasser ved hjelp av JAXB-kompilatoren

JAXB-kompilatoren binder et XML-skjema til et sett med Java-klasser. Et XML-skjema er et XML-dokument som, veldig presist, beskriver elementene og attributtene som er autorisert i en bestemt type XML-dokument. I dette eksemplet bruker vi et treningskursbestillingssystem som kan godta bestillinger i XML-format. En typisk ordre ser slik ut:

    10 Coyote Avenue, Arizona, USA 

Det tilsvarende XML-skjemaet beskriver hvordan opplæringskurset er booket, og inneholder detaljer om det bestilte kurset, de påmeldte studentene, selskapet som bestiller og så videre. En XML-skjemabeskrivelse er ekstremt streng og kan inneholde detaljer som antall elementer som er tillatt i en liste over objekter (kardinalitet), valgfrie og obligatoriske attributter og mer. Skjemaet for bestilling av kurs (kalles kursbestilling.xsd) vises her:

Kommandolinjeverktøyet xjc kjører JAXB-kompilatoren. For å kjøre JAXB-kompilatoren mot skjemaet vårt, kjører vi følgende kommando:

 $ xjc kurs-booking.xsd -p nz.co.equinox.training.domain.booking -d src / generert

Dette vil generere et sett med Java-klasser kommentert med JAXB 2.0-merknader. Noen av de mer nyttige alternativene er beskrevet her:

  • -d : Plasser de genererte filene i denne katalogen.
  • -p : Plasser de genererte filene i denne pakken.
  • -nv: Ikke utfør streng validering av inngangsskjemaet.
  • -httpproxy : Bruk dette hvis du står bak en fullmektig. Tar formatet [bruker [: passord] @] proxyHost [: proxyPort].
  • -klassesti : Spesifiser klassestien, om nødvendig.
  • -les bare: Genererer skrivebeskyttede kildekodefiler hvis operativsystemet ditt støtter dette.

Det er også en ekvivalent maur oppgave, noe som gjør det ganske enkelt å integrere i en maur- eller Maven-basert byggeprosess.

Listen over genererte klasser vises her:

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

Brukere av tidligere versjoner av JAXB kan legge merke til at dette er et glatt sett med kommenterte og fullt dokumenterte Java-klasser, i stedet for det mer tungvint settet med grensesnitt og implementeringer av tidligere versjoner. Dermed har vi mindre genererte klasser, og lettere og mer elegant kode. Og som du vil se i neste avsnitt, er det enkelt å manipulere disse klassene.

Unmarshalling et XML-dokument

Unmarshalling er prosessen med å konvertere et XML-dokument til et tilsvarende sett med Java-objekter. Unmarshalling i JAXB 2.0 er enkelt. Først oppretter du en JAXBContext kontekstobjekt. Kontekstobjektet er utgangspunktet for marshalling, unmarshalling og validering. Her angir du Java-pakken som inneholder dine JAXB-tilordnede klasser:

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

For å oppheve arkivering av et XML-dokument, oppretter du et Unmarshaller fra sammenhengen, som vist her:

 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller ();

De unmarshaller kan behandle XML-data fra et bredt utvalg av datakilder: filer, inngangsstrømmer, URL-er, DOM-objekter, SAX-parsere og mer. Her gir vi en enkel Fil objekt som peker mot vårt XML-dokument. De unmarshaller returnerer en maskinskrevet JAXBElement, hvorfra vi kan få tak i vårt umarkerte objekt ved å bruke getValue () metode:

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

CourseBooking booking = bookingElement.getValue ();

Dokumentvalidering

Dokumentvalidering er prosessen for å sikre at XML-dokumentet tilsvarer definisjonen gitt i det tilsvarende XML-skjemaet. Det er et viktig aspekt av ethvert prosjekt som involverer XML-utveksling, spesielt hvis XML kommer fra andre systemer. Dokumentvalidering i JAXB 2.0 er enklere og mer fleksibel enn i tidligere versjoner. Du kan ganske enkelt legge ved en ValidatonEventHandler til unmarshaller før du fjerner XML-dokumentet, som vist her:

 unmarshaller.setEventHandler (ny BookingValidationEventHandler ());

En valideringshendelsesbehandler implementerer ValidationEventHandler grensesnitt og handleEvent () metode, som vist her:

public class BookingValidationEventHandler implementerer ValidationEventHandler {

public boolean handleEvent (ValidationEvent ve) {

hvis (ve.getSeverity () == ValidationEvent.FATAL_ERROR || ve .getSeverity () == ValidationEvent.ERROR) {ValidationEventLocator locator = ve.getLocator (); // Skriv ut melding fra valdasjonshendelsen System.out.println ("Ugyldig bestillingsdokument:" + locator.getURL ()); System.out.println ("Feil:" + ve.getMessage ()); // Utgangslinje og kolonnenummer System.out.println ("Feil ved kolonne" + locator.getColumnNumber () + ", linje" + locator.getLineNumber ()); } returner sant; }}

Her skriver vi bare ut detaljer om feilen, men i en reell applikasjon kan noe mindre triviell behandling være passende. I noen tilfeller kan du til og med vurdere at valideringsfeilen ikke er en show-stopper, og at den ikke vil blokkere behandlingen. Ved å returnere sant, forteller du unmarshaller å fortsette unmarshalling-prosessen: false ville avslutte prosessen med et passende unntak.

Marshalling et dokument

Marshalling innebærer å transformere Java-klassene dine til XML-format. I JAXB 2.0 er det enkelt å lage og manipulere disse Java-klassene. I de fleste tilfeller kan du bare behandle dem som vanlige Java-klasser, som vist her:

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

Merk at du fremdeles kan bruke ObjectFactory klasse på samme måte som hvordan du brukte den i JAXB 1.0, som vist i følgende liste. Imidlertid, i motsetning til JAXB 1.0, er det ingen grensesnitt eller implementeringsklasser: alle domeneobjekter er bare merkede JavaBeans-komponenter.

 ObjectFactory fabrikk = ny ObjectFactory (); CourseBooking booking = factory.createCourseBooking (); ...

Selv om de fleste XML-datatyper tilordnes direkte til normale Java-klasser, er det behov for spesiell behandling for visse datatyper, for eksempel datoer. I disse tilfellene må du bruke DatatypeFabrikk, som vist her:

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

Når domeneobjektet ditt er initialisert, bruk JAXB-konteksten til å opprette en Marshaller objekt og en maskinskrevet JAXBElement. Opprette marshaller er enkelt:

 Marshaller marshaller = jaxbContext.createMarshaller ();

Deretter oppretter du en JAXBElement objekt som innkapsler domenegenemnet ditt. De typede JAXBElement tilsvarer rotelementet complexType av XML-dokumentet. Bruk deretter det genererte ObjectFactory klasse som følger:

 JAXBElement bookingElement = (ny ObjectFactory ()). CreateBooking (booking);

I dette eksemplet setter vi en egenskap slik at utdataene blir formatert for menneskelig bruk og deretter skriver til standardutdata:

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

En fullstendig kodeeksempel vises her:

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

CourseBooking booking = ny CourseBooking (); booking.setCourseReference ("UML-101"); booking.setTotalPrice (ny BigDecimal (10000)); booking.setInvoiceReference ("123456"); DatatypeFactory datatypes = DatatypeFactory.newInstance (); booking.setCourseDate (datatypes.newXMLGregorianCalendarDate (2006,06,15,0)); booking.setTotalPrice (ny BigDecimal (10000)); booking.setInvoiceReference ("123456"); booking.getStudent (). legg til (ny StudentType ()); booking.getStudent (). get (0) .setFirstName ("John"); booking.getStudent (). get (0) .setSname ("Smith"); booking.setCompany (ny CompanyType ()); booking.getCompany (). setName ("Klienter inkl."); booking.getCompany (). setContact (ny ContactType ()); booking.getCompany (). getContact (). setName ("Paul"); booking.getCompany (). getContact (). setEmail ("[email protected]"); booking.getCompany (). getContact (). setTelephone ("12345678"); booking.getCompany (). setAddress ("10 klientgate");

// Marshal til System.out Marshaller marshaller = jaxbContext.createMarshaller (); JAXBElement bookingElement = (ny ObjectFactory ()). CreateBooking (booking); marshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

marshaller.marshal (bookingElement, System.out);

Å kjøre denne koden vil generere noe sånt som dette:

$config[zx-auto] not found$config[zx-overlay] not found