2015-06-03 1 views
7

Ich versuche, eine Liste von Objekten aus einer JSON-Antwort zu deserialisieren. Das JSON-Array verfügt über einen Schlüssel, der Probleme bei der Verwendung von GSON zur Deserialisierung verursacht.GSON-Deserialisierung einer umschlossenen Liste von Objekten

Ich habe etwa 20 ähnliche Objekte.

public class Device extends Entity { 
    String device_id; 
    String device_type; 
    String device_push_id; 
} 

Für die meisten gibt es eine API-Methode, die eine Liste von Objekten zurückgibt. Das zurückgegebene JSON sieht so aus. Aufgrund anderer Clients ist das Ändern des JSON-Formats zu diesem Zeitpunkt keine sinnvolle Option.

{ 
    "devices":[ 
     { 
     "id":"Y3mK5Kvy", 
     "device_id":"did_e3be5", 
     "device_type":"ios" 
     }, 
     { 
     "id":"6ZvpDPvX", 
     "device_id":"did_84fdd", 
     "device_type":"android" 
     } 
    ] 
} 

Um diese Art von Antwort zu analysieren bin ich zur Zeit eine Mischung aus org.json Methoden und Gson verwenden.

Ich bin auf der Suche nach einer saubereren Methode der Deserialisierung, wie ich Retrofit verwenden möchte. Die Antwort in Get nested JSON object with GSON using retrofit ist nahe, was ich brauche, aber nicht List s. Ich habe die generische Version der Antwort hier kopiert:

public class RestDeserializer<T> implements JsonDeserializer<T> { 
    private Class<T> mClass; 
    private String mKey; 

    public RestDeserializer(Class<T> targetClass, String key) { 
    mClass = targetClass; 
    mKey = key; 
    } 

    @Override 
    public T deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) 
    throws JsonParseException { 

    JsonElement value = jsonElement.getAsJsonObject().get(mKey); 
    if (value != null) { 
     return new Gson().fromJson(value, mClass); 
    } else { 
     return new Gson().fromJson(jsonElement, mClass); 
    } 
    } 
} 

Mein Ziel ist es, diesen Aufruf "nur Arbeit" zu haben.

@GET("/api/v1/protected/devices") 
public void getDevices(Callback<List<Device>> callback); 
+0

Ist es nicht eine einfache 'Liste '? Verwenden Sie einfach die Annotation "@ SerializedName", wenn sich der Feldname vom Json-Namen unterscheidet. Retrofit führt das Parsing für Sie durch –

+0

Wie erstellen und registrieren Sie Ihren Deserializer? – Gomino

+0

Ich verwende derzeit den Deserializer nicht, weil das Problem dadurch nicht gelöst wird. – Derek

Antwort

1

Mit der unter Klasse

public class Devices { 

@Expose 
private List<Device> devices = new ArrayList<Device>(); 

/** 
* 
* @return 
* The devices 
*/ 
public List<Device> getDevices() { 
return devices; 
} 

/** 
* 
* @param devices 
* The devices 
*/ 
public void setDevices(List<Device> devices) { 
this.devices = devices; 
} 

} 

Geräteklasse

public class Device extends Entity { 
    @Expose 
    String id; 
    @Expose 
    String device_id; 
    @Expose 
    String device_type; 
} 

oder

public class Device extends Entity { 
    @Expose @SerializedName("id") 
    String deviceId; 
    @Expose @SerializedName("device_id") 
    String devicePushId; 
    @Expose @SerializedName("device_type") 
    String deviceType; 
} 

Aktualisierungs Retrofit Methode

@GET("/api/v1/protected/devices") 
public void getDevices(Callback<Devices> callback); 

devices.getDevices() //call inside callback method will give you the list 

Auch benötigen Sie nicht den benutzerdefinierten Deserializer

+0

Ich dachte darüber nach, und in der Tat werde ich tun, wenn keine generische Option auftaucht. Da ich jedoch über 20 solcher Objekte habe, hoffe ich, dass ich 20 zusätzliche Klassen vermeiden muss, nur um die Listen zu verpacken. – Derek

+0

versuchen Sie diese stattdessen @GET ("/ api/v1/protected/devices") öffentliche void getDevices (Rückruf Rückruf-Callback); Ich habe dies selbst nicht versucht, lassen Sie mich wissen, wenn das funktioniert .. Sie müssen das zusätzliche Objekt nicht erstellen, wenn dies funktioniert – 3xplore

+0

Das funktioniert nicht. Ein Problem ist, wie Gson wissen würde, dass das Json-Element, das "Geräte" genannt wird, das richtige ist, um es zu entpacken, um seine Liste oder Device [] zu finden. – Derek

Verwandte Themen