Gson Parse Json mit Array mit verschiedenen Objekttypen

Wie kann ich diesen JSON mit Gson analysieren? Ich habe ein Array mit mehreren Objekttypen und ich weiß nicht, welche Art von Objekt ich erstellen muss, um diese Struktur zu speichern. Ich kann die Json-Nachricht nicht ändern (ich kontrolliere den Server nicht).

Die einzige Klasse, die Funktion (Art von) war das

  • Kommunikation zwischen einem Fragment und einer Aktivität - Best Practices
  • Dividing zwei Integers in Java gibt mir 0 oder 100?
  • Crosswalk Cordova - js alert zeigt Blockzeichen auf der chinesischen Schnittstelle android
  • Werden Sie Anfänger empfehlen, Android Studio zu benutzen?
  • Ändern Sie die Farbe des Cursors eines EditText in Android über alle sdk
  • Sende benutzerdefiniertes Objekt mit Android native Binder
  • public class Response { private List<Object> tr; private int results; (...) } 

    JSON-Meldung (Beachten Sie das Array mit mehreren Objekttypen.)

     { "tr": [ { "a": { "userId": "112" } }, { "b": { "userId": "123", "address":"street dummy" } }, { "a": { "userId": "154" } } ], "results":3 } 

  • Android webview loadurl ("file: ///android_asset/index.html#home") ist fehlgeschlagen
  • Ändern der Position von Android Action Bar
  • Service nach Kraftanschlag starten
  • Wie fange ich eine Softtastatur auf?
  • Bild von URL über Twitter App teilen - Android
  • Gradle 2.3.0-alpha1 funktioniert keine Datenbindung
  • 5 Solutions collect form web for “Gson Parse Json mit Array mit verschiedenen Objekttypen”

    Das Gson User's Guide deckt dies ausdrücklich ab:

    https://sites.google.com/site/gson/gson-user-guide#TOC-Serialisierung-und-Deserialisierung-Collection-with-Objects-of-Arbitrary-Types

    Sie haben ein Objekt mit einem Feld tr , das ein Array mit beliebigen Typen ist.

    Der Benutzerführer erklärt, dass man eine solche Struktur nicht direkt deserialisieren kann und empfiehlt:

    Verwenden Sie Gson's Parser API (Low-Level-Streaming-Parser oder DOM-Parser JsonParser), um die Array-Elemente zu analysieren und dann Gson.fromJson () auf jedem der Array-Elemente zu verwenden. Dies ist der bevorzugte Ansatz.

    In deinem Fall … würde es wirklich davon abhängen, welche Objekte in diesem Array möglich waren. Wenn sie alle das gleiche innere Objekt haben wollen, möchtest du so etwas machen …

     List<MyUserPojo> list = new ArrayList<MyUserPojo>(); JsonArray array = parser.parse(json).getAsJsonObject().getAsJsonArray("tr"); for (JsonElement je : array) { Set<Map.Entry<String,JsonElement>> set = je.getAsObject().entrySet(); JsonElement je2 = set.iterator().next().getValue(); MyUserPojo mup = new Gson().fromJson(je2, MyUserPojo.class); list.add(mup); } 

    Und natürlich müsste das in einem benutzerdefinierten Deserializer für dein aktuelles Objekt sein, das die tr und results haben würde.

     class MyPojo { List<MyUserPojo> userList; int results; } class MyUserPojo { String userId; String address; } class MyDeserializer implements JsonDeserializer<MyPojo> { @Override public MyPojo deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException { List<MyUserPojo> list = new ArrayList<MyUserPojo>(); JsonArray array = je.getAsJsonObject().getAsJsonArray("tr"); for (JsonElement je2 : array) { Set<Map.Entry<String,JsonElement>> set = je2.getAsObject().entrySet(); JsonElement je3 = set.iterator().next().getValue(); MyUserPojo mup = new Gson().fromJson(je3, MyUserPojo.class); list.add(mup); } MyPojo mp = new MyPojo(); mp.tr = list; mp.results = je.getAsObject().getAsJsonPrimitive("results").getAsInt(); return mp; } } 

    Jetzt sind Sie alle eingestellt – Sie können diesen Deserializer verwenden und Ihr Objekt erstellen:

     Gson gson = new GsonBuilder() .registerTypeAdapter(MyPojo.class, new MyDeserializer()) .build(); MyPojo mp = gson.fromJson(json, MyPojo.class); 

    Wenn die a , b etc sind wichtig … gut, müssen Sie das herausfinden. Aber die oben genannten sollten Sie gut auf Ihrem Weg zu verstehen, was wird erforderlich sein, um mit Ihrem JSON-Struktur umzugehen.

    Für die Vollständigkeit halber ist der einzige "hackige" Weg um diese, wenn es eine ziemlich begrenzte Anzahl dieser Typen gibt und das innere Objekt ist auch ziemlich begrenzt in seinen Feldern. Du könntest einen POJO erstellen, der alle Möglichkeiten umfasst:

     class MyPojo { MySecondPojo a; MySecondPojo b; ... MySecondPojo f; } class MySecondPojo { String userId; String address; ... String someOtherField; } 

    Wenn Gson JSON deserialisiert, wird es irgendwelche fehlenden Felder in deinem POJO (s) setzen, um zu null . Du könntest jetzt eine List oder ein Array von diesen in deinem POJO haben. Wieder und zu betonen, das ist wirklich ganz hacky und der falsche Weg, es zu tun , aber ich dachte, ich würde erklären, was erforderlich wäre, um direkt zu analysieren, dass Array.

    Ich wähle etwas von jeder Antwort und habe es so gemacht:

    ResponseObject

     public class Response { private List<Users> tr; private int results; (...) } 

    GenericUser

     public class User { public static final int TYPE_USER_A =0; public static final int TYPE_USER_B =1; private String userId; private int type; (...) } 

    EIN

     public class a extends User { private Strngt location; (...) } 

    B

     public class b extends User { private String adress; (...) } 

    Parsing-Methode

     private Response buildResponseObject(String response) { Response tls = new Response(); List<Users> users = new ArrayList<users>(); User u; try { JSONObject object = new JSONObject(response); tls.setResults(object.getInt("results")); JSONArray array = object.getJSONArray("tr"); for (int i = 0; i < array.length(); i++) { JSONObject trs = array.getJSONObject(i); if (trs.has("a")) { String json = trns.getString("a"); A a = new Gson().fromJson(json,A.class); a.setType(User.TYPE_USER_A); users.add(a); } else if (trs.has("b")) { String json = trs.getString("b"); B b= new Gson().fromJson(json,B.class); B.setType(User.TYPE_USER_B); users.add(b); } } tls.setUsers(users); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return tls; } 

    Dies ist nicht so elegant wie ich wollte und mischen native JsonObjects mit Gson Methoden aber funktioniert für mich.

    Versuchen Sie diesen Code hier:

     public class Address { public String userId; public String address; // ... } public class Response { private HashMap<String, Address> tr; private int results; // ... } 

    Verwendung:

     String json = "{\n \"tr\":\n {\n \"a\": {\n \"userId\": \"112\"\n },\n \"b\": {\n \"userId\": \"123\",\n \"address\":\"street dummy\"\n },\n \"c\": {\n \"userId\": \"154\"\n }\n },\n \"results\":3\n}"; Response users = new Gson().fromJson(json, Response.class); 

    Wie Sie vielleicht sehen, musste ich die Struktur ändern:

     { "tr": { "a": { "userId": "112" }, "b": { "userId": "123", "address":"street dummy" }, "c": { "userId": "154" } }, "results":3 } 

    Aber leider habe ich es nicht geschafft, mehrere Schlüssel zuzulassen. Im Moment habe ich keine Ahnung, wie ich das beheben kann.

    Ich denke, dieser Link könnte Ihnen helfen: https://sites.google.com/site/gson/gson-user-guide#TOC-Collections-Examples

    Grundsätzlich erstellen Sie eine Klasse für Ihr "Objekt" (Art von Benutzer, den ich vermute), und verwenden Sie dann den Deserialisierungscode von Gson, wie folgt:

     Type collectionType = new TypeToken<Collection<User>>(){}.getType(); Collection<User> users= gson.fromJson(json, collectionType); 

    Sie können entsprechende Java-Klassen für die json-Objekte erstellen. Die Integer-, String-Werte können wie abgebildet abgebildet werden. Json kann so geparkt werden –

     Gson gson = new GsonBuilder().create(); Response r = gson.fromJson(jsonString, Response.class); 

    Hier ist ein Beispiel – http://rowsandcolumns.blogspot.com/2013/02/url-encode-http-get-solr-request-and.html

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.