【问题标题】:Strange "nameValuePairs" key appear when using Gson使用 Gson 时出现奇怪的“nameValuePairs”键
【发布时间】:2015-04-08 22:38:07
【问题描述】:

我正在尝试从其字段重建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,但没有用。

是否有人有解决方案/解决方法或可以向我解释此密钥的来源?

谢谢。

【问题讨论】:

    标签: java android json gson


    【解决方案1】:

    尝试像这样使用 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);
    

    【讨论】:

    • 我有成员而不是nameValuePairs和Gson,有可能什么都没有吗?
    • 如果您计划构建每个 JsonObject——这意味着你有键值对——但如果你有 JsonObject 字符串怎么办?使用 JSONObject,您可以通过仅传入字符串来创建 JSONObject。你不能用 JsonObject 做到这一点。
    【解决方案2】:

    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 来存储它的内容。

    【讨论】:

    • 因为这就是ment的使用方式:)
    【解决方案3】:

    当我只想将 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());
    

    【讨论】:

    • JsonParser 已弃用
    【解决方案4】:

    最后,我找到了解决这个问题的方法。我不会使用 Gson 保存我的 JSONObject,而是使用 toString() 将其保存为字符串,稍后通过将保存的字符串包装到 JSONArray 中来重建原始 JSONObject,如下例所示。

    在我的情况下,我没有选择将 JSONObject 更改为 com.google.gson.JsonObject 作为已接受答案中的建议,因为我已完成 90% 的编码,而这样的更改会毁了我的日日夜夜。以下是对我有用的代码:

    例如,将 JSONObject 保存到共享首选项(或 DB),如下所示:

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

    【讨论】:

      【解决方案5】:

      你可以使用这个解决方案:

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

      【讨论】:

        猜你喜欢
        • 2020-08-30
        • 2021-03-31
        • 2013-05-05
        • 2015-01-18
        • 2013-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多