Baza Wiedzy

JAXB

    Czym jest JAXB🔗

    JAXB, czyli Java Architecture for XML Binding, jest specyfikacją wchodzącą w skład Javy SE pozwalającą na manipulację dokumentami XML. Najczęściej wykorzystywana jest w połączeniu ze specyfikacjami definiowania webserwisów takimi jak JAX-WS i JAX-RS.

    jaxb

    JAXB przypomina nieco frameworki do mapowania obiektowo relacyjnego takie jak Hibernate, ponieważ przy pomocy zestawu predefiniowanych adnotacji jesteśmy w stanie kontrolować wynik marshallingu do dokumentu XML i unmarshallingu do obiektu POJO. W rzeczywistości spotkamy się z takimi aplikacjami, gdzie klasa definiująca encję JPA będzie jednocześnie oznaczona dodatkowymi adnotacjami JAXB.

    Adnotacje🔗

    JAXB definiuje zestaw adnotacji, które pozwalają na konfigurację mapowania obiektów Javy. Dzięki takiemu podejściu jest to specyfikacja nieinwazyjna i mogąca być zastosowana do już istniejących, zwykłych klas POJO bez ingerencji w ich kod. Dwie najważniejsze adnotacje to:

      • @XmlRootElement - definiuje, że dana klasa może być mapowana na dokument XML
      • @XmlAccessorType - określa, czy dostęp do składowych klasy będzie odbywał się bezpośrednio, czy poprzez metody dostępowe

      Oprócz tego znajdziemy zestaw adnotacji pozwalających określić szczegóły mapowania np. @XmlTransient wyłącza dane pole z mapowania dokumentu (analogicznie jak transient przy serializacji), @XmlAttribute mapuje na atrybut XML.

      Wszystkie powyższe adnotacje znajdują się w pakiecie javax.xml.bind.annotation.

      Przykład🔗

      Stwórzmy prosty przykład mapowania obiektu do XML i odwrotnie.

      jaxb project

      Zaczynamy od stworzenia prostej klasy zgodnej z konwencją JavaBeans pamiętając o jednej ważnej rzeczy - specyfikacja JAXB wymaga obecności bezparametrowego konstruktora.

      Product.java

      package pl.javastart.model;
       
       import javax.xml.bind.annotation.XmlAccessType;
       import javax.xml.bind.annotation.XmlAccessorType;
       import javax.xml.bind.annotation.XmlRootElement;
       import javax.xml.bind.annotation.XmlTransient;
       
       @XmlRootElement
       @XmlAccessorType(XmlAccessType.FIELD)
       public class Product {
       	
       	@XmlTransient
       	private int id;
       	private String name;
       	private String producer;
       	private double price;
       	
       	public Product() {}
       	
       	public Product(int id, String name, String producer, double price) {
       		this.id = id;
       		this.name = name;
       		this.producer = producer;
       		this.price = price;
       	}
       
       	public int getId() {
       		return id;
       	}
       	public void setId(int id) {
       		this.id = id;
       	}
       	public String getName() {
       		return name;
       	}
       	public void setName(String name) {
       		this.name = name;
       	}
       	public String getProducer() {
       		return producer;
       	}
       	public void setProducer(String producer) {
       		this.producer = producer;
       	}
       	public double getPrice() {
       		return price;
       	}
       	public void setPrice(double price) {
       		this.price = price;
       	}
       
       	@Override
       	public String toString() {
       		return "Product [id=" + id 
       				+ ", name=" + name 
       				+ ", producer=" + producer
       				+ ", price=" + price + "]";
       	}
       	
       }

      Dzięki adnotacjom JAXB będzie mógł zmapować obiekty typu Product na dokumenty XML. Zauważ, że adnotacje dodaliśmy na poziomie pól klasy, ale można je dodać również na poziomie getterów. Adnotacja @XmlTransient sprawi, że wartość id nie zostanie umieszczone w docelowym XMLu.

      package pl.javastart.jaxb.marshaller;
       
       import java.io.File;
       
       import javax.xml.bind.JAXBContext;
       import javax.xml.bind.JAXBException;
       import javax.xml.bind.Marshaller;
       
       import pl.javastart.model.Product;
       
       public class MarshallerExample {
       	public static void main(String[] args) throws JAXBException {
       		JAXBContext ctx = JAXBContext.newInstance(Product.class);
       		Marshaller marshaller = ctx.createMarshaller();
       		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
       		
       		Product product = new Product(1, "Mleko", "Mlekowita", 2.5);
       		marshaller.marshal(product, new File("product.xml"));
       	}
       }

      W celu dokonania Marshallingu najpierw tworzymy kontekst JAXB, a następnie obiekt Marshaller. Możemy go dodatkowo skonfigurować - my ustawiamy wartość Marshaller.JAXB_FORMATTED_OUTPUT na true, dzięki czemu uzyskamy efekt "pretty format", czyli kod będzie czytelniejszy. Marshaller posiada wiele przeciążonych wersji metody marshal() więc możemy wynik zapisać zarówno w pliku jak i konsoli, czy dowolnym strumieniu.

      Po uruchomieniu programu utworzony zostanie plik product.xml z zawartością:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
       <product>
           <name>Mleko</name>
           <producer>Mlekowita</producer>
           <price>2.5</price>
       </product>

      Spójrzmy jeszcze na odczyt obiektu z pliku:

      package pl.javastart.jaxb.unmarshaller;
       
       import java.io.File;
       
       import javax.xml.bind.JAXBContext;
       import javax.xml.bind.JAXBException;
       import javax.xml.bind.Unmarshaller;
       
       import pl.javastart.model.Product;
       
       public class UnmarshallerExample {
       	public static void main(String[] args) throws JAXBException {
       		JAXBContext ctx = JAXBContext.newInstance(Product.class);
       		Unmarshaller unmarshaller = ctx.createUnmarshaller();
       		
       		Product product = (Product) unmarshaller.unmarshal(new File("product.xml"));
       		System.out.println(product);
       	}
       }

      Po uruchomieniu zobaczymy w konsoli wynik metody toString():

      tostring

      Projekt na Github

      Najlepszy newsletter o Javie w Polsce

      Czy chcesz otrzymywać nowości ze świata Javy oraz przykładowe pytania rekrutacyjne? Zapisz się na newsletter i bądź na bieżąco! Otrzymasz także ekskluzywne materiały oraz informacje o nowych kursach i promocjach.

      Nikomu nie udostępniamy Twojego maila, a jeśli zechcesz to w każdej chwili możesz się wypisać.

      Komentarze do artykułu

      Wyłączyliśmy możliwość dodawania komentarzy. Poniżej znajdziesz archiwalne wpisy z czasów gdy strona była jeszcze hobbystycznym blogiem. Zapraszamy natomiast do zadawnia pytań i dyskusji na naszej grupe na facebooku.