2013-05-16 15 views
12

Mam problem z analizowaniem odpowiedzi JSON przy użyciu Gson.Niestandardowy deserializator JSON przy użyciu Gson

JSON ciąg:

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

mam te 2 klasy:

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

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

Ale mam wyjątek podczas analizowania tego używając Gson. Wiem, że to dlatego, że pierwszy element tablicy odpowiedzi nie jest obiektem, ale liczbą całkowitą.

Pytanie brzmi, czy mogę to jakoś rozwiązać?

Odpowiedz

30

Musisz napisać custom deserializer. Zrobiłbym tak:

Najpierw musisz włączyć nową klasę, dalej niż 2 masz już:

public class Response { 
    public VkAudioAlbumsResponse response; 
} 

A potem trzeba niestandardowego Deserializator, coś podobnego do tego:

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

Następnie trzeba deserializowania swoją JSON jak:

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

Z tego ok o, gdy Gson próbuje deserializować JSON w klasę Response, stwierdza, że ​​istnieje atrybut response w tej klasie, który pasuje do nazwy w odpowiedzi JSON, więc kontynuuje przetwarzanie.

Następnie zdaje sobie sprawę, że ten atrybut jest typu VkAudioAlbumsResponse, więc używa niestandardowego deserializera, który utworzyłeś, aby go przetworzyć, przetwarzając pozostałą część odpowiedzi JSON i zwracając obiekt o wartości VkAudioAlbumsResponse.

Uwaga: kod do Deserializatora jest dość proste, więc myślę, że nie będziesz mieć problemu, żeby go zrozumieć ... W celu uzyskania dalszych informacji patrz Gson API Javadoc

+0

Wielką odpowiedź, nawet jeśli Wolę stworzyć metoda prywatna zamiast tworzenia nowej klasy;) –

+1

@MattiaRuggiero Wolę osobną klasę z tą szczególną odpowiedzialnością - posiadanie wielu małych klas jest zawsze dobre, o ile tylko je uporządkujesz ... – MikO

Powiązane problemy