【问题标题】:How parse json array with multiple objects by gson?如何通过gson解析具有多个对象的json数组?
【发布时间】:2015-09-08 07:25:33
【问题描述】:

如何使用 gson 解析 json?我有一个包含多种对象类型的 json 数组,我不知道我需要创建什么样的对象来保存这个结构。我无法更改 json 数据格式(我不控制服务器)。 我可以使用gson或其他库解析这个json数组吗,我该怎么做?

这是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"
    }
  }
]

【问题讨论】:

  • 嗨!您阅读并尝试过我的答案了吗?

标签: java android json gson


【解决方案1】:

这个 json 结构本质上对 gson 不友好。即你不能在java中干净地建模,因为“object”键是指动态类型。你可以用这个结构做的最好的事情就是这样建模:

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

}

然后在类型和对象字段上做一些尴尬的开关:

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;

    }
}

最终最好的解决方案是将 json 结构更改为与 java 更兼容的结构。

例如:

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

【讨论】:

    【解决方案2】:

    这对于原始海报来说可能有点晚了,但希望它可以帮助其他人。

    我在Android 中使用Gson。 我看到每个人都使用自定义类和长期解决方案。 我的是基本的。

    我有一个包含许多不同对象类型的 ArrayList(我的数据库的模型)- Profile 就是其中之一。我使用mContactList.get(i) 得到该项目,它返回:

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

    现在我创建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)); 
    

    现在无需创建自定义类 - 只需使用以下代码将其作为 JsonObject 传递:

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

    现在,您可以像这样调用对象:

    JsonObject profile = obj.getAsJsonObject("profile");
    

    【讨论】:

    • 如何获取profile的name属性? @Haring10
    【解决方案3】:

    您可以非常轻松地在模型类中设置方法。只需创建一个 StringRequest。下面是一个sn-p:

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

    我使用this 从你的 json 生成你的模型类。您的模型类将如下所示:

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

    【讨论】:

    • 但是对象有四种类型,如何处理
    • 您可以更改模型类并将对象定义为“对象”类的列表。 i,e 您将创建另一个类对象并分别定义其 getter 和 setter。但是是的,我认为作为数组的对象值应该与作为对象的对象值具有不同的名称
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 2016-01-21
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多