Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse List of JSON objects using GSON

I have a JSON object like this:

{
  "user1": {
    "timeSpent": "20.533333333333335h",
    "worklog": [
      {
        "date": "06/26/2013",
        "issues": [
          {
            "issueCode": "COC-2",
            "comment": "\ncccccc",
            "timeSpent": "20.533333333333335h"
          }
        ],
        "dayTotal": "20.533333333333335h"
      }
    ]
  },
  "admin": {
    "timeSpent": "601.1h",
    "worklog": [
      {
        "date": "06/25/2013",
        "issues": [
          {
            "issueCode": "COC-1",
            "comment": "",
            "timeSpent": "113.1h"
          }
        ],
        "dayTotal": "113.1h"
      },
      {
        "date": "06/26/2013",
        "issues": [
          {
            "issueCode": "COC-1",
            "comment": "",
            "timeSpent": "8h"
          },
          {
            "issueCode": "COC-2",
            "comment": "",
            "timeSpent": "480h"
          }
        ],
        "dayTotal": "488h"
      }
    ]
  }
}

and trying to parse it with Gson:

Gson gson = new Gson();
Book responseBean = gson.fromJson(jsonString, Book.class);

But the 'responceBean' is always 'null'

Here are all the other classes:

public class Book {

    private List<User> user = new LinkedList<User>();

    public List<User> getUser() {
        return user;
    }

    public void setUser(List<User> user) {
        this.user = user;
    }
}

public class User {
    private String timeSpent;
    private List<WorkLog> worklogs = new LinkedList<WorkLog>();;

    public List<WorkLog> getWorklogs() {
        return worklogs;
    }

    public void setWorklogs(List<WorkLog> worklogs) {
        this.worklogs = worklogs;
    }

    public String getTimeSpent() {
        return timeSpent;
    }

    public void setTimeSpent(String timeSpent) {
        this.timeSpent = timeSpent;
    }
}

public class WorkLog{
    private String date;
    private String dayTotal;
    private List<Issues> issues;

    public String getDate(){
        return this.date;
    }
    public void setDate(String date){
        this.date = date;
    }
    public String getDayTotal(){
        return this.dayTotal;
    }
    public void setDayTotal(String dayTotal){
        this.dayTotal = dayTotal;
    }
    public List<Issues> getIssues(){
        return this.issues;
    }
    public void setIssues(List<Issues> issues){
        this.issues = issues;
    }
}

public class Issues{
    private String comment;
    private String issueCode;
    private String timeSpent;

    public String getComment(){
        return this.comment;
    }
    public void setComment(String comment){
        this.comment = comment;
    }
    public String getIssueCode(){
        return this.issueCode;
    }
    public void setIssueCode(String issueCode){
        this.issueCode = issueCode;
    }
    public String getTimeSpent(){
        return this.timeSpent;
    }
    public void setTimeSpent(String timeSpent){
        this.timeSpent = timeSpent;
    }
}

This is my latest attempt. Somehow I cannot figure out the right way. Will be very appreciative for any help.

like image 819
ITisha Avatar asked Dec 27 '22 01:12

ITisha


1 Answers

Your JSON model does not match your object model.

You need an intermediate layer to fill the gap: a TypeAdapter.

Moreover there is no naming information for the user.

And finally there is a name mismatch: "worklog" in JSON, "worklogs" in Java.

Here is a fixed version:

Java model:

class User {
    private String timeSpent;
    @SerializedName("worklog")
    private List<WorkLog> worklogs = new LinkedList<WorkLog>();
    private String name;

    public List<WorkLog> getWorklogs() {
        return worklogs;
    }

    public void setWorklog(List<WorkLog> worklogs) {
        this.worklogs = worklogs;
    }

    public String getTimeSpent() {
        return timeSpent;
    }

    public void setTimeSpent(String timeSpent) {
        this.timeSpent = timeSpent;
    }

    public String getName() {
        return name;
    }

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

The plumbing to fill the gap:

class BookTypeAdapter implements JsonSerializer<Book>, JsonDeserializer<Book>
{
      Gson gson = new Gson();

      public JsonElement serialize(Book book, Type typeOfT, JsonSerializationContext context)
      {
          JsonObject json = new JsonObject();

          for (User user : book.getUser())
          {
              json.addProperty(user.getName(), gson.toJson(user));
          }

          return json;
      }

      public Book deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
      {
          JsonObject json = element.getAsJsonObject();

          Book book = new Book();

          for (Entry<String, JsonElement> entry : json.entrySet())
          {
              String name = entry.getKey();
              User user = gson.fromJson(entry.getValue(), User.class);
              user.setName(name);

              book.getUser().add(user); 
          }

          return book;
      }
}

And a roundtrip:

GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Book.class, new BookTypeAdapter());

Gson gson = builder.create();

Book book = gson.fromJson("{" +
        " \"user1\": {" +
        "   \"timeSpent\": \"20.533333333333335h\"," +
        "   \"worklog\": [" +
        "     {" +
        "       \"date\": \"06/26/2013\"," +
        "       \"issues\": [" +
        "         {" +
        "           \"issueCode\": \"COC-2\"," +
        "           \"comment\": \"\ncccccc\"," +
        "           \"timeSpent\": \"20.533333333333335h\"" +
        "         }" +
        "       ]," +
        "       \"dayTotal\": \"20.533333333333335h\"" +
        "     }" +
        "   ]" +
        " }," +
        " \"admin\": {" +
        "   \"timeSpent\": \"601.1h\"," +
        "   \"worklog\": [" +
        "     {" +
        "       \"date\": \"06/25/2013\"," +
        "       \"issues\": [" +
        "         {" +
        "           \"issueCode\": \"COC-1\"," +
        "           \"comment\": \"\"," +
        "           \"timeSpent\": \"113.1h\"" +
        "         }" +
        "       ]," +
        "       \"dayTotal\": \"113.1h\"" +
        "     }," +
        "     {" +
        "       \"date\": \"06/26/2013\"," +
        "       \"issues\": [" +
        "         {" +
        "           \"issueCode\": \"COC-1\"," +
        "           \"comment\": \"\"," +
        "           \"timeSpent\": \"8h\"" +
        "         }," +
        "         {" +
        "           \"issueCode\": \"COC-2\"," +
        "           \"comment\": \"\"," +
        "           \"timeSpent\": \"480h\"" +
        "         }" +
        "       ]," +
        "       \"dayTotal\": \"488h\"" +
        "     }" +
        "   ]" +
        " }" +
        "}", Book.class);

String json = gson.toJson(book);

Have a look at my tutorial to get an idea of what is possible with Gson: Java/JSON mapping with Gson

Enjoy! :)

like image 122
Pragmateek Avatar answered Jan 13 '23 06:01

Pragmateek