jump to navigation

Serializame… marzo 7, 2007

Posted by superpiwi in Java, Javascript.
trackback

He escrito una clase para serializar objetos java a un string XML y a cadenas JSON. (Para quien no lo sepa: ¿Que que es JSON?).
JSON (javascript object notation) es una forma de representar un objeto mediante una cadena de caracteres. Se suele emplear en JavaScript, aunque puedes usarlo donde mejor te venga. Yo lo suelo emplear con AJAX lo cuál me viene muy bien en muchas ocasiones en la que no quiero crear y parsear un XML (esto suele ser mas lento y tambien implica mas procesamiento).

Puedes encontrar informacion de JSON en http://www.json.org/

Bueno,… ¿Y para que nos puede servir convertir un objeto a una cadena de caracteres o a un XML String. Pues se me ocurren 2 buenas razones:

1) Para guardar el estado de un objeto . Es una manera de persistencia. Por ejemplo en una aplicacion de envio de paquetes, para la parte del seguimiento de un pedido, el pedido va pasando por diferentes estados, podriamos guardar el objeto en la base de datos, para posteriormente cuando cambie su estado, recuperarlo, actualizarlo y volver a guardarlo.

2) Para serializar un objeto, enviarlo por un socket a otra máquina y en el destino deserializarlo para poder acceder a sus métodos y propiedades o invocarlo remotamente.

No se, existen muchas mas utilidades. Seguro que se te ocurre alguna.

La clase se llama ObjectSerializer y es muy sencilla de utilizar. (La escribi hace tiempo, seguro que esto ha evolucionado, pero te puede ser util). Requiere de la siguiente libreria:

http://json-lib.sourceforge.net/

Aqui el código:


