2011-09-24 20 views
20

Necesito implementar la serialización JSON para algunos objetos, y he encontrado un problema cuando se trata de integración con colecciones genéricas.Java JSON serialization: mejor práctica

Todas las clases serializables implementar esta interfaz (JSONObject proviene de this biblioteca):

interface JSONSerializable{ 
    public JSONObject dump() throws JSONException //serializes object 
    public void load(JSONObject obj) throws JSONException //deserializes object 
} 
Código

para mi colección basada en java.util.List se ve más o menos así:

class AwesomeList<T extends JSONSerializable> implements JSONSerializable{ 
    private LinkedList<T> items = new LinkedList<T>(); 
    ... 
    ... 

    public JSONObject dump() throws JSONException { 
     JSONObject result = new JSONObject(); 
     JSONArray a = new JSONArray(); 
     for(T i : items){ 
      a.put(i.dump()); 
     } 
     result.put("items", a); 
     return result; 
    } 

    public void load(JSONObject obj) throws JSONException{ 
     //here is my problem 
    } 
} 

Mi problema es: cuando cargo AwesomeList desde JSONObject, necesito crear sus elementos pero es imposible ya que java me prohíbe escribir

T newItem = new T(); 
newItem.load(obj); 

¿Cómo debo modificar mi enfoque para esta tarea?

+0

Para ser honesto, no veo cómo esto funciona incluso con conocidos tipos. ¿Está almacenando los nombres de clase en el paquete de datos JSON? – Perception

+0

No, cada objeto sabe cómo cargarse desde JSONObject (de hecho, es solo una matriz asociativa). Actualicé la publicación para mostrar lo que quiero hacer. – KCH

Respuesta

30

¿Está vinculado a esta biblioteca? Google Gson es muy popular. Yo mismo no lo he usado con Generics, pero su página principal dice que Gson considera que el soporte para Generics es muy importante.

+2

gson puede manejar genéricos muy bien. – kingori

+3

la última vez que verifiqué gson no maneja referencias circulares ... aunque una actualización podría haber solucionado eso ... me parece que el [enlace] http://jackson.codehaus.org/ es el mejor. Verifique esta pregunta mía sobre cómo hacer la conversión de json con generic en gson [link] http://stackoverflow.com/questions/5528385/json-conversion-using-gson –

+0

El uso de GSON es muy, muy, muy simple. – schmijos

0

Bueno, al escribirlo en un archivo, usted sabe qué clase T es, por lo que puede almacenarlo en dump. Luego, cuando lo vuelva a leer, puede llamarlo dinámicamente utilizando la reflexión.

public JSONObject dump() throws JSONException { 
    JSONObject result = new JSONObject(); 
    JSONArray a = new JSONArray(); 
    for(T i : items){ 
     a.put(i.dump()); 
     // inside this i.dump(), store "class-name" 
    } 
    result.put("items", a); 
    return result; 
} 

public void load(JSONObject obj) throws JSONException { 
    JSONArray arrayItems = obj.getJSONArray("items"); 
    for (int i = 0; i < arrayItems.length(); i++) { 
     JSONObject item = arrayItems.getJSONObject(i); 
     String className = item.getString("class-name"); 
     try { 
      Class<?> clazzy = Class.forName(className); 
      T newItem = (T) clazzy.newInstance(); 
      newItem.load(obj); 
      items.add(newItem); 
     } catch (InstantiationException e) { 
      // whatever 
     } catch (IllegalAccessException e) { 
      // whatever 
     } catch (ClassNotFoundException e) { 
      // whatever 
     } 
    } 
4

Como han insinuado otros, debería considerar la posibilidad de descargar la biblioteca de org.json. Es bastante obsoleto en estos días, y tratar de solucionar sus problemas es una pérdida de tiempo.

Pero a una pregunta específica; tipo de variable T simplemente no tiene ninguna información para ayudarlo, ya que es poco más que información en tiempo de compilación. En su lugar, debe pasar la clase real (como argumento 'Class cls'), y luego puede crear una instancia con 'cls.newInstance()'.

0

¿Has probado tu json-io (https://github.com/jdereg/json-io)?

Esta biblioteca le permite serializar/deserializar cualquier gráfico de objetos Java, incluidos gráficos de objetos con ciclos en ellos (por ejemplo, A-> B, B-> A). No requiere que sus clases implementen ninguna interfaz en particular ni hereden de ninguna clase Java en particular.

Además de serialización de Java para JSON (y JSON para Java), que se puede utilizar para dar formato (impresión bonita) JSON:

String niceFormattedJson = JsonWriter.formatJson(jsonString)