Java Architecture for XML Binding (JAXB) Example
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 esta