2014-07-25 20 views
5

Ich benutze Gson, um Antworten von einem Server auf Android zu analysieren. Jede Antwort hat einige nutzlose (für mich) Daten, die meine Gson-Modelle verkomplizieren. Hier ist die allgemeine Hierarchie der json zurückgegeben:Mit Gson elegant verschachtelte JSON-Objekte behandeln?

response: { 
    date: 1406253006807, 
    otherUselessData1: "This is some useless data", 
    otherUselessData2: "This is some useless data", 

    usefulJsonObject: { <---- This is really the object that I care about 
    } 

} 

Alles über oder auf dem gleichen Niveau wie usefulJsonObject konnte ich wirklich verzichten. Die nutzlosen Daten werden für jede Anforderung zurückgegeben, und die tatsächliche Antwort ist darunter als usefulJsonObject eingebettet. Das wäre kein großes Problem, aber es ist wirklich meine gson Modellobjekte überladen.

Zum Beispiel: Sagen wir, ich habe 3 Anfragen, die ich machen kann: A, B, und C. Für jede Antwort muss ich mindestens 3 benutzerdefinierte Klassen erstellen.

public class ResponseA { 

    @SerializedName("response") ResponseObjectA responseObject; 

    public static class ResponseObjectA { 
    @SerializedName("usefulJsonObject") UsefulObjectA usefulObject; 
    } 

    public static class UsefulObjectA { 
    } 

} 

Ich habe ein paar Lösungen ausprobiert, aber ich habe nichts elegant gefunden, die nicht einen zusätzlichen Schritt zu meinem Prozess hinzufügen würden. Ich verwende Retrofit, um meine HTTP-Anfragen zu machen, und es ist wirklich nett, dass es mir das vollständig geparste Gson-Objekt zurückgibt. Ich habe über andere Lösungen nachgedacht wie das nützliche Objekt einfach ein JsonElement zu sein und dann einen zweiten gson Call zu machen, nachdem der erste zurückkommt. Wiederum nicht ideal.

Ich wollte nur wissen, ob ich etwas verpasst habe. Sicher bin ich nicht der Einzige, dem so etwas begegnet ist, und deshalb dachte ich, ich würde fragen, wie andere mit so etwas umgehen würden.

+0

Willst du sagen, dass 'nützlichJsonObject' dynamisch ist? Ihr Wert könnte alles sein, aber Sie brauchen es? –

+0

@StiriosDelimanolis Nein, es hat immer den gleichen Schlüssel. In diesem Beispiel würde es also immer "usableJsonObject" heißen. – spierce7

+0

Was ist mit dem Wert dieses Schlüssel-Wert-Paares? –

Antwort

0

Ich fand nie eine elegante Art und Weise mit nur Gson beschäftigen. Ich habe mehrere Möglichkeiten mit Generics ausprobiert, die alle nicht funktionierten oder etwas zu wünschen übrig ließen.

Da ich Retrofit verwende, entschied ich mich, den GsonConverter zu überschreiben und nur die unnötigen Informationen aus meinen Anfragen herauszufiltern. Es ist nicht so flexibel, da ich nicht die gleiche Retrofit-Netzwerkschnittstelle für Anrufe zu anderen Servern verwenden kann, aber ich mache das nicht wirklich, und es hat auch den Nachteil, dass es zwei Runden json-Parsing-Aufrufe gibt (meh). Sie könnten das wahrscheinlich effizienter machen, aber das funktioniert jetzt für mich.

public class CustomGsonConverter extends GsonConverter { 

    private Gson mGson; 

    public CustomGsonConverter(Gson gson) { 
    super(gson); 
    this.mGson = gson; 
    } 

    public CustomGsonConverter(Gson gson, String encoding) { 
    super(gson, encoding); 
    this.mGson = gson; 
    } 

    @Override public Object fromBody(TypedInput body, Type type) throws ConversionException { 
    try { 
     CustomResponse customResponse = mGson.fromJson(new InputStreamReader(body.in()), CustomResponse.class); 
     return mGson.fromJson(customResponse.responseObject.data, type); 
    } catch (IOException e) { 
     throw new ConversionException(e); 
    } 
    } 

    public static class CustomResponse { 

    @SerializedName("rsp") ResponseObject responseObject; 

    public static class ResponseObject { 

// @SerializedName("date") long date; 

     @SerializedName("data") JsonElement data; 

    } 

    } 

} 

Vielleicht gibt es einen besseren Weg, den ich gerade nicht realisiere.

0

Es ist die Initialisierung Instance Wert, nicht NULL Wert. Überprüfen Sie mein Beispiel.

Address.java

public class Address { 
    public Address(){ 
    } 
} 

Person.java

public class Person { 
    private String name; 
    private String nrc; 
    private Address address; 

    public Person(String name, String nrc, Address address) { 
     this.name = name; 
     this.nrc = nrc; 
     this.address = address; 
    } 
} 

Die folgende Json Zeichenkette wird equalvent zu

Person person = new Person("Zaw Than Oo", "11111", null); 

{ 
    "name": "Zaw Than Oo", 
    "nrc": "11111" 
} 

Die folgende Json Zeichenkette wird equalvent zu

0.123.
Person person = new Person("Zaw Than Oo", "11111", new Address()); 

{ 
    "name": "Zaw Than Oo", 
    "nrc": "11111", 
    "address": {} <-- here use less object for you. 
} 

Auch wenn Sie nicht neue Instance erstellen Sie, andere lib/api (Sie verwendet) sein kann, dass die Instanz von Reflection erstellen.

Kurz auf den Punkt

{ 
    ... 
    "xxx": {} --> new instance without data/value 
    ... 
} 
{ 
    ... 
       --> null value 
    ... 
} 
+0

Also ich denke du hast meine Frage falsch verstanden. Ich kann nicht kontrollieren, was der Server mir zurücksendet. Ich habe mehrere Anfragen, und alle Antworten enthalten diese nutzlosen Informationen und zwingen mich, nutzlose Klassen zu erstellen, um jede dieser nutzlosen Informationen für jede Anfrage darzustellen, weil die nutzlose Information die nützliche Information in eine Hierarchie zwingt. Alles, was mir wichtig ist, ist der Zugriff auf die Informationen bei Antwort> nützlichJsonObject, aber um dies zu tun, muss ich 3 separate Klassen für jede Antwort erstellen, die ich möglicherweise bekommen könnte. Ich suche nach einem Workaround. – spierce7

+0

Alles, was ich versuche, ist, es so zu machen, dass ich nicht 3 Klassen für jede Antwort machen muss, damit ich die nützlichen Informationen bekomme, die ich möchte. – spierce7

Verwandte Themen