2015-09-08 10 views
6

Jak mogę analizować json za pomocą gson? Mam tablicę json z wieloma typami obiektów i nie wiem, jakiego rodzaju obiekt muszę utworzyć, aby zapisać tę strukturę. Nie mogę zmienić formatu danych json (nie kontroluję serwera). Czy mogę użyć biblioteki gson lub innej do analizy tej tablicy json, jak mam to zrobić?W jaki sposób analizować tablicę json z wieloma obiektami za pomocą gson?

Jest to blok kodu json:

[ 
    { 
    "type": 1, 
    "object": { 
     "title1": "title1", 
     "title2": "title2" 
    } 
    }, 
    { 
    "type": 2, 
    "object": [ 
     "string", 
     "string", 
     "string" 
    ] 
    }, 
    { 
    "type": 3, 
    "object": [ 
     { 
     "url": "url", 
     "text": "text", 
     "width": 600, 
     "height": 600 
     }, 
     { 
     "url": "url", 
     "text": "text", 
     "width": 600, 
     "height": 600 
     } 
    ] 
    }, 
    { 
    "type": 4, 
    "object": { 
     "id": 337203, 
     "type": 1, 
     "city": "1" 
    } 
    } 
] 
+0

Witam! Czy znasz i wypróbowałeś moją odpowiedź? – BNK

Odpowiedz

5

Ta struktura json jest z natury niepoprawna dla gsonów. Nie można tego modelować czysto w java, ponieważ klucz "object" odnosi się do typu dynamicznego. Najlepiej można zrobić z tej struktury jest modelem to tak:

public class Models extends ArrayList<Models.Container> { 

    public class Container { 
     public int type; 
     public Object object; 
    } 

    public class Type1Object { 
     public String title1; 
     public String title2; 
    } 

    public class Type3Object { 
     public String url; 
     public String text; 
     public int width; 
     public int height; 
    } 

    public class Type4Object { 
     public int id; 
     public int type; 
     public int city; 
    } 

} 

Następnie zrobić jakąś niezręczną przełącznik rodzaju i pole obiektu:

String json = "{ ... json string ... }"; 
Gson gson = new Gson(); 
Models model = gson.fromJson(json, Models.class); 


for (Models.Container container : model) { 

    String innerJson = gson.toJson(container.object); 

    switch(container.type){ 
     case 1: 
      Models.Type1Object type1Object = gson.fromJson(innerJson, Models.Type1Object.class); 
      // do something with type 1 object...         
      break; 
     case 2: 
      String[] type2Object = gson.fromJson(innerJson, String[].class); 
      // do something with type 2 object... 
      break; 
     case 3: 
      Models.Type3Object[] type3Object = gson.fromJson(innerJson, Models.Type3Object[].class); 
      // do something with type 3 object... 
      break; 
     case 4: 
      Models.Type4Object type4Object = gson.fromJson(innerJson, Models.Type4Object.class); 
      // do something with type 4 object... 
      break; 

    } 
} 

Ostatecznie najlepszym rozwiązaniem jest, aby uzyskać strukturę json zmieniono na coś bardziej kompatybilnego z Javą.

Np:

[ 
    { 
    "type": 1, 
    "type1Object": { 
     "title1": "title1", 
     "title2": "title2" 
    } 
    }, 
    { 
    "type": 2, 
    "type2Object": [ 
     "string", 
     "string", 
     "string" 
    ] 
    }, 
    { 
    "type": 3, 
    "type3Object": [ 
     { 
     "url": "url", 
     "text": "text", 
     "width": 600, 
     "height": 600 
     }, 
     { 
     "url": "url", 
     "text": "text", 
     "width": 600, 
     "height": 600 
     } 
    ] 
    }, 
    { 
    "type": 4, 
    "type4Object": { 
     "id": 337203, 
     "type": 1, 
     "city": "1" 
    } 
    } 
] 
+0

dzięki, to działa dla mnie. – xiangmao

1

można ustawić metody w swojej klasie modelu bardzo łatwo. Po prostu wykonaj StringRequest. Poniżej znajduje się fragment:

