【问题标题】:Java - How to Parse empty Nested Json ArrayJava - 如何解析空的嵌套 Json 数组
【发布时间】:2020-09-27 17:57:00
【问题描述】:

我正在尝试使用 (GSON) 库将 JSON 数据解析为 Java 中的字符串,我能够解析除 JSON 数组之一之外的所有 JSON 字段数据。我想检查它是否为空/空,然后在字符串变量中存储空值,如果不是,则存储原始值。

输入 JSON 数据:

{
    "expand": "schema,names",
    "startAt": 0,
    "maxResults": 50,
    "total": 37875,
     "issues": [
            {
                "id": "1190",
                "key": "GDS-81",
                "fields": {
                    "issuetype": {
                        "id": "2170",
                        "name": "Service Request with Approvals",
                        "subtask": false
                    },
                    "customfield_29805": {
                        "id": "26",
                        "name": "Issue - First Response",
                        "completedCycles": []
                    }
                }
            }
        ]
     }

到目前为止我已经完成的代码,

JsonObject object = (JsonObject) new JsonParser().parse(jsonResponse);              
JsonArray issuesArray = object.getAsJsonArray("issues");
for(int i=0; i<issuesArray.size(); i++) {
    JsonObject currentissues = (JsonObject) issuesArray.get(i); 
    String Issue_Id = (String) currentissues.get("id").toString().replace("\"", "");
    String Issue_Key =  (String) currentissues.get("key").toString().replace("\"", ""); 
    String Issue_Type = (String) currentissues.get("fields").getAsJsonObject().get("issuetype").getAsJsonObject().get("name").getAsString();
    JsonObject customfield = (JsonObject) currentissues.get("fields").getAsJsonObject().get("customfield_29805");
    JsonArray completedCyclesArray= customfield.getAsJsonArray("completedCycles");
    String Issue_FirstResponseStartTime = (completedCyclesArray.size() > 0) ? completedCyclesArray.getAsString() : "NULL";
}

但是,当我执行代码时,出现以下错误:JsonObject customfield

java.lang.ClassCastException: com.google.gson.JsonNull cannot be cast to com.google.gson.JsonObject

[![UpdatedCode StackTrace][1]][1] [1]:https://i.stack.imgur.com/2wY0S.jpg

【问题讨论】:

标签: java json gson


【解决方案1】:
  1. 您不需要显式地将 JsonElement 转换为 JsonObject 而是使用 getAsJsonArray ,一旦您获得了数组,就可以遍历它的所有元素。

  2. 您还需要在检查其大小之前对 completedCyclesArray 进行空检查,否则它将为您提供 NPE ,我也已修复该问题。 请找到修改后的工作代码如下

     JsonParser parser = new JsonParser();
     JsonArray array = parser.parse(jsonResponse).getAsJsonArray();
     for(JsonElement e : array) {
         JsonObject currentissues = (JsonObject) e;
         String Issue_Id = (String) currentissues.get("id").toString().replace("\"", "");
         String Issue_Key =  (String) currentissues.get("key").toString().replace("\"", "");
         String Issue_Type = (String) currentissues.get("fields").getAsJsonObject().get("issuetype").getAsJsonObject().get("name").getAsString();
         JsonObject customfield = (JsonObject) currentissues.get("fields").getAsJsonObject().get("customfield_29805");
         JsonArray completedCyclesArray= customfield.getAsJsonArray("completedCycles");
         String Issue_FirstResponseStartTime = (null != completedCyclesArray && completedCyclesArray.size() > 0) ? completedCyclesArray.getAsString() : "NULL";
     }
    

    }

请为更新的 json 请求(不是数组,而是嵌套的 json 请求)找到我的工作解决方案

