Guía de JAXB

1. Introducción

Este es un artículo introductorio sobre JAXB (Arquitectura Java para enlaces XML).

Primero, mostraremos cómo convertir objetos Java a XML y viceversa, y luego nos enfocaremos en generar clases Java a partir del esquema XML y viceversa usando el complemento JAXB-2 Maven.

2. Resumen

JAXB proporciona una manera rápida y conveniente de ordenar (escribir) objetos Java en XML y desarmar (leer) XML en objetos. Es compatible con un marco de enlace que asigna elementos y atributos XML a campos y propiedades de Java mediante anotaciones de Java.

El complemento JAXB-2 Maven delega la mayor parte de su trabajo a cualquiera de las dos herramientas proporcionadas por JDK, XJC y Schemagen.

3. Anotaciones JAXB

JAXB utiliza anotaciones de Java para aumentar las clases generadas con información adicional. Agregar tales anotaciones a las clases Java existentes las prepara para el tiempo de ejecución de JAXB.

Primero creemos un objeto Java simple para ilustrar la clasificación y la eliminación de la clasificación:

@XmlRootElement(name = "book") @XmlType(propOrder = { "id", "name", "date" }) public class Book { private Long id; private String name; private String author; private Date date; @XmlAttribute public void setId(Long id) { this.id = id; } @XmlElement(name = "title") public void setName(String name) { this.name = name; } @XmlTransient public void setAuthor(String author) { this.author = author; } // constructor, getters and setters }

La clase anterior contiene las siguientes anotaciones:

  • @XmlRootElement : el nombre del elemento raíz XML se deriva del nombre de la clase y también podemos especificar el nombre del elemento raíz del XML usando su atributo de nombre
  • @XmlType : define el orden en el que se escriben los campos en el archivo XML
  • @XmlElement : define el nombre real del elemento XML que se utilizará
  • @XmlAttribute : define que el campo de identificación se asigna como un atributo en lugar de un elemento
  • @XmlTransient : anota los campos que no queremos que se incluyan en XML

Para obtener más detalles sobre la anotación JAXB, es posible que desee consultar el siguiente enlace.

4. Marshalling: conversión de objetos Java a XML

Marshalling proporciona a una aplicación cliente la capacidad de convertir un árbol de objetos Java derivado de JAXB en datos XML. De forma predeterminada, Marshaller utiliza codificación UTF-8 al generar datos XML. A continuación, generaremos archivos XML a partir de objetos Java.

Creemos un programa simple usando JAXBContext que proporciona una abstracción para administrar la información de enlace XML / Java necesaria para implementar las operaciones del marco de enlace JAXB:

public void marshal() throws JAXBException, IOException { Book book = new Book(); book.setId(1L); book.setName("Book1"); book.setAuthor("Author1"); book.setDate(new Date()); JAXBContext context = JAXBContext.newInstance(Book.class); Marshaller mar= context.createMarshaller(); mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); mar.marshal(book, new File("./book.xml")); }

La clase javax.xml.bind.JAXBContext proporciona un punto de entrada del cliente a la API JAXB. De forma predeterminada, JAXB no formatea el documento XML. Esto ahorra espacio y evita que cualquier espacio en blanco pueda interpretarse accidentalmente como significativo.

Para que la salida tenga formato JAXB, simplemente establecemos la propiedad Marshaller.JAXB_FORMATTED_OUTPUT en true en Marshaller . El método marshal usa un objeto y un archivo de salida donde almacenar el XML generado como parámetros.

Cuando ejecutamos el código anterior, podemos verificar el resultado en book.xml para verificar que convertimos correctamente el objeto Java en datos XML:

  Book1 2016-11-12T11:25:12.227+07:00 

5. Anulación de clasificación: conversión de XML a objeto Java

La eliminación de referencias proporciona a una aplicación cliente la capacidad de convertir datos XML en objetos Java derivados de JAXB.

Usemos JAXB Unmarshaller para deshacer el ordenamiento de nuestro book.xml de nuevo a un objeto Java:

public Book unmarshall() throws JAXBException, IOException { JAXBContext context = JAXBContext.newInstance(Book.class); return (Book) context.createUnmarshaller() .unmarshal(new FileReader("./book.xml")); }

Cuando ejecutamos el código anterior, podemos verificar la salida de la consola para verificar que hemos convertido correctamente los datos XML en un objeto Java:

Book [id=1, name=Book1, author=null, date=Sat Nov 12 11:38:18 ICT 2016]

6. Tipos de datos complejos

Al manejar tipos de datos complejos que pueden no estar disponibles directamente en JAXB, podemos escribir un adaptador para indicar a JAXB cómo administrar un tipo específico.

