„Nie tak szybko, młody człowieku! Mam dla ciebie jeszcze dwie lekcje!”

„Dwa? Wow. Cóż, dobrze. Czego byś nie zrobił, żeby poprawić swój spokój! Zamieniam się w słuch”.

„XML, podobnie jak JSON, jest często używany przy przekazywaniu danych między różnymi programami i komputerami. Istnieje kilka frameworków, które znacznie upraszczają życie programistów Javy podczas pracy z XML. Dzisiaj przedstawię wam jeden z nich”.

„JAXB to doskonała wielozadaniowa platforma do pracy z XML”.

JAXB - 1

„JAXB jest częścią JDK, więc nie musisz go pobierać osobno”.

„Pozwól, że najpierw pokażę ci przykład, jak go użyć, a potem go przeanalizujemy. Na przykład:”

Konwertuj obiekt na XML
public static void main(String[] args) throws JAXBException
{
 // Create an object to be serialized into XML
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // Create a Marshaller object that will perform the serialization
 JAXBContext context = JAXBContext.newInstance(Cat.class);
 Marshaller marshaller = context.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 // And here's the serialization itself:
 marshaller.marshal(cat, writer);

 // Convert everything written to the StringWriter
 String result = writer.toString();
 System.out.println(result);
}
Klasa, której obiekty są konwertowane na format XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}
Wynik serializacji i wyjście ekranu:
<cat> 
<name> Missy </name> 
<wiek> 5 </age> 
<waga> 4 </waga> 
</cat>

„Z jakiegoś powodu, linia po linii, ten kod przypomina mi serializację JSON. Te same adnotacje, ale JSON użył ObjectMapper, a to używa kontekstu i Marshallera”.

„Tak. Naprawdę są bardzo podobni. Jackson był wzorowany na JAXB. Ale JAXB też skądś skopiowano. Nie można wymyślić czegoś genialnego od podstaw”.

— Na to wygląda.

„OK, oto co się dzieje:”

„W liniach 4-7 tworzymy obiekt Cat i wypełniamy go danymi”.

„W wierszu 10 tworzymy obiekt Writer, aby zapisać wynik”.

„W linii 13 tworzymy„ kontekst ”. Jest to podobne do ObjectMapper, ale następnie tworzone są z niego dwa dodatkowe obiekty potomne. Marshaller służy do serializacji, a Unmarshaller do deserializacji. Istnieją niewielkie różnice w stosunku do Jacksona, ale nie zasadniczo się nie różni”.

„W linii 14 tworzymy obiekt Marshaller . Marshalling jest synonimem serializacji”.

„W wierszu 15 ustawiliśmy właściwość FORMATTED_OUTPUT na PRAWDA. Spowoduje to dodanie końca linii i spacji do wyniku, dzięki czemu kod będzie czytelny dla człowieka i nie będzie zawierał całego tekstu w jednym wierszu”.

„W linii 17 serializujemy obiekt”.

„W wierszach 20-21 wyświetlamy wynik serializacji na ekranie”.

„Co to są adnotacje @XmlType(name = 'cat&') i @XmlRootElement?”

" @XmlRootElement wskazuje, że ten obiekt może być 'korzeniem drzewa' elementów XML. Innymi słowy, może to być element najwyższego poziomu i może zawierać wszystkie inne elementy."

" @XmlType(name = 'cat') wskazuje, że klasa jest zaangażowana w serializację JAXB, a także określa nazwę tagu XML dla tej klasy."

„W porządku, teraz pokażę ci przykład deserializacji XML:”

Konwertuj obiekt z XML
public static void main(String[] args) throws JAXBException
{
 String xmldata = "<cat><name>Missy</name><age>5</age><weight>4</weight></cat>";
 StringReader reader = new StringReader(xmldata);

 JAXBContext context = JAXBContext.newInstance(Cat.class);
 Unmarshaller unmarshaller = context.createUnmarshaller();

 Cat cat = (Cat) unmarshaller.unmarshal(reader);
}
Klasa, której obiekty są deserializowane z XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}

„Wszystko jest prawie takie samo jak z Jacksonem. Ale na wszelki wypadek wyjaśnię wszystko, co się tutaj dzieje”.

„W wierszu 3 przekazujemy ciąg , który przechowuje XML do deserializacji”.

„W linii 4 zawijamy ciąg XML w StringReader ”.

„W linii 6 tworzymy kontekst JAXB , do którego przekazujemy listę klas.”

