【问题标题】:Parse Dynamic Json Objects in gson在 gson 中解析动态 Json 对象
【发布时间】:2016-01-20 09:27:37
【问题描述】:

我有这样的 json 结构,我如何在 Gson 的帮助下解析 json。我需要将键值存储在 json 对象中,我尝试了许多与动态数组相关的示例,但没有方括号的动态 json 数组我无法解析使用Gson.Any 解决方案或需要手动 Json Parse?如果有人觉得重复,请在下面评论答案。

{ "Result":[[
      "Title",
      {
        "0": 1323,
        "1": 3358,
        "2": 2123,
        "3": 8536,
        "4": 1399,
        "5": 9303,
        "7": 9732,
        "8": 3433,
        "9": 1383
      }
    ],[
      "Title",
      {
        "0": 1323,
        "1": 3358,
        "2": 2123,
        "3": 8536,
      }
    ]]}

【问题讨论】:

  • 在您的 Json 数据中是否需要 Title... 或任何类似 Title:xyz
  • @Don'tBenegative "Title" 是一个没有键的对象,不像你说的那样。
  • 那么是否有必要在你的应用中查看
  • @Don'tBenegative 我需要将所有数据存储在对象中
  • 请发布您收到的错误消息或描述错误行为以及导致错误的代码。

标签: java android gson jsonobject


【解决方案1】:

首先,您的 JSON 会导致抛出异常,因为它无效 - 在第二个示例中,您在最后一个值的末尾有一个额外的逗号。 "3": 8536, 应该是 "3": 8536

修复该问题后,只要您正确定义对象,这应该是一项简单的任务。这是我想出的:

public class Results {
    @SerializedName("Result")
    List<Result> results;
}

public class Result {
    String title;
    Map<String, Integer> results;
}

从那里,Result 类需要以特殊方式反序列化,因为Result 类中的字段不直接映射到 JSON 中的条目。相反,我们需要提取每个Result 中包含的JsonArray 的第一个和第二个元素,并相应地对其进行解析。看起来像这样:

public class ResultDeserializer implements JsonDeserializer<Result> {

    @Override
    public Result deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonArray array = json.getAsJsonArray();

        Result result = new Result();
        result.title = array.get(0).getAsString();

        result.results = new LinkedHashMap<String, Integer>();
        for(Entry<String, JsonElement> entry : array.get(1).getAsJsonObject().entrySet()) {
            result.results.put(entry.getKey(), entry.getValue().getAsInt());
        }

        return result;
    }   
}

请注意,我的示例省略了错误检查。最后,注册这个反序列化器,一切准备就绪:

Gson gson = new GsonBuilder().registerTypeAdapter(Result.class, new ResultDeserializer()).create();

Results results = gson.fromJson(json, Results.class);

for(Result r : results.results) {
    System.out.println("Title = " + r.title);
    for(Entry<String, Integer> entry : r.results.entrySet()) {
        System.out.println("\t " + entry.getKey() + " -> " + entry.getValue());
    }
}

打印出来:

Title = Title
     0 -> 1323
     1 -> 3358
     2 -> 2123
     3 -> 8536
     4 -> 1399
     5 -> 9303
     7 -> 9732
     8 -> 3433
     9 -> 1383
Title = Title
     0 -> 1323
     1 -> 3358
     2 -> 2123
     3 -> 8536

我将把它留给 OP 来实现反向,即Result 的序列化程序以产生相同的结果。

【讨论】:

  • 结果 results = gson.fromJson(json, Results.class);在这一行中什么是 json?
【解决方案2】:

找到了在 Gson

中使用 Nested Map 解析上述 json 的简单方法

Result.java

public class Result {
    @SerializedName("formatted_facet_fields")
    Map<String,Map<String,String>> formatted_facet_fields;
}

响应接收方

 Gson  gson=new Gson();
 Result result = gson.fromJson(json_response, Result.class);

【讨论】:

    【解决方案3】:

    是的,您可以解析嵌套的 json 对象。

    if (!exists) {
            keys = json.keys();
            while (keys.hasNext()) {
                nextKeys = (String) keys.next();
                try {
    
                    if (json.get(nextKeys) instanceof JSONObject) {
    
                        if (exists == false) {
                            getKey(json.getJSONObject(nextKeys), key);
                        }
    
                    } else if (json.get(nextKeys) instanceof JSONArray) {
                        JSONArray jsonarray = json.getJSONArray(nextKeys);
                        for (int i = 0; i < jsonarray.length(); i++) {
                            String jsonarrayString = jsonarray.get(i).toString();
                            JSONObject innerJSOn = new JSONObject(jsonarrayString);
    
                            if (exists == false) {
                                getKey(innerJSOn, key);
                            }
    
                        }
    
                    }
    
                } catch (Exception e) {
                    // TODO: handle exception
                }
    
            }
    

    如需全面了解,请查看以下代码:代码说明:https://www.youtube.com/watch?v=ZjZqLUGCWxo

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    相关资源
    最近更新 更多