2013-03-20 10 views
7

sto cercando di implementare un GSON personalizzato serializzatore/deserialiser per un certo elenco di oggetti BasicNameValuePair.serializzatore personalizzato - deserializzatore utilizzando GSON per un elenco di BasicNameValuePairs

ho visto il codice di soluzione parziale (per la serializzazione) qui: How do I get Gson to serialize a list of basic name value pairs?

Tuttavia ho voluto implementare anche deserializzazione e ho provato le mie possibilità e il codice è qui:

package dto; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

import org.apache.http.message.BasicNameValuePair; 


import com.google.gson.TypeAdapter; 
import com.google.gson.stream.JsonReader; 
import com.google.gson.stream.JsonWriter; 


    public class KeyValuePairSerializer extends TypeAdapter<List<BasicNameValuePair>> { 
     @Override 
     public void write(JsonWriter out, List<BasicNameValuePair> data) throws IOException { 
      out.beginObject(); 
      for(int i=0; i<data.size();i++){ 
       out.name(data.get(i).getName()); 
       out.value(data.get(i).getValue()); 
      } 
      out.endObject(); 
     } 

     @Override 
     public List<BasicNameValuePair> read(JsonReader in) throws IOException { 
      ArrayList<BasicNameValuePair> list=new ArrayList<BasicNameValuePair>(); 
      in.beginObject(); 
      while (in.hasNext()) { 
       String key = in.nextName(); 
       String value = in.nextString(); 
       list.add(new BasicNameValuePair(key,value)); 
      } 
      in.endObject(); 
      return list; 
     } 

} 

Codice per inizializzare e riempire la lista

ArrayList<BasicNameValuePair> postParameters=new ArrayList<BasicNameValuePair>(); 
postParameters.add(new BasicNameValuePair("some_key","some_value")); 

ed ecco il codice per utilizzare la nuova classe KeyValuePairSerializer:

 GsonBuilder gsonBuilder= new GsonBuilder(); 
     gsonBuilder.registerTypeAdapter(KeyValuePairSerializer.class, new KeyValuePairSerializer()); 
     Gson gson1=gsonBuilder.create(); 

     //serialization works just fine in the next line 
     String jsonUpdate=gson1.toJson(postParameters, KeyValuePairSerializer.class); 


     ArrayList<BasicNameValuePair> postParameters2 = new ArrayList<BasicNameValuePair>(); 
     //postParameters2 = gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class); //? how to cast properly 
     //deserialization throws an error, it can't cast from ArrayList<BasicNameValuePair> to KeyValuePairSerializer 
     gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class); 

Il problema è che viene generata un'eccezione alla fine e non so dove si trova esattamente il problema e ancora non sicuro di come scrivere l'ultima riga per ottenere il risultato torna nella nuova ArrayList postParameters2.

risposta

8

tratto dal GSON Collections Examples:

GsonBuilder gsonBuilder= new GsonBuilder(); 
gsonBuilder.registerTypeAdapter(KeyValuePairSerializer.class, new KeyValuePairSerializer()); 
Gson gson1=gsonBuilder.create(); 

Type collectionType = new TypeToken<ArrayList<BasicNameValuePair>>(){}.getType(); 
ArrayList<BasicNameValuePair> postParameters2 = gson1.fromJson(jsonUpdate, collectionType); 
+0

Fare una cosa del genere ignorerà la mia nuova classe definita KeyValuePairSerializer e non chiamerà il metodo sovrascritto: leggi. – Arise

+0

In realtà, non lo ignorerà se chiami "registerTypeAdapter()" come hai fatto nella domanda. – Nachi

+0

Non sembra essere il caso. registerTypeAdapter sembra funzionare solo per il serializzatore e non per il deserializzatore. – Arise

1

registerTypeAdapter sembra funzionare solo per il serializzatore non per deserializzatore.

L'unico modo per chiamare l'override leggere funzione del KeyValuePairSerializer è chiamare il: gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class); senza salvare il valore del risultato in una variabile. Mentre elaborerà la funzione in modo corretto, genererà un errore nella classe gson perché non sarà in grado di eseguire il cast da ArrayList a KeyValuePairSerializer. E capisco perché (suppongo la cancellazione), solo che non so come farlo correttamente.

In ogni caso ho trovato una soluzione alternativa per risolvere questo problema. Sembra che invece di registrare l'oggetto GSON e chiamando registerTypeAdapter e quindi utilizzando gson1.toJson(Object src, Type typeOfSrc) e gson1.fromJson(String json,Class <T> classOfT) posso scappare per deserializzazione con qualcosa di più semplice come:

KeyValuePairSerializer k= new KeyValuePairSerializer(); 
parametersList = (ArrayList<BasicNameValuePair>)k.fromJson(jsonUpdate); 
-1

Ho seguito questo blog per GSON Collection Examples. Il collegamento è semplice da capire e implementare.

public class TimeSerializer implements JsonSerializer<time> { 

    /** 
    * Implementing the interface JsonSerializer. 
    * Notice that the the interface has a generic 
    * type associated with it. 
    * Because of this we do not have ugly casts in our code. 
    * {@inheritDoc} 
    */ 
    public JsonElement serialize(
        final Time time, 
        final Type type, 
        final JsonSerializationContext jsonSerializationContext) { 

     /** 
     * Returning the reference of JsonPremitive 
     * which is nothing but a JSONString. 
     * with value in the format "HH:MM" 
     */ 
     return new JsonPrimitive(String.format("%1$02d:%2$02d", 
           time.getHour(), time.getMinute())); 
    } 
0

Entrambi si comportano di NameValuePair in modo simile ai dizionari di JsonObject e, non credo è necessario convertire l'uno nell'altro, se il caso d'uso è simile. Inoltre, JsonObject ti consente di trattare i tuoi valori ancora più facilmente (invece di scorrere l'array di coppie di valori per trovare la chiave di cui hai bisogno per ottenere il suo valore, JsonObject si comporta in modo simile a una mappa in modo che tu possa chiamare direttamente il nome della chiave e tornerà la proprietà desiderata):

jsonObject.get("your key").getAsString(); (getAsBoolean(), getAsInt(), etc). 

Per il vostro caso mi piacerebbe creare un JsonObject dalla stringa, risposta o flusso e quindi accedere come una mappa (come indicato sopra):

JsonParser parser = new JsonParser(); 
JsonObject o = (JsonObject)parser.parse("your json string"); 
Problemi correlati