List<YourModelClass> inpList; 
StringRequest greq = new StringRequest(Request.Method.POST, yourURL, new Response.Listener<String>() { 
      @Override 
      public void onResponse(String response) { 
       try { 
         Log.d("response array===> ", response.toString()); 

         Type type = new TypeToken<List<YourModelClass>>(){}.getType(); 
         inpList = new Gson().fromJson(response, type); 

       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       error.printStackTrace(); 

      } 
     }){ 
      @Override 
      protected Map<String, String> getParams() throws AuthFailureError { 
       Map<String, String> params = new HashMap<String, String>(); 
       //return params back to server, if any 
      } 
     }; 

     yourVolley.getRequestQueue().add(greq); 

Użyłem this wygenerować klasę modelu od ciebie json. Klasa model będzie wyglądać następująco:

package com.example; 

import javax.annotation.Generated; 
import com.google.gson.annotations.Expose; 

@Generated("org.jsonschema2pojo") 
public class YourModelClass { 

@Expose 
private Integer type; 
@Expose 
private Object object; 

/** 
* 
* @return 
* The type 
*/ 
public Integer getType() { 
return type; 
} 

/** 
* 
* @param type 
* The type 
*/ 
public void setType(Integer type) { 
this.type = type; 
} 

/** 
* 
* @return 
* The object 
*/ 
public Object getObject() { 
return object; 
} 

/** 
* 
* @param object 
* The object 
*/ 
public void setObject(Object object) { 
this.object = object; 
} 

} 
-----------------------------------com.example.Object.java----------------------------------- 

package com.example; 

import javax.annotation.Generated; 
import com.google.gson.annotations.Expose; 

@Generated("org.jsonschema2pojo") 
public class Object { 

@Expose 
private Integer id; 
@Expose 
private Integer type; 
@Expose 
private String city; 

/** 
* 
* @return 
* The id 
*/ 
public Integer getId() { 
return id; 
} 

/** 
* 
* @param id 
* The id 
*/ 
public void setId(Integer id) { 
this.id = id; 
} 

/** 
* 
* @return 
* The type 
*/ 
public Integer getType() { 
return type; 
} 

/** 
* 
* @param type 
* The type 
*/ 
public void setType(Integer type) { 
this.type = type; 
} 

/** 
* 
* @return 
* The city 
*/ 
public String getCity() { 
return city; 
} 

/** 
* 
* @param city 
* The city 
*/ 
public void setCity(String city) { 
this.city = city; 
} 

} 
+0

ale obiekt ma cztery typy, jak sobie z nim radzić – rainash

+0

Możesz zmienić klasę modelu i zdefiniować obiekt jako listę klasy "obiekt". i, e utworzysz inny obiekt klasy i osobno zdefiniujesz jego moduły pobierające i ustawiające. Ale tak myślę, że wartość obiektu jako tablica powinna mieć inną nazwę niż wartość obiektu jako obiekt –

0

Dla wydać, proponuję następujące rozwiązanie:

Ponieważ wewnętrzny obiekt może być obiekt JSON lub tablicą JSON, więc użyję ogólna JsonElement z gson (można znaleźć więcej informacji na temat tej klasie naciskając Ctrl-B na to w swoim projekcie lub refering here)

public class CustomJson { 
    private int type; 
    private JsonElement object; 
} 

Następnie w Aktywny, z wykorzystaniem Gson do analizowania:

Gson gson = new Gson(); 
CustomJson[] customJson = gson.fromJson(jsonString, CustomJson[].class); 

Ponieważ com.google.gson.JsonElement może być JsonObject (nie JSONObject) lub JsonArray (nie JSONArray), jeśli chcesz przekonwertować do JSONObject i JSONArray , należy użyć następującego kodu:

 if (customJson!= null && customJson.length > 0) { 
      for (CustomJson aCustomJson : customJson) { 
       JsonElement jsonElement = aCustomJson.object; 
       if (jsonElement instanceof JsonObject) { 
        try { 
         JSONObject jsonObject = new JSONObject(jsonElement.toString()); 
         Log.i(LOG_TAG, jsonObject.toString()); 
        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
       } else if (jsonElement instanceof JsonArray) { 
        try { 
         JSONArray jsonArray = new JSONArray(jsonElement.toString()); 
         Log.i(LOG_TAG, jsonArray.toString()); 
        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 

Oto wyniki logcat w moim projekcie mam przetestowane:

09-08 15:41:48.024 6202-6202/com.example.jsonparse I/JSONParse﹕ {"title1":"title1","title2":"title2"} 
09-08 15:41:51.458 6202-6202/com.example.jsonparse I/JSONParse﹕ ["string","string","string"] 
09-08 15:41:51.458 6202-6202/com.example.jsonparse I/JSONParse﹕ [{"text":"text","url":"url","height":600,"width":600},{"text":"text","url":"url","height":600,"width":600}] 
09-08 15:41:51.458 6202-6202/com.example.jsonparse I/JSONParse﹕ {"type":1,"id":337203,"city":"1"} 

Mam nadzieję, że to pomoże!

1

To może być trochę za późno oryginalnego plakatu, ale mam nadzieję, że to pomoże kogoś innego.

Używam Gson w Android. Widziałem, jak wszyscy używali niestandardowych klas i rozwiązań długich. Moja jest podstawowa.

Mam ArrayList wielu różnych typów obiektów (modele dla mojej bazy danych) - profil jest jednym z nich. Pojawia się element za pomocą mContactList.get(i) która zwraca:

{"profile": 
    {"name":"Josh", 
    "position":"Programmer", 
    "profile_id":1, 
    "profile_image_id":10, 
    "user_id":1472934469 
    }, 
"user": 
    {"email":"[email protected]", 
    "phone_numbers":[], 
    "user_id":1, 
    "user_type_id":1 
    }, 
"follower": 
    {"follower_id":3, 
    "following_date":1.4729345E9, 
    "referred_by_id":2, 
    "user_from_id":1, 
    "user_to_id":2 
    }, 
"media": 
    {"link":"uploads/profiles/profile-photos/originals/1-G9FSkRCzikP4QFY.png", 
    "media_description":"", 
    "media_id":10, 
    "media_name":"", 
    "media_slug":"", 
    "medium_link":"uploads/profiles/profile-photos/thumbs-medium/1-G9FSkRCzikP4QFY.png", 
    "thumbnail_link":"uploads/profiles/profile-photos/thumbs-small/1-G9FSkRCzikP4QFY.png", 
    "uploader_id":1 
    } 
} 

Teraz tworzę obiekt Gson:

Gson gson = new Gson(); 
// this creates the JSON string you see above with all of the objects 
String str_obj = new Gson().toJson(mContactList.get(i)); 

Teraz zamiast tworzenia niestandardowej klasy - po prostu przekazać go przez jako JsonObject stosując następujący kod:

JsonObject obj = gson.fromJson(str_obj, JsonObject.class); 

A teraz, można wywołać obiekt tak:

JsonObject profile = obj.getAsJsonObject("profile"); 
Powiązane problemy