JsonObject object = (JsonObject) new JsonParser().parse(jsonResponse);
JsonArray issuesArray = object.getAsJsonArray("issues");
String expand = object.get("expand").toString();
String startAt = object.get("startAt").toString();
String maxResults = object.get("maxResults").toString();
String total = object.get("total").toString();
System.out.println(String.format("expand %s , startAt %s, maxResults %s, total %s", expand, startAt, maxResults, total));
IntStream.range(0, issuesArray.size()).mapToObj(i -> (JsonObject) issuesArray.get(i)).forEach(currentissues -> {
    String Issue_Id = (String) currentissues.get("id").toString().replace("\"", "");
    String Issue_Key = (String) currentissues.get("key").toString().replace("\"", "");
    String Issue_Type = (String) currentissues.get("fields").getAsJsonObject().get("issuetype").getAsJsonObject().get("name").getAsString();
    JsonObject customfield = (JsonObject) currentissues.get("fields").getAsJsonObject().get("customfield_29805");
    JsonArray completedCyclesArray = customfield.getAsJsonArray("completedCycles");
    String Issue_FirstResponseStartTime = (completedCyclesArray.size() > 0) ? completedCyclesArray.toString() : "NULL";
    System.out.println(String.format("Issue_Id %s , Issue_Key %s, Issue_Type %s, Issue_FirstResponseStartTime %s", Issue_Id, Issue_Key, Issue_Type, Issue_FirstResponseStartTime));
});

这是我得到的输出:

expand "schema,names" , startAt 0, maxResults 50, total 37875 Issue_Id 1190,Issue_Key GDS-81,Issue_Type 带有批准的服务请求, Issue_FirstResponseStartTime NULL

请在此处查看我的完整工作代码complete code

两种情况

空的已完成循环

{
    "expand": "schema,names",
    "startAt": 0,
    "maxResults": 50,
    "total": 37875,
     "issues": [
            {
                "id": "1190",
                "key": "GDS-81",
                "fields": {
                    "issuetype": {
                        "id": "2170",
                        "name": "Service Request with Approvals",
                        "subtask": false
                    },
                    "customfield_29805": {
                        "id": "26",
                        "name": "Issue - First Response",
                        "completedCycles": []
                    }
                }
            }
        ]
     }

非空已完成循环

{
"expand": "schema,names",
"startAt": 0,
"maxResults": 50,
"total": 37875,
 "issues": [
        {
            "id": "1190",
            "key": "GDS-81",
            "fields": {
                "issuetype": {
                    "id": "2170",
                    "name": "Service Request with Approvals",
                    "subtask": false
                },
                "customfield_29805": {
                    "id": "26",
                    "name": "Issue - First Response",
                      "completedCycles": [{"name":"abc"},{"name": "xyz"}]
                }
            }
        }
    ]
 }

【讨论】:

  • 谢谢,但是我得到的 JSON 响应不仅仅是一个 JSONArray 块,它在开头也有一些参数(startAt、maxResults 等),我在帖子中更新了这些参数,因此代码失败错误 java.lang.IllegalStateException: 这不是 JSON 数组。
  • 它仍然在语句 IntStream.range(0, issuesArray.size()).mapToObj(i -> (JsonObject) issuesArray.get(i)).forEach(currentissues -> { 上失败堆栈跟踪检查i.stack.imgur.com/2wY0S.jpg
  • fixed ,而不是使用 completedCyclesArray.getAsString() 我们应该使用 completedCyclesArray.toString() ,请重新测试
  • 我更新了代码,但仍然失败并出现同样的错误:java.lang.ClassCastException: com.google.gson.JsonNull 无法转换为 com.google.gson.JsonObject 和相同的堆栈跟踪。 :(
  • 你能把请求的json发给我吗?代码也完整,因为它在我的机器上完美运行
【解决方案2】:

尝试在该语句的末尾添加 getAsJsonObject()。

【讨论】:

  • 我在该语句的末尾添加了 getAsJsonObject() (JsonObject customfield),但它失败并出现错误 java.lang.IllegalStateException: Not a JSON Object: null
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
  • 2014-02-26
相关资源
最近更新 更多