Usando XmlAdapter de JAXB , podemos definir un código personalizado para convertir una clase no mapeable en algo que JAXB pueda manejar. La anotación @XmlJavaTypeAdapter usa un adaptador que extiende la clase XmlAdapter para el cálculo de referencias personalizado.

Creemos un adaptador para especificar un formato de fecha al calcular:

public class DateAdapter extends XmlAdapter { private static final ThreadLocal dateFormat = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } }; @Override public Date unmarshal(String v) throws Exception { return dateFormat.get().parse(v); } @Override public String marshal(Date v) throws Exception { return dateFormat.get().format(v); } }

Usamos un formato de fecha “ aaaa-MM-dd HH: mm: ss ” para convertir Date en String cuando se calcula y ThreadLocal para hacer que nuestro DateFormat sea seguro para subprocesos.

Apliquemos el DateAdapter a nuestro libro :

@XmlRootElement(name = "book") @XmlType(propOrder = { "id", "name", "date" }) public class Book { private Long id; private String name; private String author; private Date date; @XmlAttribute public void setId(Long id) { this.id = id; } @XmlTransient public void setAuthor(String author) { this.author = author; } @XmlElement(name = "title") public void setName(String name) { this.name = name; } @XmlJavaTypeAdapter(DateAdapter.class) public void setDate(Date date) { this.date = date; } }

Cuando ejecutamos el código anterior, podemos comprobar el resultado en el archivo book.xml para verificar que hemos convertido correctamente nuestro objeto Java a XML utilizando el nuevo formato de fecha " aaaa-MM-dd HH: mm: ss ":

  Book1 2016-11-10 23:44:18final 

7. Complemento JAXB-2 Maven

Este complemento utiliza la API de Java para enlaces XML (JAXB), versión 2+, para generar clases Java a partir de esquemas XML (y, opcionalmente, archivos de enlace) o para crear un esquema XML a partir de una clase Java anotada.

Tenga en cuenta que existen dos enfoques fundamentales para la creación de servicios web, Contract Last y Contract First . Para obtener más detalles sobre estos enfoques, es posible que desee consultar el siguiente enlace.

7.1. Generando una clase Java a partir de XSD

El complemento JAXB-2 Maven utiliza la herramienta XJC suministrada por JDK, una herramienta de compilación JAXB Binding que genera clases Java a partir de XSD (Definición de esquema XML).

Creemos un archivo user.xsd simple y usemos el complemento JAXB-2 Maven para generar clases Java a partir de este esquema XSD:

Configuremos el complemento JAXB-2 Maven:

 org.codehaus.mojo jaxb2-maven-plugin 2.3   xjc  xjc      src/main/resources/global.xjb   src/main/resources/user.xsd  ${basedir}/src/main/java false  

De forma predeterminada, este complemento ubica archivos XSD en src / main / xsd . Podemos configurar la búsqueda XSD modificando la sección de configuración de este complemento en pom.xml en consecuencia.

De forma predeterminada, estas clases de Java se generan en la carpeta target / generate-resources / jaxb . Podemos cambiar el directorio de salida agregando un elemento outputDirectory a la configuración del complemento. También podemos agregar un elemento clearOutputDir con un valor de false para evitar que se borren los archivos de este directorio.

También podemos configurar un enlace JAXB global que anula las reglas de enlace predeterminadas:

El global.xjb anterior anula el tipo dateTime por el tipo java.util.Calendar .

Cuando construimos el proyecto, genera archivos de clase en la carpeta src / main / java y el paquete com.baeldung.jaxb.gen .

7.2. Generando esquema XSD desde Java

The same plugin uses the JDK-supplied tool Schemagen. This is a JAXB Binding compiler tool that can generate an XSD schema from Java classes. In order for a Java Class to be eligible for an XSD schema candidate, the class must be annotated with a @XmlType annotation.

We reuse the Java class files from the previous example. Let's configure the plugin:

 org.codehaus.mojo jaxb2-maven-plugin 2.3   schemagen  schemagen      src/main/java/com/baeldung/jaxb/gen  src/main/resources false   /jaxb/gen user user-gen.xsd    

By default, JAXB scans all the folders under src/main/java recursively for annotated JAXB classes. We may specify a different source folder for our JAXB annotated classes by adding a source element to the plug-in configuration.

También podemos registrar un transformSchemas , un postprocesador responsable de nombrar el esquema XSD. Funciona haciendo coincidir el espacio de nombres con el espacio de nombres de @XmlType de su clase Java.

Cuando construimos el proyecto, genera un archivo user-gen.xsd en el directorio src / main / resources .

8. Conclusión

En este artículo, cubrimos conceptos introductorios sobre JAXB. Para más detalles, podemos echar un vistazo a la página de inicio de JAXB.

Podemos encontrar el código fuente de este artículo en GitHub.