我使用下面的库来创建一些JSON对象。
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;我想要创建的json是:
{
"function": "create_contact_group",
"parameters": [{
"user_id": "teer",
"comp_id": "97",
"contact_group_name": "Test01",
"invite_user_list": [{
"invite_user_id": "steve"
}]
}]
}我的功能如下:
public JSONObject createJSONRequest() {
/* Create json object */
JSONObject jsonObject = new JSONObject();
Map<String, String> map = new HashMap<>();
map.put("user_id", "teer");
map.put("comp_id", "97");
map.put("contact_group_name", "Test01");
List<String> mInviteUserList = new ArrayList<>();
mInviteUserList.add("steve");
/* Create the list of invitee */
Map<String, String> inviteList = new HashMap<>();
for(String user : mInviteUserList) {
inviteList.put("invite_user_id", user);
}
/* Add the invitees into the json array */
JSONArray inviteArray = new JSONArray();
inviteArray.add(inviteList);
/* Add the json array to the json object */
jsonObject.put("invite_user_list", inviteArray);
JSONArray parameterlist = new JSONArray();
parameterlist.add(map);
parameterlist.add(jsonObject);
jsonObject.put("parameters", parameterlist);
jsonObject.put("function", "create_contact_group");
Log.d(TAG, "jsonObject: " + jsonObject.toJSONString());
return jsonObject;
}但是,当我到达以下行时,该函数会崩溃:
Log.d(TAG, "jsonObject: " + jsonObject.toJSONString())我想这和这句话有关:
parameterlist.add(jsonObject);堆栈跟踪:
java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95) java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:132) at java.lang.StringBuffer.append(StringBuffer.java:126) java.lang.StackOverflowError java.lang.StackOverflowError在org.json.simple.JSONValue.escape(JSONValue.java:266) at org.json.simple.JSONObject.toJSONString(JSONObject.java:116)
非常感谢你的建议,
发布于 2016-06-27 08:05:41
您的代码中有几个问题。一个问题是,您在java代码中创建的结构与上面显示的结构不匹配。我试着在下面描述一下这一点。第二个问题是,您得到了堆栈溢出异常(您知道,但不知道原因)。
引发堆栈溢出异常将导致程序耗尽计算机分配的堆栈内存。你为什么要问?因为您创建了一个递归或循环JSON对象。这不太好,但没什么大不了的,因为这件事很容易解决。那么为什么程序会抛出这个异常呢?那么,看下面的片段:
JSONArray parameterlist = new JSONArray();
parameterlist.add(map);
parameterlist.add(jsonObject);
jsonObject.put("parameters", parameterlist);
jsonObject.put("function", "create_contact_group");创建一个JSONArray,然后将前面创建的JSONObject添加到数组中。之后,将相同的数组添加到已经在数组中的对象中。我希望你能看到问题所在!
因此,不应这样做。以及如何解决这个问题?好吧,我想我应该描述一下你应该如何编写代码来得到你真正想要的结构,所以我会尝试这样做……
怎么办.?
JSON (JavaScript对象表示法) -object总是使用这种类型的括号声明的:{}是一个带有[]的JSON数组,因此,您要生成的JSON应该在以下数据类型中:
{ // <= Root object (a JSON-object).
"function": "create_contact_group", // <= Key in the root-object (where the key is a string and the value a string)
"parameters": [ // <= Key in the root-object (where the key is a string and the value is an array.
{ // <= Object inside the array.
"user_id": "teer", // Key (string/string)
"comp_id": "97", // Key (string/string)
"contact_group_name": "Test01", // Key (string/string)
"invite_user_list": [ // Key (string/array)
{ // Object inside the invite_user_list array
"invite_user_id": "steve" // Key (string/string)
}
]
}
]
}因此,在java中创建JSON对象时,您需要创建一个根对象,然后在其中添加所有的diff参数。向JSONObject添加值是使用JSONObject.put(string, Object)方法完成的,其中字符串是键,对象是值。
因此,首先,我建议创建参数列表。在您的示例中,对对象使用HashMap,这并不是真正的错误,但也不是真正必要的,我只想坚持使用一个JSONObject,它与HashMap<string, Object>并没有什么不同。因此,您可以不使用map.put(...),而可以执行如下操作:
JSONObject param = new JSONObject();
param.put("user_id", "teer");
param.put("comp_id", "97");
param.put("contact_group_name", "Test01");现在,对象值之一应该是数组(invite_user_id),向对象添加数组的最简单方法是创建一个JSONArray,然后添加它。
JSONArray inviteList = new JSONArray();
// Then you need to add an object to the array for each `user` that has invited.
// For-loop here maybe?
JSONObject invitee = new JSONObject();
invitee.put("invite_user_id", user);
inviteList,add(invitee); // This will make it into an array with objects, I.E., [ { "invite_user_id": "Steve" } ]创建invite列表后,将其添加到param对象,如下所示:
param.put("invite_user_list", inviteList);
// Now, param should be in its own list too, so you should probably create a JSONArray for the params.
// Ill leave that to you, and we pretend we have a list of the param objects named "params".最后,创建根对象并设置其值:
JSONObject root = new JSONObject();
root.put("parameters", params);
root.put("function", "create_contact_group");应该是这样的。
这应该会创建一个JSON字符串,它的结构是您在上面创建的。但我建议进行测试(并编写单元测试!)为此(特别是我已经在浏览器中编写了这段代码!)。
但为什么?!
我想我应该尝试描述为什么您的代码没有像我前面描述的那样工作。
首先创建一个根对象,到目前为止(可以在开始时或需要时创建它,这并不重要),然后创建一个HashMap并将属性添加到它。到目前为止,这也是合法的(稍后您可以根据地图创建一个JSONObject )。
在下一部分中,您创建一个ArrayList (我不太确定为什么)并向它添加一个名称,然后在for-循环中向(键invite_user_list)添加一个名称。
这要么是不必要的(因为它只是一个名称),要么是错误的(如果在实际代码的执行中应该有更多的名称),在没有必要的情况下,for-循环不应该存在,如果“不喜欢真实的生活”,则不应该添加到Map中!
相反,invieList应该是一个数组,添加的每个条目都应该是一个对象,其中将"invite_user_id“键设置为名称。
在此之后,将inviteList HashMap添加到新创建的JSONArray中,我想这是可以的,如果您只希望数组中有一个对象,否则我建议在循环之前创建它,并将每个条目添加到其中!
然后,将inviteArray与键invite_user_list放在根对象中,然后创建另一个JSONArray,并添加首先创建的map (开始时创建的参数)和JSONObject (根)。
但是在此之后,您要做的就是为什么要获得stackoverflow异常,将parameterlist (它包含jsonObject (根))添加到jsonObject中,这使得jsonObject存在于一个位于其内部的数组中!
这将创建一个循环JSON结构,如果要展开整个过程,它将永远不会结束,因此计算机会抛出异常。
结果对象的结构也是错误的,因为它看起来如下所示:
{ // Root (jsonObject)
"invite_user_list": [
{ "invite_user_id": "steve" }
]
"parameters": [
{ // The "map" hashmap
"user_id", "teer",
"comp_id": "97",
"contact_group_name": "Test01"
},
{ // The jsonObject object (which is also the root!)
"invite_user_list": [
{ "invite_user_id": "steve" }
],
"parameters": [
{ // The "map" hashmap
"user_id", "teer",
"comp_id": "97",
"contact_group_name": "Test01"
},
{
// The jsonObject object again (which is also the root and the parent!)
// ... and so on til eternity!
}
],
"function": "create_contact_group"
}
],
"function": "create_contact_group"
}额外的..。
我想在这里的结尾加上(我希望你读完我上面写的整堵墙,因为你可能学到了一些东西!)有一种更简单的方法。
现在,我自己还没有使用这个库,但据我所知,它应该能够序列化整个对象,这个库可以在谷歌github repos找到,它可以用作json序列化程序,并将类实例转换为json字符串,然后您可以为整个对象创建一个类,然后在函数的末尾填充它并序列化它,而不需要使用JSONArray或JSONObject。
发布于 2016-06-27 08:14:16
此问题是由于在尝试将JsonObject添加到JsonArray和viceVersa时发生的递归过程造成的。
你所做的是,
JSONArray parameterlist = new JSONArray();
parameterlist.add(map);
parameterlist.add(jsonObject);然后
jsonObject.put("parameters", parameterlist);问题是,当您使用jsonObject.toJSONString()打印对象时,它首先将获取parameterlist,然后由于jsonObject是parameterlist JsonArray上键值对的一部分,它将重新获取jsonObject,然后再获取parameterlist,然后这个进程继续进行,从而导致StackOverflow问题。
快速解决方案是在分配JsonObject的同时创建新的parameterList,
JSONArray parameterlist = new JSONArray();
parameterlist.add(map);
parameterlist.add(jsonObject);
JSONObject newJson = new JSONObject();
newJson.put("parameters", parameterlist);
System.out.println(newJson.toJSONString());https://stackoverflow.com/questions/38048363
复制相似问题