How to parse json array with multiple gson objects?

How can I parse json using gson? I have a json array with several types of objects and I don’t know which object I need to create to save this structure. I cannot change the json data format (I do not control the server). Can I use gson or another library to parse this json array, how can I do this?

This is the json code code:

[ { "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" } } ] 
+7
source share
4 answers

This json structure is inherently gson-unfriendly. ie you cannot correctly model this in java, because the "object" key is of a dynamic type. The best you can do with this structure is this:

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

Then make some inconvenient inclusion type and object field:

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

Ultimately, the best solution is to convert the json structure to something more compatible with java.

eg:

 [ { "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" } } ] 
+7
source

It may be a little late for the original poster, but hopefully it helps someone else.

I am using Gson on Android . I saw how everyone uses custom classes and long-path solutions. My main.

I have an ArrayList from many different types of objects (Models for my database). Profile is one of them. I get the element using mContactList.get(i) , which returns:

 {"profile": {"name":"Josh", "position":"Programmer", "profile_id":1, "profile_image_id":10, "user_id":1472934469 }, "user": {"email":" example@you.co.za ", "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 } } 

Now I create a Gson object:

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

Now instead of creating a custom class, just pass it as a JsonObject using the following code:

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

And now you can call the object as follows:

 JsonObject profile = obj.getAsJsonObject("profile"); 
+2
source

You can easily set methods in the model class. Just create a StringRequest. Below is a snippet:

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

I used this to generate your json model class. The model class will look something like this:

  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
source

To solve the problem, I propose the following solution:

Since your internal object can be a json object or a json array, so I will use the generic JsonElement gson (you can find more information about this class by pressing Ctrl-B on it in your project or referring here )

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

Then in Activity , using Gson for parsing:

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

Since com.google.gson.JsonElement can be JsonObject (not JsonObject ) or JsonArray (not JsonArray ), if you want to convert to JsonObject and JsonArray , use the following code:

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

Here are the logcat results in my project that I tested:

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

Hope this helps!

0
source

All Articles