Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert JSON objects to POJO from Gson

Tags:

java

json

I am trying to convert JSON objects to POJO's with GSON.

JSON String

[
  {
    "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
    }
  }
]

The AutomationProjectsList class used with GSON

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
            + "]";
}}

Automation Project 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;
    }}

The code I'm using

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());
        }
    }

But it gives an exception :

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)

Why am I receiving an IndexOutOfBoundsException exception? Where am I wrong?

like image 801
ricardoramos Avatar asked Jun 26 '15 12:06

ricardoramos


People also ask

How do I change from JSON to pojo?

Converting Java object to JSON In it, create an object of the POJO class, set required values to it using the setter methods. Instantiate the ObjectMapper class. Invoke the writeValueAsString() method by passing the above created POJO object. Retrieve and print the obtained JSON.

How is the JSON object converted to Java object?

A Gson is a json library for java, which is created by Google and it can be used to generate a JSON. By using Gson, we can generate JSON and convert JSON to java objects. We can call the fromJson() method of Gson class to convert a JSON object to Java Object.


2 Answers

Your class or your JSON are incorrect. I'd suggest your JSON is. A JSON matching your POJO class would be:

{
  "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
    }
  ]
}

Notice I used the name automationProjects for the list as it makes more sense, so your class would be:

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
        + "]";
    }
}

And finally to convert JSON to AutomationProjectsList object:

AutomationProjectsList projectsList = new Gson().fromJson(jsonArray.toString(), AutomationProjectsList.class);

Then if you want to log each project:

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

In conclusion, your code seems to have the fallowing issues:

  1. Do you have a list of lists or just a single list of projects? If the list is just one, why do you iterate jsonArray like its sub-objects are lists themselves?

  2. If you model your class correctly on the JSON then you don't need to iterate the JSON to obtain your objects

  3. The JSON you posted is quite weird and uneasy to use with Gson, is it a requirement or can you edit it as you please?

Hope this helps

EDIT

Since you stated you cannot change the JSON you get, then it gets a little more complex, but everything is up to modelling the classes on the JSON format. So let's start form this 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
        }
    }
]

Now, this is quite nasty, but let's see what we have here: we have an unnamed array of objects with a single attribute "automationProject" which is our actual AutomationProject Object. So in terms of structure, it is a list of objects which wrap an actual AutomationProject.

Thus you'll need to get rid of your AutomationProjectList and change it with the more meaningful AutomationProjectWrapper looking as fallows:

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
        + "]";
    }
}

See this class is equivalent to the 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
    }
}

Finally you'll have an array of such wrapper objects as your jsonArray so you can write:

AutomationProjectWrapper[] projectsList = new Gson().fromJson(jsonArray.toString(), AutomationProjectWrapper[].class);

Then to log your objects:

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

EDIT 2

Sorry for the mistake, in AutomationProjectWrapper class the AutomationProject field should be named automation_project. Fixed in code above.

like image 182
Carlo Moretti Avatar answered Sep 28 '22 14:09

Carlo Moretti


According to your JSON String the value you are trying to access is :

jsonString[i].automation_project.user_id

In your code you have: obj.getAutomationProject().get(0).getId()

I think is should be: obj[i].getAutomationProject().getId()

like image 37
Panagiotis Stoupos Avatar answered Sep 28 '22 15:09

Panagiotis Stoupos