Reputation: 2242
I am writing an Android
app, and using RetroFit
to communicate with the REST API. I have all the classes/POJO's written, except one.
Here is the Java for the specific class.
This is the parent class, which is the root of the problem. I need to be able to map the userNameResponse
variable to the users name in the JSON
below
public class DiTopicStats {
private UserNameResponse userNameResponse;
public UserNameResponse getUserNameResponse() {
return userNameResponse;
}
public void setUserNameResponse(UserNameResponse userNameResponse) {
this.userNameResponse = userNameResponse;
}
}
and the child class, which should be fine as long as I can map to it from the above parent class:
public class UserNameResponse {
//Fields
//Getters and Setters
}
The JSON that is returned contains a field which changes per response. The field is the users name. For example:
{
"sMessage": "",
"diStatus": {
"diTopicWrongAns": {
//Some fields
},
"diOverallStats": {
//Some more fields
},
"diUserStats": {
"John Smith": { //PROBLEM: This name changes
//some other fields
}
}
}
}
So in this case, the name "John Smith" has a dynamic field name. Realistically, it could be any string with letters, numbers, a -
or a .
in it.
My question is, using RetroFit, how can I create a Java class that lets RetroFit map a field to a variable?
I'm aware you can specify a SerialisedName
but can this be done programatically at runtime, because I will have the name
or the user at this stage.
Thanks.
Upvotes: 2
Views: 1249
Reputation: 1019
Create a pojo called DiUserStats and then define a custom GsonTypeAdapter e.g.
public class DiUserStatsTypeAdapter implements JsonDeserializer<DiUserStats>, JsonSerializer<DiUserStats> {
@Override
public DiUserStats deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
DiUserStats target = new DiUserStats();
JsonObject jsonObject = json.getAsJsonObject();
Map.Entry<String,JsonElement> object =(Map.Entry<String,JsonElement>)jsonObject.entrySet().toArray()[0];
target.setName(object.getKey());
JsonObject targetValues = object.getValue().getAsJsonObject();
/*parse values to your DiUserStats as documented using targetValues.get("fooProperty").getAsString(), etc */
return target;
}
@Override
public JsonElement serialize(DiUserStats src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject obj = new JsonObject();
JsonObject values = new JsonObject();
values.addProperty("foo", src.getFoo);
obj.addProperty(target.getName(), values);
return obj;
}
}
Then when you setup Gson use a builder and add your custom type adapter e.g.
Gson gson = new GsonBuilder().registerTypeAdapter(DiUserStats.class, new DiUserStatsTypeAdapter()).create();
Upvotes: 2