Programování

Snadné mapování Java-XML s JAXB 2.0

Java Architecture for XML Binding poskytuje výkonný a praktický způsob práce s obsahem XML z aplikací Java. Nově vydaný JAXB 2.0 nabízí mnoho nových funkcí, včetně plné podpory všech funkcí schématu XML, výrazně méně generovaných tříd, generovaných tříd, se kterými se snadněji manipuluje, a flexibilnější mechanismus ověřování.

Abychom pochopili, jak zpracovávat dokumenty XML v Javě pomocí JAXB 2.0, musíme se podívat na dvě hlavní komponenty JAXB:

  • Kompilátor vazeb, který váže dané schéma XML na sadu generovaných tříd Java
  • Rámec vazby runtime, který poskytuje funkce unmarshalling, marshalling a validace

Kompilátor vazeb JAXB (nebo xbj) umožňuje generovat třídy Java z daného schématu XML. Kompilátor vazeb JAXB transformuje schéma XML do kolekce tříd Java, které odpovídají struktuře popsané ve schématu XML. Tyto třídy jsou opatřeny poznámkami se speciálními poznámkami JAXB, které poskytují běhovému prostředí mapování, které potřebuje ke zpracování odpovídajících dokumentů XML.

Rámec vazby runtime poskytuje efektivní a snadno použitelný mechanismus pro oddělování (nebo čtení) a zařazování (nebo psaní) dokumentů XML. Umožňuje vám transformovat dokument XML do hierarchie objektů Java (unmarshalling) nebo naopak transformovat hierarchii objektů Java do formátu XML (marshalling). Termín seřaďování tradičně označuje nakládání s vojáky nějakým vhodným způsobem. V sítích se jedná o umístění datových položek do vyrovnávací paměti před jejich odesláním přes komunikační kanál.

V kombinaci tyto dvě komponenty vytvářejí technologii, která umožňuje vývojářům Java snadno manipulovat s daty XML ve formě objektů Java, aniž by museli znát hloupé detaily Simple API pro XML Processing (SAX) nebo Document Object Model (DOM). nebo dokonce jemnosti schématu XML.

Předpoklady JAXB

Abyste mohli začít s JAXB 2.0, potřebujete:

  • Java Platform, Standard Edition 5: JAXB 2.0 do značné míry spoléhá na funkce prostředí Java SE 5, jako jsou anotace a generika
  • Implementace JAXB 2.0

Tento článek byl napsán pomocí kandidáta na vydání referenční implementace GlassFish JAXB.

Generujte třídy Java pomocí kompilátoru JAXB

Kompilátor JAXB váže schéma XML na sadu tříd Java. Schéma XML je dokument XML, který velmi přesně popisuje prvky a atributy povolené v určitém typu dokumentu XML. V tomto příkladu používáme rezervační systém školení, který může přijímat objednávky ve formátu XML. Typická objednávka vypadá takto:

    10 Coyote Avenue, Arizona, USA 

Odpovídající schéma XML popisuje, jak je školicí kurz rezervován, a obsahuje podrobnosti o rezervovaném kurzu, zapsaných studentech, společnosti provádějící rezervaci atd. Popis schématu XML je extrémně přísný a může obsahovat podrobnosti, jako je počet povolených prvků v seznamu objektů (mohutnost), volitelné a povinné atributy a další. Schéma pro rezervace školení (tzv rezervace kurzu.xsd) je zobrazen zde:

Nástroj příkazového řádku xjc spustí kompilátor JAXB. Chcete-li spustit kompilátor JAXB proti našemu schématu, spustíme následující příkaz:

 $ xjc kurz-booking.xsd -p nz.co.equinox.training.domain.booking -d src / generováno

Tím se vygeneruje sada tříd Java anotovaných anotacemi JAXB 2.0. Zde jsou popsány některé z užitečnějších možností:

  • -d : Umístěte vygenerované soubory do tohoto adresáře.
  • -p : Umístěte vygenerované soubory do tohoto balíčku.
  • -nv: Neprovádějte přísné ověření vstupního schématu.
  • -httpproxy : Použijte toto, pokud jste za proxy. Vezme formát [uživatel [: heslo] @] proxyHost [: proxyPort].
  • -classpath : V případě potřeby zadejte cestu ke třídě.
  • -pouze ke čtení: Generuje soubory zdrojového kódu jen pro čtení, pokud to váš operační systém podporuje.

Existuje také ekvivalent mravenec úkol, díky kterému je docela snadné se integrovat do procesu sestavování založeného na Ant nebo Maven.

Seznam vygenerovaných tříd je uveden zde:

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

Uživatelé předchozích verzí JAXB si mohou všimnout, že se jedná o úhlednou sadu anotovaných a plně zdokumentovaných tříd Java, spíše než o těžkopádnější sadu rozhraní a implementací předchozích verzí. Máme tedy méně generované třídy a lehčí a elegantnější kód. A jak uvidíte v další části, manipulace s těmito třídami je snadná.

Zrušení sdílení dokumentu XML

Unmarshalling je proces převodu dokumentu XML na odpovídající sadu objektů Java. Unmarshalling v JAXB 2.0 je snadný. Nejprve vytvoříte a JAXBContext kontextový objekt. Kontextový objekt je výchozím bodem pro operace zařazování, oddělování a ověřování. Zde určíte balíček Java obsahující vaše třídy mapované JAXB:

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

