0

I have a particular situation where I am retrieving a list of Objects which have unique Ids as their keys, and they also have nested objects which also have their own unique ids.

I am using GSON to create pojos but when creating model classes for these objects I would need to serialize all unique key values, this is not a good solution.

I have attached an image to give you a better idea of what I am talking about:

enter image description here

I want GSON to create a list of NestedObject1 which will it self contain a list of NestedObject2. The problem is that the key value is unique for each type of NestedObject

I was thinking of doing something like so:

Objects.java

public class Objects {

    @SerializedName("Objects")
    private List<NestedObject1> mNestedObjects1;
    public List<NestedObject1> getNestedObjects1() {
        return mNestedObjects1;
    }

}

NestedObjects1.java

public class NestedObject1 {

    @SerializedName("WHAT-TO-PUT-HERE?")
    private String mId;
    public String getId() {
        return mId;
    }

    @SerializedName("WHAT-TO-PUT-HERE?")
    private List<NestedObject2> mNestedObjects2;
    public List<NestedObject2> getNestedObjects2() {
        return mNestedObjects2;
    }

}

NestedObject2

public class NestedObject2 {

    // Same deal here?

}

Any suggestions on how to tackle this?

EDIT: Sample JSON OUTPUT

"Objects" : {
"-JrEvneZHQV73jxKu0-U" : {
  "-JrEvoBeZaysRRttNGP-" : {
    "started" : true
  },
  "-JrEvqaNyTHhjRIMGR-r" : {
    "started" : true
  }
},
"-JrF0_yWy_NmrMROB3qp" : {
  "-JrF0lWRsa5KmU6SnC7Z" : {
    "started" : true
  },
  "-JrF1txLoFd2w4wN8Q4n" : {
    "started" : true
  },
  "-JrF2skHdMmT9WN3wKVS" : {
    "started" : true
  }
},
"-JrF3XSkpvo2WMzF1osb" : {
  "-JrF3ZYwyxUz0RDooVna" : {
    "started" : true
  },
  "-JrF4D-cesLhqbbzdfT1" : {
    "started" : true
  },
  "-JrF5GufdDqFGjw8aYRB" : {
    "started" : true
  }
},
}
AndyRoid
  • 5,062
  • 8
  • 38
  • 73

1 Answers1

1

As the names are not the same, you can't use an neither an annotation or have a field with the same name in your Java class.

What I would suggest is to implement a custom deserializer so that you shouldn't have to care about these key-values.

Assuming proper constructors here's how you could implement a deserializer for the Objects class (by the way it's a very bad name as there is already a class named Objects in the JDK).

class ObjectsDeserializer implements JsonDeserializer<Objects> {
    @Override
    public Objects deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObject = json.getAsJsonObject().getAsJsonObject("Objects");
        List<NestedObject1> list = new ArrayList<>();
        for(Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
            List<NestedObject2> nestedObject2List = new ArrayList<>();
            //here deserialize each NestedObject2 and put it in the list
            list.add(new NestedObject1(entry.getKey(), nestedObject2List));
        }
        return new Objects(list);
    }
}

Then you register your deserializers in the Gson parser:

Gson gson = new GsonBuilder()
    .registerTypeAdapter(Objects.class, new ObjectsDeserializer())
    .registerTypeAdapter(NestedObject2.class, new NestedObject2Deserializer())
    .create();

Objects o = gson.fromJson(new FileReader(new File("file.json")), Objects.class);

which outputs:

Objects{mNestedObjects1=
    NestedObject1{mId='-JrEvneZHQV73jxKu0-U', mNestedObjects2=[]}
    NestedObject1{mId='-JrF0_yWy_NmrMROB3qp', mNestedObjects2=[]}
    NestedObject1{mId='-JrF3XSkpvo2WMzF1osb', mNestedObjects2=[]}
}

You'd need to define a custom deserializer for the NestedObject2 class, here I just fill it with an empty list, but I guess you will be able to do it as it's the same principle.

Hope it helps! :-)

Alexis C.
  • 91,686
  • 21
  • 171
  • 177