JAXB (Java Architecture for XML Binding) nos proporciona una API que nos permite mapear (mapping) entre documentos XML y objetos Java automaticamente. Será con este framework que llevaremos a cabo la serialización de un objeto Java en un fichero (que será un documento XML) persistiendo el estado del objeto, además de crear un objeto Java a partir de un documento XML (recuperando el estado que tenia dicho objeto al ser serializado).
Crearemos las siguientes clases:
1. Clase Localidad
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@XmlType class Localidad{ private String nombre; private int cp; public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public int getCp() { return cp; } public void setCp(int cp) { this.cp = cp; } } |
2. Clase Provincia
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@XmlRootElement class Provincia { private String nombre; private Localidad[] localidad; public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public Localidad[] getLocalidad() { return localidad; } public void setLocalidad(Localidad[] localidad) { this.localidad = localidad; } } |
Nada fuera de lo normal en estas clases salvo las annotations presentes.
@XmlType: Indica a JAXB que debería generar un tipo de dato XML schema a partir de un tipo de dato Java.
@XmlRootElement: Indica que JAXB debería generar un documento XML (la raíz) a partir de una clase Java
Por ultimo la clase con el main donde se llevará a cabo la serialización/deserialización de los objetos
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
package examples.serialization; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; public class JAXBSerializationExample { private static final String PROVINCIA_DAT_FILE = "provincia.dat"; public static void main(String[] args) throws JAXBException, IOException { JAXBContext context = JAXBContext.newInstance(Provincia.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); Provincia provincia = fillProvincia(); //Mostramos el documento XML generado por la salida estandar marshaller.marshal(provincia, System.out); FileOutputStream fos = new FileOutputStream(PROVINCIA_DAT_FILE); //guardamos el objeto serializado en un documento XML marshaller.marshal(provincia, fos); fos.close(); Unmarshaller unmarshaller = context.createUnmarshaller(); //Deserealizamos a partir de un documento XML Provincia provincaAux = (Provincia) unmarshaller.unmarshal(new File(PROVINCIA_DAT_FILE)); System.out.println("********* Provincia cargado desde fichero XML***************"); //Mostramos por linea de comandos el objeto Java obtenido //producto de la deserialziacion marshaller.marshal(provincaAux, System.out); } private static Provincia fillProvincia(){ String[] nombreLocalidad = {"Madrid", "Coslada"}; int[] cpLocalidad = {28028, 28820}; Localidad[] localidades = new Localidad[2]; for(int i=0; i<2; i++){ localidades[i] = new Localidad(); localidades[i].setCp(cpLocalidad[i]); localidades[i].setNombre(nombreLocalidad[i]); } Provincia provincia = new Provincia(); provincia.setNombre("Madrid"); provincia.setLocalidad(localidades); return provincia; } } |
Como pueden ver resulta bastante sencillo la serialización de objetos a XML, quizás aquí no podamos apreciar todo su potencial, pero les puedo mencionar que es justo esto lo que utiliza el framework jax-ws en los servicios web SOAP con tipos de datos complejos, por supuesto cuando trabajamos con jax-ws no nos percatamos de esto ya que el framework esconde este proceso de convertir los datos XML recibidos en objetos Java y los objetos Java enviados con el cliente del servicio web convertidos a XML (Los servicios web envían XML para de esta manera ser interoperables e independientes de plataformas y lenguajes), siendo transparente para el programador, de esta manera el programador se enfoca en desarrollar la lógica de la aplicación (sea la creación del servicio web o la aplicación que hace uso del cliente del servicio).
Además de esta funcionalidad JAXB también nos ofrece otras herramientas como xjc que nos permite crear clases Java a partir de un XML schema (XSD) y schemagen que lleva a cabo la función inversa, es decir, crear un XML schema (XSD) a partir de una clase Java.