/**
* ObjectSerializer.java
*
* Clase de utilidad para codificar y decodificar un objeto a String empleando XML o una cadena JSON.
* Util por ejemplo para enviar el objeto a otra maquina e invocar sus metodos desde alli o para
* guardar su estado en la base de datos.
*
* @author jdelgado
* @version 0.0.1
* @since JDK 1.5
* @ide Eclipse 3.2 Callisto
* @revision 13 Julio 2006
*
* @note Para serializar/deserializar a JSON emplea la libreria json-lib.jar.
* @note Para serializar/deserializar a XML emplea las clases de Sun XMLEncoder y XMLDecoder.
*
* TODO: soporte para otros metodos (XStream, Castor, XMLBeans, etc...)
*/
package comun.util;
import java.beans.XMLEncoder;
import java.beans.XMLDecoder;
import java.io.*;
import net.sf.json.JSONObject;
import net.sf.json.JSONArray;
import java.util.Vector;
public class ObjectSerializer
{
public static int XML_METHOD=0;
public static int JSON_METHOD=1;
/**
* Codifica un objeto a un String.
* @param o objeto para codificar.
* @param method metodo de la codificacion: XML_METHOD o JSON_METHOD.
* @return un string con el objeto codificado.
* @throws Exception Excepcion levantada en caso de error.
*/
public static String encode(Object o,int method) throws Exception
{
ByteArrayOutputStream bout = null;
if (method==ObjectSerializer.XML_METHOD)
{
// serializar a xml
bout = new ByteArrayOutputStream();
XMLEncoder e = new XMLEncoder(bout);
e.writeObject(o);
e.close();
String s = bout.toString();
return s;
}
else if(method==ObjectSerializer.JSON_METHOD)
{
// serializar a cadena json (javascript object notation)
JSONObject jsonObject = JSONObject.fromObject( o );
return jsonObject.toString();
}
else
{
throw new Exception("unknown method");
}
//return null;
}
//------------------------------
/**
* Codifica un objeto a un String.
* @param o objeto para codificar.
* @param method metodo de la codificacion: XML_METHOD o JSON_METHOD.
* @return un string con el objeto codificado.
* @throws Exception Excepcion levantada en caso de error.
*/
public static Object decode(String s,int method) throws Exception
{
ByteArrayInputStream bin = null;
if (method==ObjectSerializer.XML_METHOD)
{
// deserializar a xml
bin = new ByteArrayInputStream(s.getBytes());
XMLDecoder d = new XMLDecoder(bin);
Object result = d.readObject();
d.close();
return result;
}
else if(method==ObjectSerializer.JSON_METHOD)
{
// serializar a cadena json (javascript object notation)
JSONObject jsonObject = JSONObject.fromString(s);
return jsonObject;
}
else
{
throw new Exception("method unknown");
}
//return null;
}
//------------------------------
public static void main(String[] args) {
try
{
com.sqlmap.User usuario = new com.sqlmap.User();
usuario.setLogin("superpiwi");
usuario.setPassword("superpiwi");
usuario.setProfile("Usuario");
usuario.setSid("00001");
com.sqlmap.User usuario1 = new com.sqlmap.User();
usuario1.setLogin("jose");
usuario1.setPassword("jose");
usuario1.setProfile("Usuario Jose");
usuario1.setSid("00001-01");
com.sqlmap.User usuario2 = new com.sqlmap.User();
usuario2.setLogin("soledad");
usuario2.setPassword("soledad");
usuario2.setProfile("Usuario Soledad");
usuario2.setSid("00001-02");
usuario.addUser(usuario1);
usuario.addUser(usuario2);
// Codificarlos
String XML_STRING = ObjectSerializer.encode(usuario, ObjectSerializer.XML_METHOD);
System.out.println("Codificado como XML:\r\n\r\n"+XML_STRING);
String JSON_STRING = ObjectSerializer.encode(usuario, ObjectSerializer.JSON_METHOD);
System.out.println("Codificado como JSON:\r\n\r\n:"+JSON_STRING);
// Decodificarlos
com.sqlmap.User MiUsuario = null;
JSONObject json = (JSONObject) ObjectSerializer.decode(JSON_STRING, ObjectSerializer.JSON_METHOD);
JSONArray array = json.getJSONArray("usuarios");
int numero = array.length();
for (int i=0;i<numero;i++)
{
JSONObject usuario_interno = array.getJSONObject(i);
String id=usuario_interno.getString("login");
System.out.println("usuario interno: "+id);
}
String login = (String) json.get("login");
System.out.println("usuario principal:"+login);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
//end of class ObjectSerializer.java

En el ejemplo instancio una clase User, y relleno algunos de sus atributos (no te proporciono el codigo de esta clase, pero puedes usar cualquiera de las tuyas).

Al convertirlo a XML obtenemos algo como lo siguiente:


<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_08" class="java.beans.XMLDecoder">
<object class="com.sqlmap.User">
<void property="login">
<string>superpiwi</string>
</void>
<void property="password">
<string>superpiwi</string>
</void>
<void property="profile">
<string>Usuario</string>
</void>
<void property="sid">
<string>00001</string>
</void>
<void property="usuarios">
<object class="java.util.Vector">
<void method="add">
<object class="com.sqlmap.User">
<void property="login">
<string>jose</string>
</void>
<void property="password">
<string>jose</string>
</void>
<void property="profile">
<string>Usuario Jose</string>
</void>
<void property="sid">
<string>00001-01</string>
</void>
</object>
</void>
<void method="add">
<object class="com.sqlmap.User">
<void property="login">
<string>soledad</string>
</void>
<void property="password">
<string>soledad</string>
</void>
<void property="profile">
<string>Usuario Soledad</string>
</void>
<void property="sid">
<string>00001-02</string>
</void>
</object>
</void>
</object>
</void>
</object>
</java>

Si lo codificamos como un String JSON obtenemos lo siguiente:


{"phone":"","password":"superpiwi","sid":"00001","login":"superpiwi","description":"","project":"","usuarios":[{"phone":"","password":"jose","sid":"00001-01","login":"jose","description":"","project":"","usuarios":null,"email":"","profile":"Usuario Jose"},{"phone":"","password":"soledad","sid":"00001-02","login":"soledad","description":"","project":"","usuarios":null,"email":"","profile":"Usuario Soledad"}],"email":"","profile":"Usuario"}

En el resto del ejemplo recuperamos los valores de los atributos a partir de la cadena JSON. Si quisieramos mapearlos de nuevo a un objeto tendriamos que implementar un metodo que fuera leyendo los atributos a partir de la cadena y asignandoselos a la clase.
Solo un comentario, para indicar el uso del elemento JSONArray, lo que he hecho en la clase User es tener un vector de usuarios, que voy rellenando con el metodo add, es decir, tengo un usuario principal y un atributo “usuarios” que realmente es un vector de mas usuarios.

Para acceder a un elemento simple empleariamos el JSONObject, pero para acceder a esta lista de elementos (que a su vez son JSONObject) empleariamos el JSONArray.

Comentarios»

1. …Y tambien encriptame « Java.Lang.NullPointer - marzo 7, 2007

[…] tambien encriptame marzo 7, 2007 Posted by superpiwi in Java. trackback En el post anterior comentaba como convertir a una cadena de texto nuestros objetos. ¿Porque no encriptarlos […]

2. Andres Almiray - marzo 30, 2007

Superpiwi, me parece interesante el uso the Json-lib en tu ejemplo, pero noto que la representacion en XML es distinta a la de JSON, en terminos de que JSON solo tiene los datos, y la de XML contiene la información de métodos de Java.

La ultima version (en cvs) de Json-lib (1.1-SNAPSHOT) contiene muchas mejoras en JSONSerializer y XMLSerializer, de tal suerte que podrás convertir de JSON a XML sin perder datos y con cambios minimos de estructura segun sea el caso.

Suerte!

3. superpiwi - marzo 30, 2007

Muchas gracias por la informacion, algo habia visto. De hecho meti en mi TODO particular estudiar el nuevo API, pero ya sabes, este mundillo es tan enorme que siempre tienes algun frente abierto. Muchas cosas para aprender y poco tiempo.


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: