使用 Gson 时出现奇怪的 "nameValuePairs" 键
Strange "nameValuePairs" key appear when using Gson
我正在尝试从它的字段中重建一个 Object
(我将这些字段作为 JSONObject),像这样:
JSONObject jObj = new JSONObject();
JSONObject jObj1 = new JSONObject();
JSONObject jObj2 = new JSONObject();
JSONObject jObj21 = new JSONObject();
JSONObject jObj22 = new JSONObject();
jObj1.put("jObj11", "value11");
jObj1.put("jObj12", "value12");
jObj21.put("jObj211", "value211"); // level 2
jObj21.put("jObj212", "value212");
jObj21.put("jObj213", "value213");
jObj22.put("jObj221", "value221");
jObj22.put("jObj222", "value222");
jObj22.put("jObj223", "value223");
jObj2.put("jObj21", jObj21); // level 1
jObj2.put("jObj22", jObj22);
jObj.put("jObj1", jObj1); // level 0
jObj.put("jObj2", jObj2);
我使用这些行从 Obeject
中获取 Json
GsonBuilder builder = new GsonBuilder();
Gson gSon = builder.create();
gSon.toJSon(jObj);
问题 是当我用 Gson 解析主 Object
( jObj ) 时,我发现了一个名为 "nameValuePairs"
的额外键。那么为什么我得到这把钥匙?
注意事项:
- 如果我这样做:
jObj.toString();
在日志上,此键消失。
- 如果我这样做:
jObj.opt("nameValuePairs");
结果是 Null(就像没有名为 "nameValuePairs" 的密钥)。
这是我的实际结果:
这就是我期望的:
我找到了 something similar to my problem,但没有用。
有没有人有 solution/workaround 或者可以解释一下这个密钥的来源?
谢谢。
GSON是一个POJO序列化的工具。如果您自己构建 JSONObject,则不需要 gSon.toJSon(jObj);
,您只需调用 jObj.toString()
即可获得结果。
正确的 GSON 用法是为您的数据结构创建 POJO 对象。
您的根对象将如下所示:
public class jObj {
JObj11 jObj11;
JObj12 jObj12;
}
以这种方式定义整个结构后,您可以使用 gSon.toJSon(jObj);
将其序列化为 JSON,而无需使用任何 JSONObject。 GSON 将遍历它并生成 JSON 字符串。
在您的示例中,GSON 尝试序列化 JSONObject Java 对象的内部结构,而不是它所表示的 JSON 结构。如您所见,JSONObject 使用 nameValuePair 来存储它的内容。
尝试像这样使用 Gson 的 JsonObject
而不是 JSONObject
:
JsonObject jObj = new JsonObject();
JsonObject jObj1 = new JsonObject();
JsonObject jObj2 = new JsonObject();
JsonObject jObj21 = new JsonObject();
JsonObject jObj22 = new JsonObject();
jObj1.addProperty("jObj11", "value11");
jObj1.addProperty("jObj12", "value12");
jObj21.addProperty("jObj211", "value211"); // level 2
jObj21.addProperty("jObj212", "value212");
jObj21.addProperty("jObj213", "value213");
jObj22.addProperty("jObj221", "value221");
jObj22.addProperty("jObj222", "value222");
jObj22.addProperty("jObj223", "value223");
jObj2.add("jObj21", jObj21); // level 1
jObj2.add("jObj22", jObj22);
jObj.add("jObj1", jObj1); // level 0
jObj.add("jObj2", jObj2);
String json = new Gson().toJson(jObj);
终于,我找到了解决这个问题的方法。我不会使用 Gson 保存我的 JSONObject,而是使用 toString() 将它保存为字符串,然后通过将保存的字符串包装到 JSONArray 中重建原始 JSONObject,如下例所示。
在我的例子中,我没有选择按照接受的答案中的建议将 JSONObject 更改为 com.google.gson.JsonObject,因为我的 90% 编码已经完成,这样的更改会毁了我的日日夜夜。以下是对我有用的一段代码:
例如,将 JSONObject 保存到共享首选项(或数据库),如下所示:
public void saveJson(JSONObject reqJson) {
sharedPref.editor().put("savedjson_key",reqJson.toString()).apply();
}
然后,当你想重建原始的 JSONObject 时:
public JSONObject getSavedJson() {
String reqJson=sharedPref.getString("savedjson_key");
if (reqJson != null) {
try {
JSONArray arr = new JSONArray(("["+reqJson+"]").replaceAll("\\", ""));
return arr.getJSONObject(0);
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
当我只想将 Gson 用于漂亮打印时,我遇到了同样的问题。 JsonObject 工作正常,但如果您仍然想使用 JSONObject 而不是 JsonObject,那么您可以这样使用它:
public class JsonUtil {
public static String toPrettyFormat(String jsonString)
{
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(jsonString).getAsJsonObject();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String prettyJson = gson.toJson(json);
return prettyJson;
}
}
并像这样将 JSONObject 作为字符串传递:
String prettyJson = JsonUtil.toPrettyFormat(jsonObject.toString());
您可以使用此解决方案:
//org.json.JSONObject
JSONObject jObj = new JSONObject();
//com.google.gson.JsonObject
JsonObject jObj1 = new JsonObject();
jObj1.addProperty("jObj11", "value11");
JsonObject jObj2 = new JsonObject();
jObj2.addProperty("jObj12", "value12");
//JSONObject put(String name, Object value)
jObj.put("jObj1", jObj1);
jObj.put("jObj2", jObj2);
//Result
objectToJson(toMap(jObj));
public Map<String, Object> toMap(JSONObject content) {
final Map<String, Object> map = new HashMap<>(content.length());
for (final Iterator<String> iterator = content.keys(); iterator.hasNext(); ) {
final String key = iterator.next();
map.put(key, get(key));
}
return map;
}
public static <T> String objectToJson(T object) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
return gson.toJson(object);
}
我正在尝试从它的字段中重建一个 Object
(我将这些字段作为 JSONObject),像这样:
JSONObject jObj = new JSONObject();
JSONObject jObj1 = new JSONObject();
JSONObject jObj2 = new JSONObject();
JSONObject jObj21 = new JSONObject();
JSONObject jObj22 = new JSONObject();
jObj1.put("jObj11", "value11");
jObj1.put("jObj12", "value12");
jObj21.put("jObj211", "value211"); // level 2
jObj21.put("jObj212", "value212");
jObj21.put("jObj213", "value213");
jObj22.put("jObj221", "value221");
jObj22.put("jObj222", "value222");
jObj22.put("jObj223", "value223");
jObj2.put("jObj21", jObj21); // level 1
jObj2.put("jObj22", jObj22);
jObj.put("jObj1", jObj1); // level 0
jObj.put("jObj2", jObj2);
我使用这些行从 Obeject
GsonBuilder builder = new GsonBuilder();
Gson gSon = builder.create();
gSon.toJSon(jObj);
问题 是当我用 Gson 解析主 Object
( jObj ) 时,我发现了一个名为 "nameValuePairs"
的额外键。那么为什么我得到这把钥匙?
注意事项:
- 如果我这样做:
jObj.toString();
在日志上,此键消失。 - 如果我这样做:
jObj.opt("nameValuePairs");
结果是 Null(就像没有名为 "nameValuePairs" 的密钥)。
这是我的实际结果:
这就是我期望的:
我找到了 something similar to my problem,但没有用。
有没有人有 solution/workaround 或者可以解释一下这个密钥的来源?
谢谢。
GSON是一个POJO序列化的工具。如果您自己构建 JSONObject,则不需要 gSon.toJSon(jObj);
,您只需调用 jObj.toString()
即可获得结果。
正确的 GSON 用法是为您的数据结构创建 POJO 对象。
您的根对象将如下所示:
public class jObj {
JObj11 jObj11;
JObj12 jObj12;
}
以这种方式定义整个结构后,您可以使用 gSon.toJSon(jObj);
将其序列化为 JSON,而无需使用任何 JSONObject。 GSON 将遍历它并生成 JSON 字符串。
在您的示例中,GSON 尝试序列化 JSONObject Java 对象的内部结构,而不是它所表示的 JSON 结构。如您所见,JSONObject 使用 nameValuePair 来存储它的内容。
尝试像这样使用 Gson 的 JsonObject
而不是 JSONObject
:
JsonObject jObj = new JsonObject();
JsonObject jObj1 = new JsonObject();
JsonObject jObj2 = new JsonObject();
JsonObject jObj21 = new JsonObject();
JsonObject jObj22 = new JsonObject();
jObj1.addProperty("jObj11", "value11");
jObj1.addProperty("jObj12", "value12");
jObj21.addProperty("jObj211", "value211"); // level 2
jObj21.addProperty("jObj212", "value212");
jObj21.addProperty("jObj213", "value213");
jObj22.addProperty("jObj221", "value221");
jObj22.addProperty("jObj222", "value222");
jObj22.addProperty("jObj223", "value223");
jObj2.add("jObj21", jObj21); // level 1
jObj2.add("jObj22", jObj22);
jObj.add("jObj1", jObj1); // level 0
jObj.add("jObj2", jObj2);
String json = new Gson().toJson(jObj);
终于,我找到了解决这个问题的方法。我不会使用 Gson 保存我的 JSONObject,而是使用 toString() 将它保存为字符串,然后通过将保存的字符串包装到 JSONArray 中重建原始 JSONObject,如下例所示。
在我的例子中,我没有选择按照接受的答案中的建议将 JSONObject 更改为 com.google.gson.JsonObject,因为我的 90% 编码已经完成,这样的更改会毁了我的日日夜夜。以下是对我有用的一段代码:
例如,将 JSONObject 保存到共享首选项(或数据库),如下所示:
public void saveJson(JSONObject reqJson) {
sharedPref.editor().put("savedjson_key",reqJson.toString()).apply();
}
然后,当你想重建原始的 JSONObject 时:
public JSONObject getSavedJson() {
String reqJson=sharedPref.getString("savedjson_key");
if (reqJson != null) {
try {
JSONArray arr = new JSONArray(("["+reqJson+"]").replaceAll("\\", ""));
return arr.getJSONObject(0);
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
当我只想将 Gson 用于漂亮打印时,我遇到了同样的问题。 JsonObject 工作正常,但如果您仍然想使用 JSONObject 而不是 JsonObject,那么您可以这样使用它:
public class JsonUtil {
public static String toPrettyFormat(String jsonString)
{
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(jsonString).getAsJsonObject();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String prettyJson = gson.toJson(json);
return prettyJson;
}
}
并像这样将 JSONObject 作为字符串传递:
String prettyJson = JsonUtil.toPrettyFormat(jsonObject.toString());
您可以使用此解决方案:
//org.json.JSONObject
JSONObject jObj = new JSONObject();
//com.google.gson.JsonObject
JsonObject jObj1 = new JsonObject();
jObj1.addProperty("jObj11", "value11");
JsonObject jObj2 = new JsonObject();
jObj2.addProperty("jObj12", "value12");
//JSONObject put(String name, Object value)
jObj.put("jObj1", jObj1);
jObj.put("jObj2", jObj2);
//Result
objectToJson(toMap(jObj));
public Map<String, Object> toMap(JSONObject content) {
final Map<String, Object> map = new HashMap<>(content.length());
for (final Iterator<String> iterator = content.keys(); iterator.hasNext(); ) {
final String key = iterator.next();
map.put(key, get(key));
}
return map;
}
public static <T> String objectToJson(T object) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
return gson.toJson(object);
}