"¡No tan rápido, jovencito! ¡Tengo dos lecciones más para ti!"

"¿Dos? Wow. Bueno, está bien. ¡Qué no harías para mejorar tu propia frialdad! Soy todo oídos".

"XML, como JSON, se usa a menudo al pasar datos entre diferentes programas y computadoras. Y hay varios marcos que simplifican enormemente la vida de los programadores de Java cuando trabajan con XML. Hoy les presentaré uno de ellos".

"JAXB es un excelente marco multipropósito para trabajar con XML".

JAXB - 1

"JAXB es parte de JDK, por lo que no necesita descargarlo por separado".

"Déjame mostrarte primero un ejemplo de cómo usarlo y luego lo analizaremos. Por ejemplo:"

Convertir un objeto a 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 clase cuyos objetos se convierten a XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}
Resultado de serialización y salida de pantalla:
<gato> 
<nombre> Señorita </nombre> 
<edad> 5 </edad> 
<peso> 4 </peso> 
</gato>

"Por alguna razón, línea por línea, este código me recuerda a la serialización JSON. Las mismas anotaciones, pero JSON usó un ObjectMapper, y este usa Context y Marshaller".

"Sí. Realmente son muy similares. Jackson se inspiró en JAXB. Pero JAXB también fue copiado de alguna parte. No se puede inventar algo genial desde cero".

"Eso parece".

"Está bien, esto es lo que sucede:"

"En las líneas 4-7, creamos un objeto Cat y lo llenamos con datos".

"En la línea 10, creamos un objeto Writer para escribir el resultado".

"En la línea 13, creamos el 'contexto'. Esto es similar a ObjectMapper, pero luego se crean dos objetos secundarios adicionales a partir de él. Marshaller es para serialización y Unmarshaller es para deserialización. Hay pequeñas diferencias con respecto a Jackson, pero es no es fundamentalmente diferente".

"En la línea 14, creamos un objeto Marshaller . Marshalling es sinónimo de serialización".

"En la línea 15, configuramos la propiedad FORMATTED_OUTPUT en VERDADERO. Esto agregará saltos de línea y espacios al resultado, de modo que el código sea legible por humanos y no solo tenga todo el texto en una línea".

"En la línea 17, serializamos el objeto".

"En las líneas 20-21, mostramos el resultado de la serialización en la pantalla".

"¿Qué son las anotaciones @XmlType(name = 'cat&') y @XmlRootElement?"

" @XmlRootElement indica que este objeto puede ser la 'raíz de un árbol' de elementos XML. En otras palabras, puede ser el elemento de más alto nivel y puede contener todos los demás elementos".

" @XmlType(name = 'cat') indica que la clase está involucrada en la serialización JAXB y también especifica el nombre de la etiqueta XML para esta clase".

"Muy bien, ahora les mostraré un ejemplo de deserialización de XML:"

Convertir un objeto de 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 clase cuyos objetos se deserializan de XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}

"Todo es casi igual que con Jackson. Pero por si acaso, te explicaré todo lo que está pasando aquí".

"En la línea 3, pasamos una cadena que almacena el XML que se deserializará".

"En la línea 4, envolvemos la cadena XML en un StringReader ".

"En la línea 6, creamos un contexto JAXB , al que le pasamos la lista de clases".

"En la línea 7, creamos un Unmarshaller , el objeto que realizará la deserialización".

"En la línea 9, deserializamos XML del objeto del lector y obtenemos un objeto Cat".

"Ahora todo parece casi obvio. Pero hace un par de horas, estaba devanándome los sesos para descubrir cómo funciona".

"Eso siempre sucede cuando te vuelves más inteligente. Las cosas complejas se vuelven simples".

"¿Me estoy volviendo más inteligente? No puedo evitar estar feliz por eso".

"Genial. Entonces aquí hay una lista de anotaciones que puede usar para controlar el resultado de la serialización JAXB:"

anotaciones JAXB Descripción
@XmlElement(nombre) Situado cerca de un campo.
El campo se almacenará en un elemento XML.
Le permite establecer el nombre de la etiqueta.
@XmlAttribute(nombre) Situado cerca de un campo.
¡El campo se almacenará como un atributo XML!
Le permite establecer el nombre del atributo.
@XmlElementWrapper(anulable = verdadero) Situado cerca de un campo.
Le permite establecer una 'etiqueta contenedora' para un grupo de elementos.
@XmlType Colocado cerca de una clase.
Le permite especificar un método para crear un objeto si el constructor predeterminado es privado.
@XmlJavaTypeAdapter Situado cerca de un campo.
Le permite especificar la clase que convertirá el campo en una cadena.

"¡Qué interesante! Pero, ¿puede darme un ejemplo que use estas anotaciones? Una explicación es una cosa, pero un ejemplo de trabajo es otra".

"Está bien. Te mostraré un ejemplo. Solo quería agregar que JAXB te permite anotar métodos getter/setter en lugar de campos".

"Aquí está ese ejemplo que prometí:"

Convertir un objeto a 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 clase cuyos objetos se convierten a 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()
 {
 }
}
Resultado de serialización y salida de pantalla:
<zoológico> 
<animales-salvajes> 
<edad del tigre = "5" w = "4"> <nombre del gato> 
Señorita</nombre del gato> </tigre> 
< 
edad del tigre = "5" w = "4"> <nombre del gato> 
Señorita </catname> 
</tigre> 
</wild-animals> 
</zoo>

"Observe que esta vez no estamos serializando un objeto Cat, sino un objeto Zoo que almacena una colección de objetos Cat".

"El objeto cat se agregó a la colección dos veces, por lo que está en el XML dos veces".

"La colección tiene su propia etiqueta de ' animales salvajes ' que envuelve todos los elementos de la colección".

"Los elementos de edad y peso se han convertido en los atributos de edad y w w".

"Usando un atributo @XmlElement , cambiamos la etiqueta de gato a una etiqueta de tigre ".

"Preste atención a la línea 17. Aquí pasamos dos clases ( Zoo y Cat ) al contexto JAXB, ya que ambas están involucradas en la serialización".

"Hoy fue un día muy interesante. Tanta información nueva".

"Sí. Me alegro por ti. Ahora, tómate un breve descanso y continuaremos".