【问题标题】:How can I deserialize a json into a hashmap that contains a key and a Object?如何将 json 反序列化为包含键和对象的 hashmap?
【发布时间】:2015-11-14 06:26:35
【问题描述】:

这是我的 Json 的形式:

{
"records": {
    "fastest": {
        "30": {
            "category": "fastest",
            "timestamp": 1407422694,
            "value": 2,
            "group_id": 30,
            "trip_id": 3429,
            "id": 28247
        },
        "42": {
            "category": "fastest",
            "timestamp": 1423570020,
            "value": -467,
            "group_id": 42,
            "trip_id": 9082,
            "id": 28040
        },
        "43": {
            "category": "fastest",
            "timestamp": 1410960788,
            "value": 16,
            "group_id": 43,
            "trip_id": 5138,
            "id": 28044
        },
        "46": {
            "category": "fastest",
            "timestamp": 1404286123,
            "value": 1609,
            "group_id": 46,
            "trip_id": 2524,
            "id": 28050
        }
    },
    "longest_flight": {
        "category": "longest_flight",
        "timestamp": 1434897403,
        "value": 1242203,
        "group_id": null,
        "trip_id": 12633,
        "id": 27950
    }
}
}

我知道如何获取longest_flight 对象。但是如何创建包含从“最快”json 对象创建的列表的 hashmap?

【问题讨论】:

  • 想象一下,如果没有父亲 google/stack,工程师们会解决这个问题。如果是你我的朋友,你会被解雇的。您应该考虑先进行谷歌搜索。安卓:你的问题。你几乎是说为我做这件事
  • 问题是 id 是动态的,在 hashmap 中获得大约 200 个值,例如 "id" : {object}。现在我正在使用 GSON,而 gson 有一种方法可以提取 JSONARRAY 或 JSONOBJECT。我对如何提取哈希图有一个想法。但是,这样我就不是第一个这样做的人。我说我会问,也许有人知道这个库(在ios上他们有一个库)。无论如何,没有找到图书馆,以及我发现我们没有帮助的谷歌示例,我开始并以自己的方式完成了它。但这让我倒退了大约2-3个小时。我希望这不会发生。

标签: android json serialization hashmap json-deserialization


【解决方案1】:

我不确定您是在问如何从 URL 中获取 JSONObject,还是在拥有 JSONObject 后如何仅检索该对象。所以这是两者的答案。

这会从 URL 获取 JSONObject:

import org.json.JSONException;
import org.json.JSONObject;

//attempts to open a connection to the specified url and returns a JSon response object
public JSONObject getResponseObject() {
    try {
        //Use URL connection 
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();


        conn.setRequestProperty("Accept", "application/json");


        // attempt the connection
        conn.connect();

        // Get the response code
        responseCode = conn.getResponseCode();

        // Check the response code, if the HTTP response code is 4nn
        // (Client Error) or 5nn (Server Error), then you may want to
        // read the HttpURLConnection#getErrorStream() to see if the
        // server has sent any useful error information.
        if (responseCode < 400) {

            // Get the response InputStream if all is well
            responseInputStream = conn.getInputStream();

            responseString = getResponseText(responseInputStream);

            try{
                responseObject = new JSONObject(responseString);
            }catch (JSONException et) {
                e.printStackTrace();
            }

            conn.disconnect();


        } else if (responseCode >= 400) {

            // Get the response ErrorStream if we got an error instead
            responseInputStream = conn.getErrorStream();
            conn.disconnect();
        }


    } catch (IOException e) {
       e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
 return responseObject;
}

你可以像这样解析 responseObject:

JSONObject records = responseObject.getJSONObject("records");
JSONObject longestFlight = records.getJSONObject("longest_flight");
String id = longestFlight.getString("id");

遍历 JSON 中的键:

我应该提到,您可能需要为 JSON 中的每个对象执行此操作。

Iterator<String> iter = json.keys();
while (iter.hasNext()) {
    String key = iter.next();
   try {
       Object value = json.get(key);
   } catch (JSONException e) {
       // Something went wrong!
   }
}

【讨论】:

  • 我使用 Volley 进行联网,你也应该这样做,因为它更易于使用。我也知道如何检索 json 对象。我的问题是我无法将我的 JSONObject“Records”转换为类 Record.class,因为我会得到所有动态键(对于 hashmap)。所以我做了下面的类,它通过 json,只取 hashmap 的值,然后为每个值创建一个类。将它们设置在一个数组中,然后我返回对象的 Arraylist :)
  • 有趣。你看过 Google 的 Gson 库吗?它允许直接从 Json 到 Class 序列化,使用起来非常直观。我不确定它会如何处理序列化动态 JSON 对象,就像您尝试做的那样,但它可能值得一试。
  • 我正在使用 Gson 和 Volley。但是 Gson 允许您直接从 Json 序列化到 Class a JSONObject 或 JSONArray,但不适用于 hashmap。如果您查看我在下面发布的答案。你看我在我制作的代码中使用 Gson :D
  • 我不知道,我不做糟糕的 JSON,我只是得到它并需要解析它。这就是它为 iOS 完成的方式,这就是我需要在 Android 上完成的方式,使用 android 的烦人部分....
  • 在这种情况下,Json.keys() 方法可能会派上用场。我将其添加到上面的答案中。它应该允许您使用 get 函数创建带有值的哈希映射。它与您所做的非常相似,只是字符串抖动较少。
【解决方案2】:

做了一个从 JSON 返回数组列表的函数(因为键也在对象内部,我的逻辑不需要它) 代码:

 public static ArrayList<Record> sortedRecordsFromJson(String statsJson){
    try{
        Map map = new Gson().fromJson(statsJson, Map.class);
        ArrayList<Record> records = new ArrayList<>();
        Iterator it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pair = (Map.Entry)it.next();
            if(pair != null){
                Log.i("","pair : " + pair.toString());
                String json = pair.getValue().toString().replace(" ", "-");
                json = json.replace(",-", ", ");
                Log.i("","pair json is: " + json);
                JSONObject citiesObj = new JSONObject(json);
                Log.i("","cities obj " + citiesObj.toString());
                if(citiesObj != null){
                    Record tempMap = new Gson().fromJson(citiesObj.toString(), Record.class);
                    records.add(tempMap);
                }
            }
            it.remove(); // avoids a ConcurrentModificationException
        }
        Log.i("","got here, size:" + records.size());
        return records;
    }catch (Exception e){
        Log.i("","exception is: " + e.getMessage());
        return null;
    }
}

这样称呼它:

   ArrayList fastest = Utils.sortedRecordsFromJson(statsJson.getJSONObject("fastest").toString());

【讨论】:

    猜你喜欢
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多