【问题标题】:How to get data from nested JSON objects using Gson如何使用 Gson 从嵌套的 JSON 对象中获取数据
【发布时间】:2020-09-29 09:35:51
【问题描述】:

我想从 API 中获取县名,它会返回嵌套对象;

"countries": {
    "1": {
        "name": "Cyprus",
        "nameTurkish": "KKTC",
        "nameNative": "Kıbrıs"
    },
    "2": {
        "name": "Turkey",
        "nameTurkish": "Türkiye",
        "nameNative": "Türkiye"
    },
    "3": {
        "name": "Monaco",
        "nameTurkish": "Monako",
        "nameNative": "Monaco"
    },

等等,有 200 多个国家/地区,每个县都有自己的“NUMBER_ID”。最后,我想列出所有“名称”信息。我想我应该使用 JsonDeserializer 但不幸的是我不能。

【问题讨论】:

  • 从国家 json 对象中获取所有键并使用 for 循环获取并保存列表中每个国家/地区的名称。

标签: android json gson retrofit deserialization


【解决方案1】:

整个 JSON 响应可以读取为 JSONObject,其中包含多个元素,您可以遍历这些元素并获取不同的数据。

String jsonResponse = ""; // Put the entire JSON response as a String 
JSONObject root = new JSONObject(jsonResponse);

JSONArray rootArray = root.getJSONArray("countries"); // root element of the json respons

for (int i = 0; i < rootArray.length(); i++) {

    JSONObject number = rootArray.getJSONObject(i);
    String country = number.getString("name"); // Get country name

    // Here you can add `country` into a List
}

更新:

但我的 JSON 文件中没有数组,它们都是对象,每个 country 在一个对象中,每个对象都有自己的 SerializedName

您可以将其读入 JSONOjbect,而不是使用 JSONArray,您可以迭代 JSONObject 的长度,如下所示。

try {
    JSONObject root = new JSONObject(jsonResponse);
    JSONObject countries = root.getJSONObject("countries");

    for (int i = 1; i <= countries.length(); i++) {

        JSONObject number = countries.getJSONObject(String.valueOf(i));
        String country = number.getString("name"); // Get country name

        // Here you can add the `country` into a List
    }

} catch (JSONException e) {
    e.printStackTrace();
}

【讨论】:

  • 你好,但是我的JSON文件中没有数组,都是对象,每个国家都在一个对象中,每个对象都有自己的SerializedName
  • @Ahmet 感谢您的通知,我已经用UPDATE 部分修改了答案,它适用于您给定的 JSON.. 希望它可以帮助
  • 谢谢@Zain,当我将数据放入 Asset 文件夹时,您编辑的模型运行良好。但是我的 JSON 数据在 API 中,我想通过改造来获得它,你能给我一个建议吗?
  • @Ahmet 不客气.. 请查看the answer here,尤其是帮助您自动创建 pojo 和改造课程的在线工具
【解决方案2】:

尝试使用 TypeToken。

Gson gson = new Gson();

List<Country> list = gson.fromJson(gson.toJson(what_you_get_data), new TypeToken<ArrayList<Country>>(){}.getType()); //Country is VO class what you make.

【讨论】:

    【解决方案3】:

    在这里,您可以看到您的数据看起来像HashMap,所以我只是尝试了这种方式,并且您的数据解析成功,没有出现故障:

    1. 创建 Pojo:

      public class Countries {
          private HashMap<String, Country> countries;
          public HashMap<String, Country> getCountries() { return countries; }
      
          public void setCountries(HashMap<String, Country> countries) { this.countries = countries; }
      }
      
      public class Country {
          private String name;
          private String nameTurkish;
          private String nameNative;
      
          public String getName() { return name; }
          public void setName(String name) { this.name = name;}
          public String getNameTurkish() { return nameTurkish; }
          public void setNameTurkish(String nameTurkish) { this.nameTurkish = nameTurkish; }
          public String getNameNative() { return nameNative; }
          public void setNameNative(String nameNative) { this.nameNative = nameNative; }
      }
      
    2. 创建一个 Gson 对象并解析它:

      Gson gson = new Gson();
      
          // Countries Object
          Type testC = new TypeToken<Countries>(){}.getType();
          Countries ob = gson.fromJson(test, testC);
          String newData = gson.toJson(ob.getCountries());
      
          System.out.println("New Data: "+newData);
      
          // All country in HashMap
          Type country = new TypeToken<HashMap<String, Country>>(){}.getType();
          HashMap<String, Country> countryHashMap = gson.fromJson(newData, country);
      
          // Print All HashMap Country
          for (Map.Entry<String, Country> set : countryHashMap.entrySet()) {
              System.out.println("==> "+set.getKey() + " = " + set.getValue());
          }
      
    3. 输出:

      I/System.out: ==> 1 = Country{name='Cyprus', nameTurkish='KKTC', nameNative='Kıbrıs'}
      I/System.out: ==> 2 = Country{name='Turkey', nameTurkish='Türkiye', nameNative='Türkiye'}
      I/System.out: ==> 3 = Country{name='Monaco', nameTurkish='Monako', nameNative='Monaco'}
      

    【讨论】:

    • 我已经看过了。有一个恒定的“内容”对象,但在我的示例中,每个国家/地区都有自己的 SerializedName
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多