2013-05-16 26 views
12

Ich habe ein Problem mit der Analyse einer JSON-Antwort mit Gson.Benutzerdefinierte JSON Deserializer mit Gson

JSON-String:

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

Ich habe diese zwei Klassen:

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

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

Aber ich habe eine Ausnahme, wenn dies mit Gson analysieren. Ich weiß, das ist, weil Antwort-Array erstes Element kein Objekt, sondern Ganzzahl ist.

Die Frage ist also, kann ich es irgendwie lösen?

Antwort

30

Sie müssen eine custom deserializer schreiben. Ich würde so etwas tun:

Zuerst Sie eine neue Klasse umfassen müssen, weiter als die 2 haben Sie bereits:

public class Response { 
    public VkAudioAlbumsResponse response; 
} 

Und dann müssen Sie eine benutzerdefinierte Deserializer, etwas Ähnliches wie folgt aus:

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

Dann haben Sie Ihre JSON wie deserialisieren:

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

Mit dieser ca. Wenn Gson versucht, den JSON in die Klasse Response zu deserialisieren, stellt es fest, dass in dieser Klasse ein Attribut response vorhanden ist, das mit dem Namen in der JSON-Antwort übereinstimmt. Daher wird die Analyse fortgesetzt.

Dann stellt es fest, dass dieses Attribut vom Typ VkAudioAlbumsResponse ist, so dass es den benutzerdefinierten Deserializer verwendet, den Sie erstellt haben, um den verbleibenden Teil der JSON-Antwort zu verarbeiten und ein Objekt VkAudioAlbumsResponse zurückgibt.

Hinweis: Der Code in den Deserializer ist sehr einfach, so dass ich glaube, dass Sie kein Problem, es zu verstehen ... Für weitere Informationen siehe Gson API Javadoc

+0

Große Antwort haben würden, auch wenn ich es vorziehen, eine zu schaffen private Methode anstatt eine neue Klasse zu erstellen;) –

+1

@MattiaRuggiero Ich bevorzuge eine separate Klasse mit dieser spezifischen Verantwortung - viele kleine Klassen zu haben ist immer gut imo, solange man sie klar organisiert ... – MikO

Verwandte Themen