„W wierszu 7 tworzymy obiekt Unmarshaller — obiekt, który wykona deserializację”.

„W wierszu 9 deserializujemy XML z obiektu czytelnika i otrzymujemy obiekt Cat”.

„Teraz wszystko wydaje się prawie oczywiste. Ale kilka godzin temu męczyłem się, żeby dowiedzieć się, jak to działa”.

„Tak się dzieje zawsze, gdy stajesz się mądrzejszy. Złożone rzeczy stają się proste”.

„Staję się mądrzejszy? Nic na to nie poradzę, że jestem z tego powodu szczęśliwy”.

„Świetnie. Oto lista adnotacji, których możesz użyć do kontrolowania wyniku serializacji JAXB:”

Adnotacje JAXB Opis
@XmlElement(nazwa) Położony w pobliżu pola.
Pole zostanie zapisane w elemencie XML.
Pozwala ustawić nazwę tagu.
@XmlAttribute(nazwa) Położony w pobliżu pola.
Pole zostanie zapisane jako atrybut XML!
Pozwala ustawić nazwę atrybutu.
@XmlElementWrapper(brak możliwości = prawda) Położony w pobliżu pola.
Pozwala ustawić „tag opakowania” dla grupy elementów.
@XmlTyp Umieszczony w pobliżu klasy.
Pozwala określić metodę tworzenia obiektu, jeśli domyślnym konstruktorem jest prywatny.
@XmlJavaTypeAdapter Położony w pobliżu pola.
Pozwala określić klasę, która przekonwertuje pole na łańcuch.

„Jakie to interesujące! Ale czy możesz podać mi przykład wykorzystujący te adnotacje? Wyjaśnienie to jedno, ale działający przykład to coś innego”.

„OK. Pokażę ci przykład. Chciałem tylko dodać, że JAXB pozwala ci dodawać adnotacje do metod pobierających/ustawiających zamiast pól”.

„Oto ten przykład, który obiecałem:”

Konwertuj obiekt na XML
public static void main(String[] args) throws JAXBException
{
 // Create Cat and Zoo objects to be serialized into XML
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 Zoo zoo = new Zoo();
 zoo.animals.add(cat);
 zoo.animals.add(cat);

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // Create a Marshaller object that will perform the serialization
 JAXBContext context = JAXBContext.newInstance(Cat.class, Zoo.class);
 Marshaller marshaller = context.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 // Here's the serialization itself
 marshaller.marshal(zoo, writer);

 // Convert everything written to the StringWriter into a String
 System.out.println(writer.toString());
}
Klasa, której obiekty są konwertowane na format XML
@XmlType(name = "zoo")
@XmlRootElement
public class Zoo
{
 @XmlElementWrapper(name = "wild-animals", nillable = true)
 @XmlElement(name = "tiger")
 public List<Cat> animals = new ArrayList<>();
}

public class Cat
{
 @XmlElement(name = "catname")
 public String name;
 @XmlAttribute(name = "age")
 public int age;
 @XmlAttribute(name = "w")
 public int weight;

 public Cat()
 {
 }
}
Wynik serializacji i wyjście ekranu:
<zoo> 
<dzikie zwierzęta> 
<wiek tygrysa = "5" w = "4"> <nazwa kota> 
Missy</nazwa kota> </tygrys> 
< 
wiek tygrysa = "5" w = "4"> <nazwa kota 
>Missy </catname> 
</tiger> 
</dzikie-zwierzęta> 
</zoo>

„Zauważ, że tym razem nie serializujemy obiektu Cat, ale obiekt Zoo, który przechowuje kolekcję obiektów Cat”.

„Obiekt cat został dodany do kolekcji dwukrotnie, więc dwukrotnie znajduje się w pliku XML”.

„Kolekcja ma swój własny znacznik„ dzikie zwierzęta ”, który obejmuje wszystkie elementy kolekcji”.

„ Elementy wieku i wagi stały się atrybutami wieku i w w”.

„Korzystając z atrybutu @XmlElement , zmieniliśmy tag cat na tag tygrysa ”.

„Zwróć uwagę na linię 17. Tutaj przekazujemy dwie klasy ( Zoo i Cat ) do kontekstu JAXB, ponieważ obie są zaangażowane w serializację”.

„Dzisiejszy dzień był bardzo interesujący. Tyle nowych informacji”.

„Tak. Cieszę się twoim szczęściem. A teraz zrób sobie krótką przerwę i będziemy kontynuować”.