"Nu atât de repede, tinere! Mai am două lecții pentru tine!"

"Doi? Wow. Ei bine, bine. Ce nu ai face pentru a-ți spori propria răcoare! Sunt urechile."

"XML, ca JSON, este adesea folosit atunci când se transmit date între diferite programe și computere. Și există mai multe cadre care simplifică foarte mult viața programatorilor Java atunci când lucrează cu XML. Astăzi vă voi prezenta unul dintre ele."

„JAXB este un cadru multifuncțional excelent pentru lucrul cu XML.”

JAXB - 1

„JAXB face parte din JDK, așa că nu trebuie să îl descărcați separat.”

„Permiteți-mi să vă arăt mai întâi un exemplu de utilizare, apoi îl vom analiza. De exemplu:”

Convertiți un obiect în 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);
}
O clasă ale cărei obiecte se convertesc în XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}
Rezultatul serializării și rezultatul ecranului:
<cat> 
<nume> Missy </name> 
<vârsta > 5 </vârstă 
> <greutate> 4 </greutate> 
</pisica>

„Din anumite motive, linie cu linie, acest cod îmi amintește de serializarea JSON. Aceleași adnotări, dar JSON a folosit un ObjectMapper, iar acesta folosește Context și Marshaller.”

"Da. Sunt într-adevăr foarte asemănătoare. Jackson a fost modelat după JAXB. Dar și JAXB a fost copiat de undeva. Nu poți inventa ceva genial de la zero."

— Așa pare.

„OK, iată ce se întâmplă:”

„În rândurile 4-7, creăm un obiect Cat și îl populăm cu date.”

„În linia 10, creăm un obiect Writer pentru a scrie rezultatul.”

„În linia 13, creăm „contextul”. Acesta este similar cu ObjectMapper, dar apoi sunt create două obiecte copil suplimentare din el. Marshaller este pentru serializare, iar Unmarshaller este pentru deserializare. Există mici diferențe față de Jackson, dar nu este. nu e fundamental diferit.”

"În linia 14, creăm un obiect Marshaller . Marshalling este un sinonim pentru serializare."

„În linia 15, am setat proprietatea FORMATTED_OUTPUT la TRUE. Acest lucru va adăuga rupturi de linie și spații la rezultat, astfel încât codul să fie citit de om și să nu aibă doar tot textul pe o singură linie.”

„În linia 17, serializăm obiectul”.

„În rândurile 20-21, afișăm rezultatul serializării pe ecran”.

„Care sunt adnotările @XmlType(name = 'cat&') și @XmlRootElement?"

@XmlRootElement indică faptul că acest obiect poate fi „rădăcina unui arbore” a elementelor XML. Cu alte cuvinte, poate fi elementul de cel mai înalt nivel și poate conține toate celelalte elemente.”

" @XmlType(name = 'cat') indică faptul că clasa este implicată în serializarea JAXB și, de asemenea, specifică numele etichetei XML pentru această clasă."

„Bine, acum vă voi arăta un exemplu de deserializare XML:”

Convertiți un obiect din 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);
}
O clasă ale cărei obiecte sunt deserializate din XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}

"Totul este aproape la fel ca cu Jackson. Dar pentru orice eventualitate, o să explic tot ce se întâmplă aici."

„În linia 3, trecem un șir care stochează XML-ul pentru a fi deserializat.”

„În linia 4, împachetăm șirul XML într-un StringReader .”

„În linia 6, creăm un context JAXB , căruia îi trecem lista de clase.”

„În linia 7, creăm un Unmarshaller — obiectul care va efectua deserializarea.”

„În linia 9, deserializăm XML din obiectul cititor și obținem un obiect Cat.”

„Acum, totul pare aproape evident. Dar acum câteva ore, îmi făceam creierul să-mi dau seama cum funcționează.”

"Asta se întâmplă întotdeauna când devii mai inteligent. Lucrurile complexe devin simple."

"Devin mai deștept? Nu pot să nu fiu fericit de asta."

„Genial. Atunci iată o listă de adnotări pe care le puteți folosi pentru a controla rezultatul serializării JAXB:”

adnotări JAXB Descriere
@XmlElement(nume) Amplasat lângă un câmp.
Câmpul va fi stocat într-un element XML.
Vă permite să setați numele etichetei.
@XmlAttribute(nume) Amplasat lângă un câmp.
Câmpul va fi stocat ca atribut XML!
Vă permite să setați numele atributului.
@XmlElementWrapper (nillable = adevărat) Amplasat lângă un câmp.
Vă permite să setați o „etichetă wrapper” pentru un grup de elemente.
@XmlType Amplasat lângă o clasă.
Vă permite să specificați o metodă pentru crearea unui obiect dacă constructorul implicit este privat.
@XmlJavaTypeAdapter Amplasat lângă un câmp.
Vă permite să specificați clasa care va converti câmpul într-un șir.

"Ce interesant! Dar îmi puteți oferi un exemplu care folosește aceste adnotări? O explicație este una, dar un exemplu de lucru este altceva."

"OK. Vă voi arăta un exemplu. Am vrut doar să adaug că JAXB vă permite să adnotați metode getter/setter în loc de câmpuri."

„Iată exemplul pe care l-am promis:”

Convertiți un obiect în 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());
}
O clasă ale cărei obiecte se convertesc în 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()
 {
 }
}
Rezultatul serializării și rezultatul ecranului:
<zoo> 
<wild-animals> 
<tiger age = "5" w = "4"> 
<catname>Missy</catname> 
</tiger> 
<tiger age = "5" w = "4"> 
<catname>Missy </catname> 
</tiger> 
</wild-animals> 
</zoo>

„Rețineți că de data aceasta nu serializăm un obiect Cat, ci un obiect Zoo care stochează o colecție de obiecte Cat.”

„Obiectul pisică a fost adăugat la colecție de două ori, deci este de două ori în XML.”

„Colecția are propria etichetă „ animale sălbatice ” care învelește toate elementele colecției.”

„Elementele de vârstă și greutate au devenit atributele de vârstă și w w.”

„Folosind un atribut @XmlElement , am schimbat eticheta de pisică într-o etichetă de tigru .”

„Fii atent la linia 17. Aici trecem două clase ( Zoo și Cat ) în contextul JAXB, deoarece ambele sunt implicate în serializare.”

"Astăzi a fost o zi foarte interesantă. Atât de multe informații noi."

"Da. Mă bucur pentru tine. Acum, ia o scurtă pauză și vom continua."