Volver al blog

Java Architecture for XML Binding (JAXB) Example

Resumen Técnico & Objetivo

Cuando se implementa un Web Service se utiliza otra API para convertir de forma automática de XML a objetos; esto es muy útil cuando la definición del Web service es cambiante. ...


Cuando se implementa un Web Service se utiliza otra API para convertir de forma automática de XML a objetos; esto es muy útil cuando la definición del Web service es cambiante. JAXB está presente a partir de la versión 1.6 del JDK. En esta entrega se demostrará cómo pasar de un XML Schema a Objetos Java y Viceversa.

Entorno de Trabajo

  • Apache Maven 3.3.3
  • JDK 1.8

Crear el proyecto

Se crea el proyecto Maven con el arquetipo maven-archetype-quickstart el cual creará un proyecto vacío

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes
-DgroupId=online.saidmlx.example.webservice
-DarchetypeArtifactId=maven-archetype-quickstart 
-DarchetypeVersion=1.0
-DartifactId=jaxb-example 
-DinteractiveMode=false

Configurar el pom.xml

Dentro del archivo de configuración hay que agregar el plugin maven-jaxb2-plugin.

El punto a resaltar aquí es que dentro del tag configuration se declara el directorio destino donde se depositaran las clases resultado.

<plugin>
  <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.14.0</version>
    <executions>
      <execution>
        <id>generate</id>
        <goals>
          <goal>generate</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <generateDirectory>${project.basedir}/src/main/generated/</generateDirectory>
  </configuration>
</plugin>

Declarando el XML Schema

La idea es tomar de la datos Abierta Northwind la tabla Products y crear un XML Schema dentro del directorio src/main/resources/.

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.saidmlx.online/database/northwind/products"
    xmlns:saidmlx="http://www.saidmlx.online/database/northwind/products"
    elementFormDefault="qualified">
 
  <element name="products" type="saidmlx:Products"></element>
  <complexType name="Products">
    <sequence>
      <element name="product_name" type="string" minOccurs="1" maxOccurs="1" />
      <element name="supplier_id" type="int" minOccurs="1" maxOccurs="1" />
      <element name="category" type="saidmlx:Categories" minOccurs="1" maxOccurs="1" />
      <element name="quantity_per_unit" type="string" minOccurs="1" maxOccurs="1" />
      <element name="unit_price" type="float" minOccurs="1" maxOccurs="1" />
      <element name="units_in_stock" type="int" minOccurs="1" maxOccurs="1" />
      <element name="units_on_order" type="int" minOccurs="1" maxOccurs="1" />
      <element name="reorder_level"	type="int" minOccurs="1" maxOccurs="1" />
      <element name="discontinued" type="int" minOccurs="1" maxOccurs="1" />
    </sequence>
    <attribute name="product_id" type="saidmlx:ID"></attribute>
  </complexType>
  
  <simpleType name="ID">
    <restriction base="int">
      <pattern value="[0-9]*"></pattern>
    </restriction>
  </simpleType>

  <complexType name="Categories">
    <all>
      <element name="category_id" type="int" />
      <element name="category_name" type="string" />
      <element name="description" type="string" />  
    </all>
  </complexType> 
</schema>

Generando los recursos

Para generar el XML Schema a objetos no es más que ejecutar el plugin con ayuda del Maven.

 mvn generate-sources

Y con eso nos realizará la siguiente estructura de clases.

src/main/generated/
├── META-INF
   └── sun-jaxb.episode
├── online
   └── saidmlx
       └── database
           └── northwind
               └── products
                   ├── Categories.java
                   ├── ObjectFactory.java
                   ├── Products.java
                   └── package-info.java
└── org
    └── w3
        └── _2001
            └── xmlschema
                └── Adapter1.java

Marshaling

El concepto de Marshaling es el proceso de Serialización(Marshal) corresponde al proceso de convertir un objeto XML a objetos y Deserialización (Unmarshal) que es el proceso de convertir de XML a objeto.

Para ese proceso de Marshaling se escribe la clase online.saidmlx.database.northwind.marshalling.Demo

package online.saidmlx.database.northwind.marshalling;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import online.saidmlx.database.northwind.products.Categories;
import online.saidmlx.database.northwind.products.Products;

public class Demo {

  public static void main(String[] args) {
  try {
    //-- fill data
    Products products = new Products();
    products.setProductId(1);
    products.setProductName("Chai");
    products.setSupplierId(8);
    products.setCategory(new Categories());
    products.getCategory().setCategoryId(1);
    products.getCategory().setCategoryName("Beverages");
    products.getCategory().setDescription("Soft drinks, coffees, teas, beers, and ales");
    products.setQuantityPerUnit("10 boxes x 30 bags");
    products.setUnitPrice(18);
    products.setUnitsInStock(39);
    products.setUnitsOnOrder(0);
    products.setReorderLevel(10);
    products.setDiscontinued(1);

    //-- Marshaling
    JAXBContext context= JAXBContext.newInstance(Products.class);			
    Marshaller marshaler = context.createMarshaller();
    StringWriter writer = new StringWriter();
    marshaler.marshal(products, writer);
    System.out.println(writer.toString());

    //-- Unmarshalling
    Unmarshaller unmarshaler = context.createUnmarshaller();
    Products productsResult = (Products)unmarshaler.unmarshal(new StringReader(writer.toString()));
    System.out.print(productsResult.getCategory().getDescription());

  } catch (JAXBException e) {
    e.printStackTrace();
  }
  }

}

Resultado

Y el proyecto está listo si ejecutamos la clase online.saidmlx.database.northwind.marshalling.Demo tendremos el resultado

Marshaling

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<products product_id="1"
xmlns="http://www.saidmlx.online/database/northwind/products">
  <product_name>Chai</product_name>
  <supplier_id>8</supplier_id>
  <category>
    <category_id>1</category_id>
    <category_name>Beverages</category_name>
    <description>Soft drinks, coffees, teas, beers, and ales</description>
  </category>
  <quantity_per_unit>10 boxes x 30 bags</quantity_per_unit>
  <unit_price>18.0</unit_price>
  <units_in_stock>39</units_in_stock>
  <units_on_order>0</units_on_order>
  <reorder_level>10</reorder_level>
  <discontinued>1</discontinued>
</products>

Unmarshaling

Que corresponde a la propiedad productsResult.getCategory().getDescription()

Soft drinks, coffees, teas, beers, and ales

Si lo que quieres es el codigo aqui{:target=“_blank”} esta

Documentación

Java Architecture for XML Binding (JAXB){:target=“_blank”}

Maven Quickstart Archetype {:target=“_blank”}

JAXB2 Maven Plugin {:target=“_blank”}