【问题标题】:Java GSON Failed parsing to object arrayJava GSON 无法解析到对象数组
【发布时间】:2021-01-26 21:31:37
【问题描述】:

我有问题。我正在做一个网络电话,我在屏幕上打印一个 json,如下所示:

{"Agents":[{"Id":"1","Owner":"Andre"},{"Id":"7","Owner":"Andre2"},{"Id":"8","Owner":"Andre"},{"Id":"9","Owner":"Alexander"},{"Id":"10","Owner":"Alexander"},{"Id":"12","Owner":"Andre"}]}

然后我使用下面的代码从网上获取json并解析成一个数组对象:

EfyWebAPI webAPI = new EfyWebAPI();
String jsonResponse = webAPI.executeQuery("www.mysite.org/test.php", "SELECT Id, Owner FROM Agents");

Gson gson = new Gson();
Agent[] agents = gson.fromJson(jsonResponse, Agent[].class);

System.out.println(agents[0].getId());

类如下所示:

public class Agent {

    private int id;
    private String owner;

    public Agent(int id, String owner) {
        this.id = id;
        this.owner = owner;
    }

    public int getId() {
        return this.id;
    }

}

但是当我运行代码时,我得到以下错误:

线程“主”com.google.gson.JsonSyntaxException 中的异常: java.lang.IllegalStateException:应为 BEGIN_ARRAY 但为 STRING 在第 1 行第 1 列路径 $ 在 com.google.gson.Gson.fromJson(Gson.java:822) 在 com.google.gson.Gson.fromJson(Gson.java:775) 在 com.google.gson.Gson.fromJson(Gson.java:724) 在 com.google.gson.Gson.fromJson(Gson.java:696) 在 com.company.Main.main(Main.java:18) 原因: java.lang.IllegalStateException:应为 BEGIN_ARRAY 但为 STRING 在第 1 行第 1 列路径 $ 在 com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350) 在 com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:70) 在 com.google.gson.Gson.fromJson(Gson.java:810) ... 4 更多

为什么会发生这种情况,我该如何解决?

【问题讨论】:

  • 另外,1) 确保你的服务器响应是一个真正的 JSON 数组; 2)Agent字段名不会映射JSON字段:使用@SerializedName映射idId
  • 你有一个大小写问题(类有小写成员,JSON 有大写)。我没有看到com.google.gson.JsonSyntaxException,所以我怀疑代码得到的字符串与您在问题中发布的字符串不同。
  • 此错误 Expected ... but was STRING 通常发生在响应不是 JSON 文档,而是来自服务器。我强烈建议 OP 仔细检查实际响应并检查它是否完全是 JSON(将响应打印到 stdout 比在此处发布问题要容易得多)。例如,这段代码也会产生相同的错误:gson.fromJson("Error!", Agent[].class)
  • 用多个对象解析 JSON 仍然没有运气!?有什么建议吗?

标签: java json gson


【解决方案1】:

错误是说

预计 BEGIN_ARRAY...

由于第二个参数 (Agent[].class),它需要一个有效的 json 数组字符串 Agent-s。 您的 json 字符串是一个带有键 Agents 的对象,其值是 Agents 的数组。

一种可能的解决方案是,例如创建一个名为 Agents 的类,它代表 json 对象。

public class Agents {
    private Agent[] Agents; // note the capital 'A' matches the key name in the json string

    public Agent[] getAgents() {
        return Agents;
    }

    public void setAgents(Agent[] agents) {
        this.Agents = agents;
    }
}

并调整Agent类如下:

public class Agent {
    @SerializedName("Id") // note the annotated field is needed since in the json string id is Id
    private int id;

    @SerializedName("Owner") // same as id field, annotation needed, or rename owner to Owner
    private String owner;

    public Agent(int id, String owner) {
        this.id = id;
        this.owner = owner;
    }

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setOwner(String owner) {
        this.owner = owner;
    }

    @Override
    public String toString() {
        return "Agent{" +
                "id=" + id +
                ", owner='" + owner + '\'' +
                '}';
    }
}

这是一个工作演示:

public class GsonDemo {
    public static void main(String[] args) {
        String json = "{\"Agents\":[{\"Id\":\"1\",\"Owner\":\"Andre\"},{\"Id\":\"7\",\"Owner\":\"Andre2\"},{\"Id\":\"8\",\"Owner\":\"Andre\"},{\"Id\":\"9\",\"Owner\":\"Alexander\"},{\"Id\":\"10\",\"Owner\":\"Alexander\"},{\"Id\":\"12\",\"Owner\":\"Andre\"}]}";
        Gson gson = new Gson();
        Agents a = gson.fromJson(json, Agents.class);
        System.out.println(a.getAgents()[1]);
        System.out.println(a.getAgents().length);
        // Output:
        // Agent{id=7, owner='Andre2'}
        // 6
    }
}

【讨论】:

    【解决方案2】:

    它的工作原理有点...而不是得到 id=1,它得到 id=0。我认为它从 json 中获取对象计数的 id。这是如何工作的,为什么我不能一次解析多个对象并将其返回到数组列表或其他东西中?

    JSON(或至少是 GSON)总是需要一个字符串作为键(据我所知)。 String 后面的内容无关紧要,只要符合 JSON 标准即可。

    如果您声明类似的内容,您提到的内容是可能的

    {"persons" : [ + 你的其他内容 + ]},但我不确定你是否可以自动将其解析为 List<Agent>

    【讨论】:

    • 我在我的问题中再次更新了我的 JSON,就像你一样,但这也不起作用!?又是Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ 错误?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 2015-10-05
    相关资源
    最近更新 更多