"Non così in fretta, giovanotto! Ho altre due lezioni per te!"

"Due? Wow. Bene, okay. Cosa non faresti per migliorare la tua freddezza! Sono tutt'orecchi."

"L'XML, come JSON, viene spesso utilizzato per il trasferimento di dati tra diversi programmi e computer. E ci sono diversi framework che semplificano notevolmente la vita dei programmatori Java quando lavorano con XML. Oggi vi presenterò uno di loro."

"JAXB è un eccellente framework multiuso per lavorare con XML."

JAXB - 1

"JAXB fa parte del JDK, quindi non è necessario scaricarlo separatamente."

"Lascia che ti mostri prima un esempio di come usarlo, e poi lo analizzeremo. Ad esempio:"

Converti un oggetto in 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);
}
Una classe i cui oggetti vengono convertiti in XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}
Risultato della serializzazione e output dello schermo:
<cat> 
<name> Missy </name> 
<age> 5 </age> 
<weight> 4 </weight> 
</cat>

"Per qualche ragione, riga per riga, questo codice mi ricorda la serializzazione JSON. Le stesse annotazioni, ma JSON utilizzava un ObjectMapper e questo utilizza Context e Marshaller."

"Sì. Sono davvero molto simili. Jackson è stato modellato su JAXB. Ma anche JAXB è stato copiato da qualche parte. Non puoi inventare qualcosa di geniale da zero."

"Sembra così."

"OK, ecco cosa succede:"

"Nelle righe 4-7, creiamo un oggetto Cat e lo popoliamo con i dati."

"Nella riga 10, creiamo un oggetto Writer per scrivere il risultato."

"Nella riga 13, creiamo il 'contesto'. Questo è simile a ObjectMapper, ma da esso vengono creati due oggetti figli aggiuntivi. Marshaller è per la serializzazione e Unmarshaller è per la deserializzazione. Ci sono piccole differenze rispetto a Jackson, ma non lo è non è fondamentalmente diverso."

"Nella riga 14, creiamo un oggetto Marshaller . Il marshalling è sinonimo di serializzazione."

"Nella riga 15, impostiamo la proprietà FORMATTED_OUTPUT su TRUE. Questo aggiungerà interruzioni di riga e spazi al risultato, in modo che il codice sia leggibile dall'uomo e non contenga tutto il testo su una riga."

"Nella riga 17 serializziamo l'oggetto."

"Nelle righe 20-21, mostriamo il risultato della serializzazione sullo schermo."

"Cosa sono le annotazioni @XmlType(name = 'cat&') e @XmlRootElement?"

" @XmlRootElement indica che questo oggetto può essere la 'radice di un albero' di elementi XML. In altre parole, può essere l'elemento di livello più alto e può contenere tutti gli altri elementi."

" @XmlType(name = 'cat') indica che la classe è coinvolta nella serializzazione JAXB e specifica anche il nome del tag XML per questa classe."

"Va bene, ora ti mostrerò un esempio di deserializzazione XML:"

Converti un oggetto da 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);
}
Una classe i cui oggetti sono deserializzati da XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}

"È quasi tutto come con Jackson. Ma per ogni evenienza, spiegherò tutto quello che sta succedendo qui."

"Nella riga 3, passiamo una stringa che memorizza l'XML da deserializzare."

"Nella riga 4, avvolgiamo la stringa XML in uno StringReader ."

"Nella riga 6, creiamo un contesto JAXB , a cui passiamo l'elenco delle classi."

"Nella riga 7, creiamo un Unmarshaller , l'oggetto che eseguirà la deserializzazione."

"Nella riga 9 deserializziamo XML dall'oggetto lettore e otteniamo un oggetto Cat."

"Ora sembra tutto quasi ovvio. Ma un paio d'ore fa mi stavo scervellando per capire come funziona."

"Succede sempre quando diventi più intelligente. Le cose complesse diventano semplici."

"Sto diventando più intelligente? Non posso fare a meno di esserne felice."

"Fantastico. Quindi ecco un elenco di annotazioni che puoi utilizzare per controllare il risultato della serializzazione JAXB:"

Annotazioni JAXB Descrizione
@XmlElement(nome) Posizionato vicino a un campo.
Il campo verrà memorizzato in un elemento XML.
Consente di impostare il nome del tag.
@XmlAttribute(nome) Posizionato vicino a un campo.
Il campo verrà memorizzato come attributo XML!
Consente di impostare il nome dell'attributo.
@XmlElementWrapper(nillable = true) Posizionato vicino a un campo.
Consente di impostare un 'tag wrapper' per un gruppo di elementi.
@XmlType Posizionato vicino a una classe.
Consente di specificare un metodo per la creazione di un oggetto se il costruttore predefinito è private.
@XmlJavaTypeAdapter Posizionato vicino a un campo.
Consente di specificare la classe che convertirà il campo in una stringa.

"Che interessante! Ma puoi fornirmi un esempio che utilizza queste annotazioni? Una spiegazione è una cosa, ma un esempio funzionante è un'altra."

"OK. Ti mostrerò un esempio. Volevo solo aggiungere che JAXB ti consente di annotare metodi getter/setter anziché campi."

"Ecco l'esempio che ho promesso:"

Converti un oggetto in 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());
}
Una classe i cui oggetti vengono convertiti in 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()
 {
 }
}
Risultato della serializzazione e output dello schermo:
<zoo> 
<wild-animals> 
<tiger age = "5" w = "4"> 
<catname>Missy</catname> 
</tiger> 
<tiger age = "5" w = "4"> 
<catname>Missy </catname> 
</tiger> 
</wild-animals> 
</zoo>

"Notate che questa volta non stiamo serializzando un oggetto Cat, ma un oggetto Zoo che memorizza una collezione di oggetti Cat."

"L'oggetto gatto è stato aggiunto alla raccolta due volte, quindi è nell'XML due volte."

"La collezione ha il proprio tag ' animali selvatici ' che racchiude tutti gli elementi della collezione."

"Gli elementi età e peso sono diventati gli attributi età e w w."

"Utilizzando un attributo @XmlElement , abbiamo modificato il tag cat in un tag tiger ."

"Presta attenzione alla riga 17. Qui passiamo due classi ( Zoo e Cat ) al contesto JAXB, poiché sono entrambe coinvolte nella serializzazione."

"Oggi è stata una giornata molto interessante. Tante nuove informazioni."

"Sì. Sono felice per te. Adesso prenditi una piccola pausa e continuiamo."