2013-02-25 15 views
7

Ich versuche, ein JSON-Objekt deserialisieren (mit Gson), die wie folgt aussieht:Deserialisieren ein JSON-Objekt mit mehreren darin enthaltenen Elementen

 "attachments": { 
      "40": { 
       "ID": 40, 
       "URL": "http:\/\/drewmore4.files.wordpress.com\/2013\/02\/wreckit.jpg", 
       "guid": "http:\/\/drewmore4.files.wordpress.com\/2013\/02\/wreckit.jpg", 
       "mime_type": "image\/jpeg", 
       "width": 287, 
       "height": 400 
      }, 
      "3": { 
       "ID": 3, 
       "URL": "http:\/\/drewmore4.files.wordpress.com\/2013\/02\/frankenweenie2bposter.jpg", 
       "guid": "http:\/\/drewmore4.files.wordpress.com\/2013\/02\/frankenweenie2bposter.jpg", 
       "mime_type": "image\/jpeg", 
       "width": 273, 
       "height": 400 
      } 
    }, 

Wie kann ich damit umgehen? Ich weiß nicht einmal, wie ich das nennen soll - Es gibt mehrere "Elemente", die hier dargestellt sind, aber es ist kein Array. Wenn ich versuche, es als ein Array zu deserialisieren, stürzt das Programm bei einer Ausnahme "Expected Begin_Array but found Begin_Object" ab. Wenn ich versuche, es als ein Strong-Objekt zu deserialisieren (siehe Klasse unten), wird das Programm ausgeführt, aber alle Felder geben null zurück. Hier

ist die Klasse, ich habe versucht, es zu zur Karte:

class Attachment { 
int ID; 
String URL; 
} 

die volle JSON-Datei here:

EDIT zu sehen ist: behobenes.

@ Wahrnehmung Lösung im Grunde funktioniert. Es wurde durch die Tatsache kompliziert, dass dieses "Element" (möchte immer noch wissen, was dieses json-Element mit mehreren Einträgen/Nicht-Arrays ist) in ein größeres json-Objekt eingebettet ist, das ein Array enthält. Auch dieses JSON ist nicht mein Design - es kommt von der Wordpress REST API und (wie @Perception angedeutet), ich denke, das Problem, das ich hatte, zeigt einen Designfehler darin - nämlich, dass das Attachments-Element ein Array sein sollte , anstatt ein einzelnes Objekt. Dennoch

Dennoch, wenn jemand jemals das Ergebnis einer Abfrage für alle Beiträge auf einer bestimmten Website mit dieser API deserialisiert muss und weitere Bedürfnisse Zugang zu den Anlagen auf jedem Pfosten, hier ist, wie Sie es tun:

private class getAll extends AsyncTask <Void, Void, JSONObject> { 
    private static final String url = "https://public-api.wordpress.com/rest/v1/sites/drewmore4.wordpress.com/posts/"; 
    @Override 
    protected JSONObject doInBackground(Void... params) { 

     HttpClient httpclient = new DefaultHttpClient(); 
     HttpGet httpget = new HttpGet(url); 
     httpget.addHeader("accept", "application/json"); 
     JSONObject returned = new JSONObject(); 
     HttpResponse response; 

     try { 
      response = httpclient.execute(httpget); 
      HttpEntity entity = response.getEntity(); 

      if (entity != null) { 
       InputStream instream = entity.getContent(); 
       String result= convertStreamToString(instream); 

       returned =new JSONObject(result);     
       instream.close(); 
      } 
     } 
     catch (ClientProtocolException | IOException | JSONException e) { e.printStackTrace();} 

     return returned; 
    } 

     @Override 
    protected void onPostExecute (JSONObject returned){ 
     Gson gson = new Gson(); 

//posts is the element within the JSONObject that is an array of post objects 
     try { 
     JSONArray posts = returned.getJSONArray("posts"); 

     for (int curr = 0; curr < posts.length(); curr++){ 
      String s = posts.get(curr).toString(); 

      Article a = gson.fromJson(s, Article.class); 

      JSONObject attachments = new JSONObject(s).getJSONObject("attachments"); 
      final Iterator<String> keys = attachments.keys(); 
       while(keys.hasNext()) { 
        final String key = keys.next(); 
        a.attached.add(gson.fromJson(attachments.getJSONObject(key).toString(), Attachment.class)); 
       } 
       stories.add(a); 
     } 

      } catch (JSONException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

Antwort

7

Dies ist ein Beispiel von Daten, die wahrscheinlich sollte hat als Array serialisiert, aber war es nicht. Eine Lösung zum Parsen ist die direkte Verwendung eines JSONObject.

String json = ...; 
final Gson gson = new Gson(); 

final List<Attachment> attachements = new ArrayList<Attachment>(64); 
final JSONObject jsonObj = new JSONObject(json).getJSONObject("attachments"); 
final Iterator<String> keys = jsonObj.keys(); 
while(keys.hasNext()) { 
    final String key = keys.next(); 
    attachements.add(gson.fromJson(jsonObj.getJSONObject(key).toString(), Attachment.class); 
} 

// Do something with attachements 

Die Daten können auch als Karte angezeigt werden, von IDs auf Anlagen. Und es kann als solche deserialisiert werden:

final String jsonObj = new JSONObject(json).getJSONObject("attachments"); 
final Gson gson = new Gson(); 
final Map<String, Attachment> data = gson.fromJson(jsonObj.toString(), 
     new TypeToken<Map<String, Attachment>>() { 
     }.getType()); 
final List<Attachment> attachments = new ArrayList<Attachment>(data.values()); 

Dies ist actuall

+0

Ich denke, es gibt ein Missverständnis hier, entweder von mir oder von Ihnen. Was hier dargestellt wird, sind keine Artikel, sondern Komponenten von Artikeln (nämlich Anhänge), die ich in Felder der Artikelinstanzen zu deserialisieren versuche, mit denen du mir zuvor geholfen hast. – drewmoore

+0

@ drewmore4 - in der Tat. Sieh dir meinen Schnitt an (nichts Wesentliches, ersetze grundsätzlich "Artikel" durch "Anhang"). – Perception

+0

Das ist, was ich dachte :) Ich versuche, was Sie vorgeschlagen, aber erhalten eine Fehlermeldung - Kann nur über ein Array oder eine Instanz von java.lang.Iterable - auf der for-Schleife. – drewmoore

2

Zuerst erstellen JSONArray von diesem JSONObject., dann

for(int i = 0; i < contacts.length(); i++){ 
      JSONObject c = contacts.getJSONObject(i); 

diese Schleife Durch die Verwendung der String-Werte erhalten und in einer Karte setzen oder ein Objekt, dass u wollen und fügen sie es zu einem Arraylist

HashMap<String, String> map = new HashMap<String, String>(); 

      // adding each child node to HashMap key => value 
      map.put(TAG_ID, id); 

Und

contactList.add(map); 

dann können Sie die Werte verwenden.

0

Wie kann ich damit umgehen? Ich weiß nicht einmal, wie ich das nennen soll - Es gibt mehrere "Elemente", die hier dargestellt sind, aber es ist kein Array.

Es sieht so aus, als ob die Sammlung in der JSON eine natürliche Passform für eine java.util.map ist. Also würde ich wahrscheinlich die JSON "Anhänge" in eine Map<String, Atachment> deserialisieren. Die Map ist dann einfach zu iterieren oder die Sammlung von Attachment-Werten in einen anderen Sammlertyp umzuwandeln, z. B. oder Attachment[].

Hinweis: The Gson User Guide enthält ein Beispiel für die Deserialisierung in eine generische Sammlung.

Verwandte Themen