JAXB – ještě bližší propojení Javy a XML
Java i XML jsou technologie, které se často používají pro komunikaci mezi aplikacemi na různých operačních systémech. Proto je v Javě řada možností, jak s XML daty pracovat, např. SAX, DOM atd.. Jednou z dalších technologií provazující Javu s XML je i JAXB (Java Architecture for XML Binding), jejíž použití si ukážeme na praktických příkladech. JAXB nabízí metody pro konverzi XML dat na Java objekty a naopak, a umožňuje zápis a čtení XML z mnoha různých zdrojů, například ze souboru, streamu, nebo z URL. V tomto článku si na několika příkladech ukážeme, jak se s JAXB pracuje.
Java i XML jsou technologie, které se často používají pro komunikaci mezi aplikacemi na různých operačních systémech. Proto je v Javě řada možností, jak s XML daty pracovat, např. SAX, DOM atd.. Jednou z dalších technologií provazující Javu s XML je i JAXB (Java Architecture for XML Binding), jejíž použití si ukážeme na praktických příkladech. JAXB nabízí metody pro konverzi XML dat na Java objekty a naopak, a umožňuje zápis a čtení XML z mnoha různých zdrojů, například ze souboru, streamu, nebo z URL. V tomto článku si na několika příkladech ukážeme, jak se s JAXB pracuje.
Budeme se zabývat JAXB verze 2.0 a vyšší. Verze 2.0 je kompatibilní s JDK 5 a je součástí JDK 6. Aktuální verze je 2.2 a najdete ji v JDK 7. Všechno co potřebujeme se nachází v balíku javax.xml.bind
.
Příklad 1: Převod Java objektu na XML dokument a naopak
Aby mohly být objekty určité třídy transformovatelné do XML dokumentů, tak je minimálně potřeba, aby měla příslušná třída bezparametrický konstruktor a byla anotována anotací @XmlRootElement
. Tato anotace označuje, že se objekty dané třídy (či výčtové typy) budou transformovat do XML dokumentu jako XML elementy. Tato anotace může být dále použita ve spojení s anotacemi @XmlType
, @XmlEnum
, @XmlAccessorType
a@XmlAccessorOrder
, jejichž význam lze dohledat například zde.
Vzorová Java třída:
package jaxb; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Product { private String name; private float price; public Product() { } public Product(String name, float price) { this.name = name; this.price = price; } ... }
K dispozici je však mnohem více dalších anotací, například:
... @XmlElementWapper(name="cars") @XmlElement(name="car") private ArrayList<Car> cars; ...
vytvoří po transformaci do XML takovouto strukturu:
<cars> <car> ... </car> <car> ... </car> ... </cars>
Všechny objekty třídy Car
v kolekci “cars” jsou transformováný na elementy <car>...</car>
a zabaleny do wraperu <cars>...</cars>
.
Při samotném převodu vytvoříme nejdříve JAXBContext pomocí metody JAXBContext.newInstance(...)
. Jako parametr uvádíme třídy, které má kontext rozpoznávat. Uvádíme je pomocí seznamu Class tříd, nebo pomoci Stringu obsahujícího dvojtečkou oddělená jména balíčků s třídami. Potom vytvoříme marshaller, který se stará o převod příslušných Java objektů do XML, podle potřeby ho nastavíme (v příkladu nastavíme formát výstupu) a již můžeme provést samotný převod.
Kód pro převod objektů vzorové třídy Product
do XML:
package jaxb; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; public class Main { /** * @param args * @throws JAXBException */ public static void main(String[] args) { try { // vytvoříme JAXBContext - jen jednou, je to časově náročnější JAXBContext jc = JAXBContext.newInstance(Product.class); // Marshaller převádí do XML Marshaller m = jc.createMarshaller(); // nastavení formátování m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // převod do XML m.marshal(new Product("chleba", 20.5f), System.out); } catch (JAXBException e) { e.printStackTrace(); } } ... }
Pro opačný převod z XML do java objektu budeme postupovat podobně, jen místo marshalleru vytvoříme unmarshaller.
... Unmarshaller u = jc.createUnmarshaller(); Object element = u.unmarshal(new File("abc.xml")); ...
V tomto případě bychom načítali XML data ze souboru “abc.xml”.
Příklad 2: generování tříd z XML schématu
Často máme na začátku projektu XML schéma, ze kterého musíme vycházet. JAXB nám pomůže vygenerovat java třídy pomocí kompilátoru schémat a dále postupujeme stejně jako v prvním příkladu. Kompilátor je také součástí JDK.
Generování tříd ze schématu:
xjc schema.xsd
Chování kompilátoru můžeme řídit pomocí parametrů a pluginů. Například při spuštění xjc schema.xsd -Xsync-methods
budou vygenerované metody označené jako synchronized a při spuštění xjc -classpath plugin.jar -Xplugin
, kde Xplugin je název pluginu, se použije plugin z dodaného souboru.
Validace
XML můžeme také validovat vůči danému schématu, a to pomocí metody setSchema(Schema schema)
zavolané na Marshalleru nebo Unmarshalleru.
Rozšíření
Existuje i mnoho doplňků, například Hyperjaxb3, které nabízí perzistenci pro JAXB objekty (ukládání a načítání z relační databáze).
Shrnutí
Jak vidíte, použití JAXB je velice snadné a pohodlné a stojí proto za to zvážit jeho použití místo SAX nebo DOM přístupu. Výhoda JAXB je především v jeho jednoduchosti. Zároveň je však robustním nástrojem, který poskytuje vývojářům rozsáhlé možnosti. Zde jsme si na několika jednoduchých příkladech ukázali jeho základní možnosti. Bližší a podrobnější informace lze nalézt například na následujících odkazech.
- Video přímo od vývojářů
- JAXB Reference Implementation Project – zde najdete dokumentaci, tutorial, seznam pluginů
- Wikipedia – základní údaje, tabulka mapování XML typů na Java typy, další odkazy
- javax.xml.bind API
- Seznam anotací