Chcete-li zrušit zařazení dokumentu XML, vytvoříte Unmarshaller z kontextu, jak je znázorněno zde:

 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller ();

The marshaller může zpracovávat data XML z nejrůznějších zdrojů dat: soubory, vstupní toky, adresy URL, objekty DOM, analyzátory SAX a další. Zde poskytujeme jednoduché Soubor objekt ukazující na náš dokument XML. The marshaller vrací zadaný JAXBElement, ze kterého můžeme získat náš nespojený objekt pomocí getValue () metoda:

JAXBElement bookingElement = (JAXBElement) unmarshaller.unmarshal (nový soubor ("src / test / resources / xml / booking.xml"));

CourseBooking booking = bookingElement.getValue ();

Ověření dokladu

Ověření dokumentu je proces zajišťování toho, aby váš dokument XML odpovídal definici dané v příslušném schématu XML. Je to důležitý aspekt každého projektu zahrnujícího výměny XML, zvláště pokud XML pochází z jiných systémů. Ověření dokumentu v JAXB 2.0 je jednodušší a flexibilnější než v předchozích verzích. Můžete jednoduše připojit a ValidatonEventHandler do marshaller před zrušením sdílení dokumentu XML, jak je znázorněno zde:

 unmarshaller.setEventHandler (nový BookingValidationEventHandler ());

Obslužná rutina události ověření implementuje ValidationEventHandler rozhraní a handleEvent () metoda, jak je znázorněno zde:

veřejná třída BookingValidationEventHandler implementuje ValidationEventHandler {

public boolean handleEvent (ValidationEvent ve) {

if (ve.getSeverity () == ValidationEvent.FATAL_ERROR || ve .getSeverity () == ValidationEvent.ERROR) {ValidationEventLocator locator = ve.getLocator (); // Tisk zprávy z valdační události System.out.println ("Neplatný rezervační dokument:" + locator.getURL ()); System.out.println ("Chyba:" + ve.getMessage ()); // Číslo výstupního řádku a sloupce System.out.println ("Chyba ve sloupci" + locator.getColumnNumber () + ", řádek" + locator.getLineNumber ()); } návrat true; }}

Zde pouze tiskneme podrobnosti o chybě, ale ve skutečné aplikaci může být vhodné nějaké méně triviální zacházení. V některých případech můžete dokonce zvážit, že chyba ověření není stop-show a že nebude blokovat zpracování. Když se vrátíte pravdivě, řeknete to marshaller pokračovat v procesu oddělování: false by ukončil proces s příslušnou výjimkou.

Zařazování dokumentu

Marshalling zahrnuje transformaci vašich tříd Java do formátu XML. V JAXB 2.0 je vytváření a manipulace s těmito třídami Java jednoduché. Ve většině případů s nimi můžete zacházet jako s běžnými třídami Java, jak je znázorněno zde:

 Rezervace CourseBooking = nový CourseBooking (); booking.setCourseReference ("UML-101"); booking.setTotalPrice (nový BigDecimal (10 000)); ...

Všimněte si, že stále můžete použít ObjectFactory třída podobně, jak jste ji použili v JAXB 1.0, jak je znázorněno v následujícím seznamu. Na rozdíl od JAXB 1.0 však neexistují žádná rozhraní ani implementační třídy: všechny objekty domény jsou pouze anotované komponenty JavaBeans.

 ObjectFactory factory = nový ObjectFactory (); Rezervace CourseBooking = factory.createCourseBooking (); ...

Přestože se většina datových typů XML mapuje přímo na normální třídy Java, je u určitých datových typů, jako jsou data, nutné zvláštní zacházení. V těchto případech musíte použít Datový typFactory, jak je znázorněno zde:

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

Jakmile je váš doménový objekt inicializován, použijte kontext JAXB k vytvoření Marshaller objekt a napsaný JAXBElement. Vytváření seřaďovač je jednoduchý:

 Marshaller marshaller = jaxbContext.createMarshaller ();

Dále vytvoříte JAXBElement objekt, který zapouzdřuje váš doménový objekt. Napsaný JAXBElement odpovídá kořenovému prvku complexType vašeho XML dokumentu. Poté použijte vygenerovaný ObjectFactory třída takto:

 JAXBElement bookingElement = (nový ObjectFactory ()). CreateBooking (rezervace);

V tomto příkladu nastavíme vlastnost tak, aby byl výstup formátován pro lidské použití a poté zapsán na standardní výstup:

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

Celý ukázkový kód je zobrazen zde:

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

Rezervace CourseBooking = nový CourseBooking (); booking.setCourseReference ("UML-101"); booking.setTotalPrice (nový BigDecimal (10 000)); booking.setInvoiceReference ("123456"); DatatypeFactory datatypes = DatatypeFactory.newInstance (); booking.setCourseDate (datatypes.newXMLGregorianCalendarDate (2006,06,15,0)); booking.setTotalPrice (nový BigDecimal (10 000)); booking.setInvoiceReference ("123456"); booking.getStudent (). add (nový StudentType ()); booking.getStudent (). get (0) .setFirstName ("John"); booking.getStudent (). get (0) .setSurname ("Smith"); booking.setCompany (new CompanyType ()); booking.getCompany (). setName ("vč. klientů"); booking.getCompany (). setContact (nový 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 = (nový ObjectFactory ()). CreateBooking (rezervace); marshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

marshaller.marshal (bookingElement, System.out);

Spuštění tohoto kódu vygeneruje něco takového:

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