Serializando objetos con XStream

Publicado el Monday 5 de March de 2007. | 8 comentarios
Categoría: Programación y diseño | Tags:

A veces puede ser necesario hacer que un simple bean u objeto sea persistente. Es decir, escribir a disco todos los atributos de un objeto dado para volver a leerlo en otro momento y recuperarlo. El sistema clásico para hacer esto es utilizando la interfaz java.io.Serializable y utilizando un ObjectOutputStream para guardarlo y un ObjectInputStream para recuperarlo.

public class MiObjeto implements java.io.Serializable {
	String nombre = "Mola";
	Collection datos = new ArrayList();
}

Creamos un par de métodos estáticos en una clase externa:

public class IOTools {
	public static void serialize(Object o, OutputStream os)
			throws IOException {
	    ObjectOutputStream oos = null;
	    try {
	        oos = new ObjectOutputStream(os);
	        oos.writeObject(o);
	    } finally {
	        if (oos != null) oos.close();
	    }
	}

	public static Object deserialize(InputStream os)
			throws IOException, ClassNotFoundException {
	    ObjectInputStream oos = null;
	    try {
	        oos = new ObjectInputStream(os);
	        Object o = oos.readObject();
	        return o;
	    } finally {
	        if (oos != null) oos.close();
	    }
	}
}

Y ahora podemos guardar y recuperar nuestros objetos de una manera muy simple:

	// Grabar
	MiObjeto o = new MiObjeto();
	IOTools.serialize(o, new FileOutputStream("objeto.dat");

	// Recuperar
	MiObjeto o = (MiObjeto)IOTools.deserialize(new FileInputStream("objeto.dat");

Sin embargo, este sistema tiene algunas complicaciones que para mi gusto, lo hacen muy poco interesante:

  1. El objeto serializado se guarda en un formato binario, por lo que es ilegible y no se puede editar externamente.
  2. Si se cambia el código de la clase serializada y se recompila la misma, es posible que no se pueda recuperar lo grabado.

¿Y cuál es la solución para todo esto? XStream. Tras mucho (bueno, no tanto) buscar, he dado con la solución definitiva:

  • Persistencia basada en XML, o sea texto plano: legible y editable.
  • No hace falta modificar tus objetos a serializar (ni siquiera tienen que implementar java.io.Serializable)
  • No requiere mapeos (como otros motores de persitencia basado en XML, como Castor)
  • Si recompilas tu objeto a escribir, o incluso si modificas sus atributos, el Xml grabado seguirá siendo válido (aunque puedes perder información si cambias el nombre de un atributo, siempre puedes editar el Xml!)
  • Controla referencias circulares. Es decir, es posible serializar un objeto con un atributo que es una referencia a si mismo.
  • Es fácil, sencillo, extensible, configurable, muy rápido y MOLA

¿Y como se usa? Pues así:

    XStream x = new XStream();

    // Grabar
    MiObjeto o = new MiObjeto();
    x.toXML(o, new FileOutputStream("objeto.xml"));

    // Recuperar
    MiObjeto o = (MiObjeto) x.fromXML(new FileInputStream("objeto.xml"));

Más sencillo, imposible. Además, podemos crear nuestras propias implementaciones de los conversores de objeto/xml y xml/objeto para ciertas clases, podemos persistir colecciones de objetos en el que se escribe un Xml en disco por cada objeto, podemos hacer alias de clases y cambiar etiquetas enteras por atributos para mejorar la legibilidad.
En resumidas cuentas, una herramienta muy recomendable.
Más información en: http://xstream.codehaus.org

Popularity: 1% [?]

8 Responses to “Serializando objetos con XStream”

  1. Carles Mateu says:

    Una pregunta, en la línea:

    x.toXML(gs, new FileOutputStream(“objeto.xml”));

    gs que variable es? donde referencias al objeto o?

    No seria algo como (no me he mirado el API de XStream :-) ):

    x.toXML(o, new FileOutputStream(“objeto.xml”));

  2. admin says:

    Efectivamente, donde pone gs es o. Maldito copypaste, ahora lo corrijo. Gracias!

  3. [...] Via Yo Programador descubro la existencia de XStream, una librería interesante para convertir nuestros objetos java en ficheros XML y poder luego recuperarlos. [...]

  4. Blaxter says:

    Suena interesante, porque desde luego nunca me ha gustado la forma de persistencia natural de java. Habrá que probarlo :)

  5. Manuel says:

    Muy buena…

    Esta me la apunto para usarla.

  6. Enrique says:

    Perdonad, una pregunta, estoy intentando serializar un objeto pero me gustaría en cada etiqueta (tag) poder introducirle atributos, es decir, algo así como:

    , (atributos fecha y motivo)

    Con Xstream sólo consigo por ahora que me transforme las propiedades de mis objetos a etiquetas con el valor que yo le haya introducido, es decir, consigo:

    Manuel
    Díaz Vázquez

    Me podeis echar una manita, me hace mucha falta la verdad. Os lo agradezco.

    Un saludo, Enrique.

  7. admin says:

    Para que los valores te los guarde como atributos, tienes que hacer lo siguiente:


    XStream xstream = new XStream();
    // Con esto haces que se use un atributo xml para todos los int
    xstream.useAttributeFor(int.class);
    // Y con esto solo para un nombre. Debes especificar el nombre del atributo y su clase
    xstream.useAttributeFor("nombre", String.class);

    Espero que te sirva

Leave a Reply