【问题标题】:How to convert JSON objects to POJO from Gson如何将 JSON 对象从 Gson 转换为 POJO
【发布时间】:2015-09-13 10:24:50
【问题描述】:

我正在尝试使用 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 异常?我哪里错了?

【问题讨论】:

    标签: java json


    【解决方案1】:

    您的课程或 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 Object:

    {
        "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。 在上面的代码中修复。

    【讨论】:

    • 您好 Onheiron,感谢您的帮助,但是我通过服务获取了这个 JSON 并且无法更改它,我只需要调整我的 POJO 以使用 JSON。我从未使用过 JSON,我想知道我使用 JSON 格式的建议是否有助于我的工作。我是 Gson,因为我认为这是将 JSON 转换为 POJO 和 POJO 转换为 JSON 的最实用方法。
    • 您是否按照我的建议编辑了课程? getAutomationProject 现在返回一个 AutomationProject 对象。不再存在 AutomationProject 对象列表。
    • 啊抱歉,我的错!我有一个命名问题:在包装器中,对象应该完全命名为 JSON 对象标签,所以它是自动化项目而不是自动化项目...立即修复它!
    • 非常感谢 Onheiron 的帮助,现在一切正常!
    【解决方案2】:

    根据您的 JSON 字符串,您尝试访问的值是:

    jsonString[i].automation_project.user_id
    

    在您的代码中,您有:obj.getAutomationProject().get(0).getId()

    我认为应该是:obj[i].getAutomationProject().getId()

    【讨论】:

    • 以同样的方式返回 null
    • 按照你告诉我的修改了 Onheiron 的建议,但仍然返回 null。测试建议projectsList[i].getAutomationProject().getId())
    • 感谢 DonCorleone 的解释,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 2015-02-17
    相关资源
    最近更新 更多