2013-02-25 11 views
7

Próbuję deserializowania (używając gson) obiekt JSON, który wygląda tak:deserializacji obiekt JSON z wielu elementów wewnątrz niego

 "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 
      } 
    }, 

Jak mam sobie z tym poradzić? Nie wiem nawet, jak to nazwać - jest tu wiele "przedmiotów", ale to nie jest tablica. Kiedy próbuję deserializować go jako tablicę, program zawiesza się na wyjątku "Oczekiwany Begin_Array, ale znalazł Begin_Object". Kiedy próbuję deserializować go jako silnego obiektu (patrz klasa poniżej), program działa, ale wszystkie pola zwracają wartość null.

Oto klasa Próbowałem mapować go:

class Attachment { 
int ID; 
String URL; 
} 

pełny plik JSON widać here:

EDIT: rozwiązany.

@ Rozwiązanie Percepcja zasadniczo działało. Było to skomplikowane przez fakt, że ten "element" (nadal chciałby wiedzieć, co ten element json wielokrotnego wejścia/nie-tablicy) jest osadzony w większym obiekcie json, który zawiera tablicę. Ponownie, ten JSON nie jest moim projektem - pochodzi z REST API Wordpress i (jak wspomniałem @Perception), myślę, że problem, który miałem, ilustruje wadę projektu - mianowicie element attachments powinien być tablicą , a nie pojedynczy obiekt. Niemniej

Niemniej jednak, jeśli ktoś kiedykolwiek potrzebuje deserializowania wynik kwerendy dla wszystkich stanowisk w danym miejscu za pomocą tego interfejsu API, a ponadto musi mieć dostęp do załączników na każdego posta, oto jak to zrobić:

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

Odpowiedz

7

Jest to przykład dane, które prawdopodobnie powinny były szeregowane w tablicy, ale nie. Jednym z rozwiązań do analizowania jest bezpośrednie użycie 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 

Dane może być również postrzegana jako mapę, z identyfikatora do załączników. I to może być rozszeregować jako takie:

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()); 

To actuall

+0

Myślę, że tutaj jest nieporozumienie, albo z mojej strony, albo z ciebie. To, co jest tutaj reprezentowane, to nie artykuły, ale elementy artykułów (a mianowicie załączniki), które próbuję deserializować w pola przykładów artykułów, z którymi mi pomogłeś. – drewmoore

+0

@ drewmore4 - rzeczywiście. Sprawdź moją edycję (nic istotnego, w zasadzie zastąp "Artykuł" za pomocą "Załącznika"). – Perception

+0

To właśnie wymyśliłem :) Próbuję to, co zasugerowałeś, ale otrzymuję ostrzeżenie o błędzie - Mogę tylko powtarzać przez tablicę lub instancję java.lang.Iterable - w pętli for. – drewmoore

2

Najpierw utwórz JSONArray z tego JSONObject., następnie

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

korzystając z tej pętli uzyskać wartości ciąg i umieścić na mapie lub obiekt, który u chcą i dodać je do ArrayList

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

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

I

contactList.add(map); 

następnie można użyć jej wartości.

0

Jak mam sobie z tym poradzić? Nie wiem nawet, jak to nazwać - jest tu wiele "przedmiotów", ale to nie jest tablica.

Wygląda na to, że kolekcja w JSON to naturalne dopasowanie do java.util.map. Tak, prawdopodobnie prawdopodobnie deserializować "załączniki" JSON do Map<String, Atachment>. Mapę można następnie łatwo przekształcić lub przekształcić zbiór wartości załącznika w inny typ kolekcji, np. List<Attachment> lub .

Uwaga: The Gson User Guide zawiera przykład deserializacji do ogólnej kolekcji.

Powiązane problemy