如何使用 Gson 解析深层嵌套 json 对象中的字段并在 android 中进行改造?

How do I parse a field from a deep nested json object using Gson and retrofit in android?

我有一个独特的情况,我必须从 json 的深层嵌套对象中获取特定时间。这有点复杂,我找不到解决方案,所以正在寻找解决这个问题的想法和方法

我有一个json如下:

[{
        "mySpaceId": 73220,
        "myBuildingId": 14019,
        "myFloorId": 10569,
        "myFloorNumber": "4",
        "myFloorName": "4th Floor",
        "spaceName": "My Room 4",
        "capacity": 5,
        "type": "huddle",
        "busyAt": []
    },
    {
        "mySpaceId": 73219,
        "myBuildingId": 14019,
        "myFloorId": 10569,
        "myFloorNumber": "4",
        "myFloorName": "4th Floor",
        "spaceName": "My room 5",
        "description": null,
        "capacity": 4,
        "type": "huddle",
        "timeZone": "America/New_York",

        "busyAt": [{
            "from": "2019-06-07T23:00:00+0000",
            "to": "2019-06-07T23:15:00+0000",
            "events": [{
                "id": "109142028",
                "series_id": null,
                "recurrence_id": null,
                "uid": "ABCDE",
                "space_id": 73219,
                "start": {
                    "date_time": "2019-06-07T19:00:00-0400",
                    "time_zone": "America/New_York"
                },
                "end": {
                    "date_time": "2019-06-07T19:15:00-0400",
                    "time_zone": "America/New_York"
                },
                "started_at": "2019-06-07T19:00:00-0400",
                "ended_at": "2019-06-07T19:15:00-0400"
            }]
        }]
    }
]

我使用这个:http://www.jsonschema2pojo.org/ 从上面的 json 字符串生成一个 class。 我想知道如何检索 "started_at": "2019-06-07T19:00:00-0400",

从 busyAt-> 事件到我的主要模型 class 由上述站点生成? 与 mySpaceId 处于同一级别。我目前使用以下 :

 public List<BusyAt> getBusyAt() {
        return busyAt;
    }

    public void setBusyAt(List<BusyAt> busyAt) {
        this.busyAt = busyAt;
    }

有没有办法在这个级别检索 started_at 并以格式解析日期和时间:8:00 am?在我的代码中使用它。

知道怎么做吗? 谢谢!如果这令人困惑或需要更多说明,请告诉我,很高兴 post 更多代码。

你将不得不做这样的事情:

JSONArray array = new JSONArray(result);
for (int i = 0; i < array.length(); ++i) {
JSONObject jObj = array.getJSONObject(i);

String busyAt = jObj.getString("busyAt");
// convert it to json array 
JSONArray busyAtArray = new JSONArray(busyAt)
String endedAt = busyAtArray.getJSONObject(0).getString("ended_at")
// convert the string and get the time from it

}

我希望你从这里得到了大概的想法。这个片段当然可以用更好的方式来写。

