2013-05-16 16 views
12

Ho un problema con l'analisi di una risposta JSON usando Gson.Deserializzatore JSON personalizzato usando Gson

JSON stringa:

response: [ 
    2, { 
    owner_id: 23972237, 
    album_id: 25487692, 
    title: 'album not new' 
    }, { 
    owner_id: 23972237, 
    album_id: 25486631, 
    title: 'фыв' 
    } 
] 

ho queste 2 classi:

public class VkAudioAlbumsResponse { 
    public ArrayList<VkAudioAlbum> response; 
    public VkError error; 
} 

public class VkAudioAlbum { 
    public int owner_id; 
    public int album_id; 
    public String title; 
} 

Ma ho un'eccezione quando analizzare questo utilizza GSON. So che questo è dovuto al fatto che l'array first array non è un oggetto, ma un intero.

Quindi la domanda è, posso risolverlo in qualche modo?

risposta

30

Devi scrivere un custom deserializer. Mi piacerebbe fare qualcosa di simile:

In primo luogo è necessario includere una nuova classe, oltre il 2 avete già:

public class Response { 
    public VkAudioAlbumsResponse response; 
} 

E poi avete bisogno di un deserializzatore personalizzato, qualcosa di simile a questo:

private class VkAudioAlbumsResponseDeserializer 
    implements JsonDeserializer<VkAudioAlbumsResponse> { 

    @Override 
    public VkAudioAlbumsResponse deserialize(JsonElement json, Type type, 
     JsonDeserializationContext context) throws JsonParseException { 

    JsonArray jArray = (JsonArray) json; 

    int firstInteger = jArray.get(0); //ignore the 1st int 

    VkAudioAlbumsResponse vkAudioAlbumsResponse = new VkAudioAlbumsResponse(); 

    for (int i=1; i<jArray.size(); i++) { 
     JsonObject jObject = (JsonObject) jArray.get(i); 
     //assuming you have the suitable constructor... 
     VkAudioAlbum album = new VkAudioAlbum(jObject.get("owner_id").getAsInt(), 
              jObject.get("album_id").getAsInt(), 
              jObject.get("title").getAsString()); 
     vkAudioAlbumsResponse.getResponse().add(album); 
    } 

    return vkAudioAlbumsResponse; 
    } 
} 

Poi si deve deserializzare vostro JSON come:

GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.registerTypeAdapter(VkAudioAlbumsResponse.class, new VkAudioAlbumsResponseDeserializer()); 
Gson gson = gsonBuilder.create(); 
Response response = gson.fromJson(jsonString, Response.class); 

Con questa appr oach, quando Gson prova a deserializzare il JSON nella classe Response, trova che c'è un attributo response in quella classe che corrisponde al nome nella risposta JSON, quindi continua l'analisi.

Quindi questo attributo è di tipo VkAudioAlbumsResponse, quindi utilizza il deserializzatore personalizzato che è stato creato per analizzarlo, che elabora la parte rimanente della risposta JSON e restituisce un oggetto di VkAudioAlbumsResponse.

Nota: Il codice nel deserializzatore è abbastanza semplice, quindi credo che non avrete alcun problema a capirlo ... Per ulteriori informazioni visita Gson API Javadoc

+0

Grande risposta, anche se io preferisco creare un metodo privato invece di creare una nuova classe;) –

+1

@MattiaRuggiero Preferisco di gran lunga una classe separata con quella specifica responsabilità: avere un sacco di classi piccole è sempre una buona idea, a patto che le organizziate chiaramente ... – MikO

Problemi correlati