如何使用Gson将JSON对象转换为POJO

10
我尝试使用GSON将JSON对象转换为POJO。
JSON字符串
[
  {
    "automation_project": {
      "user_id": null,
      "name": "Untitled Project",
      "updated_at": "2015-06-16T19:39:42Z",
      "group_id": 764496,
      "created_at": "2014-11-23T01:01:59Z",
      "id": 16214
    }
  },
  {
    "automation_project": {
      "user_id": null,
      "name": "newintropage",
      "updated_at": "2015-06-16T21:20:47Z",
      "group_id": 764496,
      "created_at": "2015-06-16T20:39:04Z",
      "id": 29501
    }
  }
]

与GSON一起使用的AutomationProjectsList类

public class AutomationProjectsList {

private List<AutomationProject> automationProject = new ArrayList<AutomationProject>();

public List<AutomationProject> getAutomationProject() {
    return automationProject;
}

public void setAutomationProject(List<AutomationProject> automationProject) {
    this.automationProject = automationProject;
}

@Override
public String toString() {
    return "AutomationProjectsList [automationProject=" + automationProject
            + "]";
}}

自动化项目POJO

 public class AutomationProject {

    private Object userId;   
    private Integer groupId;    
    private Integer id;    
    private String name;   
    private String updatedAt;   
    private String createdAt;

    public Object getUserId() {
        return userId;
    }

    public void setUserId(Object userId) {
        this.userId = userId;
    }

    public Integer getGroupId() {
        return groupId;
    }

    public void setGroupId(Integer groupId) {
        this.groupId = groupId;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(String updatedAt) {
        this.updatedAt = updatedAt;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(String createdAt) {
        this.createdAt = createdAt;
    }}

我正在使用的代码

JSONArray jsonArray = new JSONArray(response.getEntity(String.class));

    for(int i = 0; i < jsonArray.length(); i++){
        if(jsonArray.get(i) instanceof JSONObject){
            JSONObject jsnObj = (JSONObject)jsonArray.get(i);               
            AutomationProjectsList obj = new Gson().fromJson(jsnObj.toString(), AutomationProjectsList.class);                  
            System.out.println(obj.getAutomationProject().get(0).getId());
        }
    }

但它会产生一个异常:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at br.usp.icmc.teste.ConnectionRestClient.getBrowserStackProjects(ConnectionRestClient.java:74)
at br.usp.icmc.teste.TestePrincipal.main(TestePrincipal.java:9)

为什么我收到了IndexOutOfBoundsException异常?我错在哪里了?

2个回答

6

你的类或JSON可能存在错误。我建议检查一下你的JSON格式。

与POJO类相匹配的JSON应该是:

{
  "automationProjects":[
    {
      "user_id": null,
      "name": "Untitled Project",
      "updated_at": "2015-06-16T19:39:42Z",
      "group_id": 764496,
      "created_at": "2014-11-23T01:01:59Z",
      "id": 16214
    },
    {
      "user_id": null,
      "name": "newintropage",
      "updated_at": "2015-06-16T21:20:47Z",
      "group_id": 764496,
      "created_at": "2015-06-16T20:39:04Z",
      "id": 29501
    }
  ]
}

请注意,我在列表中使用了 automationProjects 的名称,因为这更有意义,所以你的类将是:

public class AutomationProjectsList {

    private List<AutomationProject> automationProjects = new ArrayList<AutomationProject>();

    public List<AutomationProject> getAutomationProjects() {
        return automationProjects;
    }

    public void setAutomationProjects(List<AutomationProject> automationProjects) {
        this.automationProjects = automationProjects;
    }

    @Override
    public String toString() {
        return "AutomationProjectsList [automationProject=" + automationProject
        + "]";
    }
}

最后,将JSON转换为AutomationProjectsList对象的方法如下:
AutomationProjectsList projectsList = new Gson().fromJson(jsonArray.toString(), AutomationProjectsList.class);

如果您想记录每个项目:

for(AutomationProject project : projectsList.automationProjects){
  System.out.println(porject.getId());
}

结论:

你的代码似乎存在以下问题:

  1. 你是否有一个项目列表或只有一个项目列表?如果列表只是一个,为什么要像子对象是列表一样迭代jsonArray

  2. 如果您在JSON上正确建模类,则不需要迭代JSON以获取对象

  3. 您发布的JSON相当奇怪且难以使用Gson,请问这是要求还是可以任意编辑?

希望这可以帮到你。

编辑

由于您表示无法更改收到的JSON,因此变得更加复杂了,但一切都取决于按照JSON格式对类进行建模。 所以我们从这个JSON开始:

[
    {
        "automation_project": {
            "user_id": null,
            "name": "Untitled Project",
            "updated_at": "2015-06-16T19:39:42Z",
            "group_id": 764496,
            "created_at": "2014-11-23T01:01:59Z",
            "id": 16214
        }
    },
    {
        "automation_project": {
            "user_id": null,
            "name": "newintropage",
            "updated_at": "2015-06-16T21:20:47Z",
            "group_id": 764496,
            "created_at": "2015-06-16T20:39:04Z",
            "id": 29501
        }
    }
]

现在,这很麻烦,但让我们看看我们有什么:我们有一个未命名的对象数组,其中包含一个单一属性“automationProject”,这是我们实际的AutomationProject对象。因此,在结构上,它是一个包装实际AutomationProject的对象列表。
因此,您需要摆脱AutomationProjectList,并将其更改为更有意义的AutomationProjectWrapper,如下所示:
public class AutomationProjectsWrapper {

    private AutomationProject automation_project = new AutomationProject();

    public AutomationProject getAutomationProject() {
        return automation_project;
    }

    public void setAutomationProject(AutomationProject automationProject) {
        this.automation_project = automationProject;
    }

    @Override
    public String toString() {
        return "AutomationProjectsList [automationProject=" + automation_project
        + "]";
    }
}

请看这个类,它相当于JSON对象:

{
    "automation_project": {
        "user_id": null,
        "name": "Untitled Project",
        "updated_at": "2015-06-16T19:39:42Z",
        "group_id": 764496,
        "created_at": "2014-11-23T01:01:59Z",
        "id": 16214
    }
}

最后您将拥有一个这样的包装对象数组,作为您的jsonArray,因此您可以编写以下内容:
AutomationProjectWrapper[] projectsList = new Gson().fromJson(jsonArray.toString(), AutomationProjectWrapper[].class);

然后记录你的对象:

for(AutomationProjectWrapper wrapper : projectsList){
    System.out.println(wrapper.getAutomationProject().getId());
}

编辑2

对于错误我感到抱歉,在AutomationProjectWrapper类中,AutomationProject字段应该被命名为automation_project。 已在上面的代码中进行修正。


1
你好Onheiron,感谢你的帮助,但我通过服务获取到这个JSON并且无法更改它,我只需要调整我的POJO来消费JSON。我从未使用过JSON,我想知道有什么建议可以让我使用JSON的形式来简化我的工作。我选择了Gson,因为我认为这是将JSON转换为POJO和POJO转换为JSON最实用的方法。 - ricardoramos
你按照我的建议编辑了这个类吗?getAutomationProject现在返回一个AutomationProject对象。不再存在AutomationProject对象的列表。 - Carlo Moretti
啊抱歉,是我不好!我有一个命名问题:在包装器中,对象应该与JSON对象标签完全相同,因此它应该是automation_project而不是automationProject...我立即修复它! - Carlo Moretti
1
非常感谢 Onheiron 的帮助,现在一切正常! - ricardoramos

1
根据您的JSON字符串,您正在尝试访问的值是:
jsonString[i].automation_project.user_id

在你的代码中,你有:obj.getAutomationProject().get(0).getId() 我认为应该是:obj[i].getAutomationProject().getId()

返回 null 的方式相同 - ricardoramos
根据Onheiron的建议进行修改,如你所说,仍然返回null。测试建议使用projectsList[i].getAutomationProject().getId()) - ricardoramos
感谢DonCorleone的解释,它完美地起作用了。 - ricardoramos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接