您可以使用 google GSON 来解析这个 JSON。 google 的 link GSON 是 [https://search.maven.org/artifact/com.google.code.gson/gson/2.8.5/jar]

这比创建 classes 更好。 如果您想使用实际源代码进行调试,只需单击页面右侧的下载部分(由上述 link 生成的页面)并下载 Jar 文件和源文件。最后,将这些包含在您的项目中。

就代码而言,这里是我编写的代码片段:

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.File;
import java.io.FileReader;
import java.util.logging.Logger;

public class JSONTester {

    private static File json = new File("/Users/XXXX/Production/Whosebug/JSON_From_https-::whosebug.com:questions:56501897:how-do-i-retrieve-json-from-a-deep-nested-object#56501897.json");
    private static Logger jsonLogger = Logger.getLogger(JSONTester.class.getSimpleName());


    public static void main(String[] args) {
        JsonElement jsonElement;
        try {
            jsonElement = new JsonParser().parse(new FileReader(json));
        } catch (Exception e) {
            jsonLogger.severe("There was an error parsing the JSON with message " + e.getLocalizedMessage());
            return;
        }

        if (jsonElement != null) {
            if (jsonElement instanceof JsonArray) {
                JsonArray jsonArray = (JsonArray) jsonElement;
                for (int i = 1; i < jsonArray.size(); i++) {
                    JsonElement element = jsonArray.get(i);
                    //We are considering only JSON objects inside a JSONArray.
                    if (element instanceof JsonObject) {
                        JsonObject jsonObject = (JsonObject) element;
                        if (jsonObject.has("busyAt")) {
                            JsonArray busyAtJsonArray =
                                    jsonObject.getAsJsonArray("busyAt");
                            if (busyAtJsonArray != null && busyAtJsonArray.size() >
                                    0) {
                                //You got the busyAt json array. Now, since you already know
                                //that events is another JSONArray within busyAt array, process this
                                //array accordingly. Get the first JsonObject from the events
                                //array to get "started_at" and "ended_at" fields from
                                //this (first) json object.
                                                                    //busyAt.get(0) = from,to,events[],
                                JsonObject firstJsonObject = (JsonObject) busyAtJsonArray.get(0);
                                JsonArray eventsArray = firstJsonObject.getAsJsonArray("events");
                                JsonObject eventsFirstObject = (JsonObject) eventsArray.get(0);
                                String started_At = eventsFirstObject.get("started_at").getAsString();
                                String ended_At = eventsFirstObject.get("ended_at").getAsString(); 

                            }
                        }
                    }
                }
            }
        }
    }
} 

请注意,我在假设 JsonElement 是 JsonArray 还是 JsonObject 时非常小心。你也应该尝试这样做,这样当你遇到任何异常时,你就会知道是什么原因造成的。显然,你会得到 class 强制转换异常(或其他取决于你做错了什么),但最好跟踪它发生的原因。

有关更多详细信息,请阅读 GSON 库文档 (link https://sites.google.com/site/gson/gson-user-guide) 以及如何解析 Json 对象、Json 数组等。这将清楚地解释使用 GSON 的好处及其相对于其他 JSON 解析方法的优势。当您解析其中任何一个时,您得到的基本元素将是 JsonElement。然后,您可以根据您认为那里的正确元素(json 对象或数组)将其转换为上述任何一个。或者,如果您 well-versed 具有 JSON 结构,您可以直接转换它并获得相应的结果。

I use this : http://www.jsonschema2pojo.org/ to generate a class from the above json string. I was wondering how do I retrieve the "started_at": "2019-06-07T19:00:00-0400", from busyAt-> events into my main model class generated by the above site? Say at the same level as mySpaceId. I currently use the following :

如果我对你的解释正确,你已经使用 www.jsonschema2pojo.org 创建了以下 classes: -

  • 一个名为 "Entity" 的 class,其中包含 "mySpaceId" 和 "BusyAt" 的列表。
  • class "BusyAt" 包含 "Event".
  • 的列表
  • class "Event" 包含一个名为 StartedAt 的字符串。

我假设您想直接从 top-most class ("Entity")

中检索每个列表的第一个条目(如果存在)

类似于:-

entity.busyAt(0).events(0).startedAt
if either busyAt or event list is empty or null, then return empty string for startedAt.

您可以做的是在 "Entity" class(包含 mySpaceId 和 List 的根 class)中创建以下方法。

public String getStartedAt(){
  //check if the busyAt List contains items or not.
  if (busyAt ==null || busyAt.isEmpty()){
    return "";
  }
  //take the list of events from the first busyAt in the array
  List<Event> eventList = busyAt.get(0).getEvents();
  //check if the event List contains items or not.
  if (eventList ==null || eventList.isEmpty()){
    return "";
  }
  //return the StartAt value of the first event.
  return eventList.get(0).getStartedAt(); 
}