2011-09-24 15 views
20

Ho bisogno di implementare la serializzazione JSON per alcuni oggetti e ho riscontrato un problema quando si trattava di integrazione con raccolte generiche.Serializzazione Java JSON - best practice

Tutte le classi serializzabili implementare questa interfaccia (JSONObject viene da this libreria):

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

Codice per la mia collezione sulla base di java.util.List sembra più o meno così:

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 
    } 
} 

Il mio problema è: quando carico AwesomeList da JSONObject, devo creare i suoi elementi ma è impossibile dal momento che java mi impedisce di scrivere

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

Come dovrei modificare il mio approccio a questa attività?

+0

Per essere onesti non vedo come questo funziona con ancora nota tipi. Stai memorizzando i nomi delle classi nel pacchetto di dati JSON? – Perception

+0

No, ogni oggetto sa come caricarsi da JSONObject (in realtà è solo un array associativo). Ho aggiornato il post per mostrare cosa voglio fare. – KCH

risposta

30

Sei legato a questo libro? Google Gson è molto popolare. Non ho usato me stesso con Generics ma la loro prima pagina dice che Gson considera il supporto per Generics molto importante.

+2

gson può gestire i generici molto bene. – kingori

+3

l'ultima volta che ho controllato gson non gestisce i riferimenti circolari .. anche se un aggiornamento potrebbe averlo risolto .. trovo il [link] http://jackson.codehaus.org/ il migliore. Acquista questo mia domanda su come fare la conversione JSON con generico GSON [link] http://stackoverflow.com/questions/5528385/json-conversion-using-gson –

+0

L'utilizzo di GSON è molto, molto, molto semplice. – schmijos

0

Bene, quando si scrive su file, si conosce la classe T, quindi è possibile memorizzarla in dump. Quindi, rileggendolo, puoi chiamarlo dinamicamente usando la reflection.

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

Come altri hanno suggerito, è consigliabile prendere in considerazione la libreria di org.json. Oggigiorno è praticamente obsoleto e cercare di aggirare i suoi problemi è una perdita di tempo.

Ma a domanda specifica; digitare la variabile T non ha alcuna informazione per aiutarti, dato che è poco più di informazioni in fase di compilazione. Invece è necessario passare la classe effettiva (come argomento 'Class cls'), e quindi è possibile creare un'istanza con 'cls.newInstance()'.

0

Avete provato json-io (https://github.com/jdereg/json-io)?

Questa libreria permette di serializzare/deserializzare qualsiasi oggetto grafico Java, compresi oggetti grafici con cicli a loro (per esempio, A-> B, B-> A). Non richiede che le tue classi implementino una particolare interfaccia o ereditino da una particolare classe Java.

Oltre alla serializzazione di Java a JSON (e JSON a Java), è possibile utilizzarlo per formattare (abbastanza di stampa) JSON:

String niceFormattedJson = JsonWriter.formatJson(jsonString)