How can I parse json using gson? I have a json array with multiple object types, and I don't know, what kind of object I need to create to save this structure. I cannot change the json data format (I don't control the server). Can I use gson or other library parse this json array, how should I do?
如何使用gson解析json?我有一个带有多个对象类型的json数组,我不知道,我需要创建哪种对象来保存这个结构。我无法更改json数据格式(我不控制服务器)。我可以使用gson或其他库解析这个json数组,我该怎么办?
This is the json code block:
这是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"
}
}
]
4 个解决方案
#1
7
This json structure is inherently gson-unfriendly. i.e You cannot model this cleanly in java because the "object" key refers to a dynamic type. The best you can do with this structure is model it like so:
这种json结构固有地对gson不友好。即你不能在java中干净地建模,因为“对象”键指的是动态类型。你可以用这个结构做的最好的模型是这样的:
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 do some awkward switch on type and the 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 get the json structure changed to something more compatible with java.
最终,最好的解决方案是将json结构更改为与java更兼容的东西。
E.g:
例如:
[
{
"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
2
This may be a bit late for the original poster, but hopefully it will help someone else.
对于原始海报来说,这可能有点晚了,但希望它会帮助其他人。
I am using Gson
in Android
. I have seen everyone use custom classes and long way round solutions. Mine is basic.
我在Android中使用Gson。我看到每个人都使用自定义类和长途解决方案。我的基本。
I have an ArrayList of many different Object types (Models for my database) - Profile is one of them. I get the item using mContactList.get(i)
which returns:
我有一个包含许多不同对象类型的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
}
}
Now I create the Gson
object:
现在我创建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));
Now instead of creating a custom class - just pass it through as a JsonObject
using the following code:
现在不是创建自定义类 - 只需使用以下代码将其作为JsonObject传递:
JsonObject obj = gson.fromJson(str_obj, JsonObject.class);
And now, you can call the object like so:
现在,您可以像这样调用对象:
JsonObject profile = obj.getAsJsonObject("profile");
#3
0
You can set the methods in your model class very easily. Just make a StringRequest. Below is a snippet:
您可以非常轻松地在模型类中设置方法。只需创建一个StringRequest。以下是一个片段:
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 have used this to generate your model class from you json. Your model class will look something like 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;
}
}
#4
-1
For you issue, I suggest the following solution:
对于你的问题,我建议以下解决方案:
Because your inner object can be a json object or a json array, so I will use a generic JsonElement
of gson (you can find more information about this class by pressing Ctrl-B
at it in your project or refering here)
因为您的内部对象可以是json对象或json数组,所以我将使用gson的通用JsonElement(您可以通过在项目中按Ctrl-B或在此处引用来查找有关此类的更多信息)
public class CustomJson {
private int type;
private JsonElement object;
}
Then in your Activity, using Gson to parse:
然后在你的Activity中,使用Gson解析:
Gson gson = new Gson();
CustomJson[] customJson = gson.fromJson(jsonString, CustomJson[].class);
Because com.google.gson.JsonElement
can be a JsonObject
(not JSONObject
) or a JsonArray
(not JSONArray
), if you want to convert to JSONObject
and JSONArray
, use the following code:
因为com.google.gson.JsonElement可以是JsonObject(不是JSONObject)或JsonArray(不是JSONArray),所以如果要转换为JSONObject和JSONArray,请使用以下代码:
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 I have tested:
以下是我测试的项目中的logcat结果:
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!
希望这可以帮助!
#1
7
This json structure is inherently gson-unfriendly. i.e You cannot model this cleanly in java because the "object" key refers to a dynamic type. The best you can do with this structure is model it like so:
这种json结构固有地对gson不友好。即你不能在java中干净地建模,因为“对象”键指的是动态类型。你可以用这个结构做的最好的模型是这样的:
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 do some awkward switch on type and the 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 get the json structure changed to something more compatible with java.
最终,最好的解决方案是将json结构更改为与java更兼容的东西。
E.g:
例如:
[
{
"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
2
This may be a bit late for the original poster, but hopefully it will help someone else.
对于原始海报来说,这可能有点晚了,但希望它会帮助其他人。
I am using Gson
in Android
. I have seen everyone use custom classes and long way round solutions. Mine is basic.
我在Android中使用Gson。我看到每个人都使用自定义类和长途解决方案。我的基本。
I have an ArrayList of many different Object types (Models for my database) - Profile is one of them. I get the item using mContactList.get(i)
which returns:
我有一个包含许多不同对象类型的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
}
}
Now I create the Gson
object:
现在我创建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));
Now instead of creating a custom class - just pass it through as a JsonObject
using the following code:
现在不是创建自定义类 - 只需使用以下代码将其作为JsonObject传递:
JsonObject obj = gson.fromJson(str_obj, JsonObject.class);
And now, you can call the object like so:
现在,您可以像这样调用对象:
JsonObject profile = obj.getAsJsonObject("profile");
#3
0
You can set the methods in your model class very easily. Just make a StringRequest. Below is a snippet:
您可以非常轻松地在模型类中设置方法。只需创建一个StringRequest。以下是一个片段:
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 have used this to generate your model class from you json. Your model class will look something like 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;
}
}
#4
-1
For you issue, I suggest the following solution:
对于你的问题,我建议以下解决方案:
Because your inner object can be a json object or a json array, so I will use a generic JsonElement
of gson (you can find more information about this class by pressing Ctrl-B
at it in your project or refering here)
因为您的内部对象可以是json对象或json数组,所以我将使用gson的通用JsonElement(您可以通过在项目中按Ctrl-B或在此处引用来查找有关此类的更多信息)
public class CustomJson {
private int type;
private JsonElement object;
}
Then in your Activity, using Gson to parse:
然后在你的Activity中,使用Gson解析:
Gson gson = new Gson();
CustomJson[] customJson = gson.fromJson(jsonString, CustomJson[].class);
Because com.google.gson.JsonElement
can be a JsonObject
(not JSONObject
) or a JsonArray
(not JSONArray
), if you want to convert to JSONObject
and JSONArray
, use the following code:
因为com.google.gson.JsonElement可以是JsonObject(不是JSONObject)或JsonArray(不是JSONArray),所以如果要转换为JSONObject和JSONArray,请使用以下代码:
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 I have tested:
以下是我测试的项目中的logcat结果:
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!
希望这可以帮助!