使用 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" 的额外键。那么为什么我得到这把钥匙?

注意事项:

这是我的实际结果:

这就是我期望的:

我找到了 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);
  }