Reputation: 22173
I'm using a library with a class to map a json message and I'm using Gson to serialized the classes over json. The message contains a data field. The field is generic and it contains anything. The class provided by the library is:
public class Api {
....
@SerializedName("data")
Map<String, JsonElement> data;
....
}
Now I'd like to extend the class but I have my own root object to map the data sub field, so to do a summary the json is something like:
{...., "data": {"myownroot":"aaaa"}}
How can I do? I could create my own classes of course but I would prefer to extend the library if possible. If I extend the class I would have:
public class MyOwnRoot extends Api {
@SerializedName("myownroot")
public String root;
}
but in this case when I serialize it doesn't work because myownroot must be a child of data but how can I say to Gson "put MyOwnRoot in the data map"??
Upvotes: 0
Views: 357
Reputation: 2786
I can't really understand why you would need to extend the Api class. I guess the class name is a bit of a misnomer, since API are (generally speaking) interfaces, and they get implemented.
I guess you could do this by using getters to your advantages, while letting Gson do its work on fields.
public class Api {
@SerializedName("data")
protected Map<String, JsonElement> data;
}
public class RootEntity extends Api {
transient StructuredRootImpl _cached;
transient Gson _gson = new Gson();
public class StructuredRootImpl {
Integer v;
String name;
}
public Integer getV() {
synch();
return _cached.v;
}
public void setV(Integer v) {
_cached.v=v;
synch();
}
private void synch() {
if(_cached==null){
if(data==null){
data = new LinkedHashMap<>();
}
JsonElement jsonElement = data.get("myroot");
_cached = _gson.fromJson(jsonElement, StructuredRootImpl.class);
}
JsonElement jsonTree = _gson.toJsonTree(_cached);
data.put("myroot", jsonTree);
}
public String getName() {
synch();
return _cached.name;
}
public void setName(String name) {
_cached.name = name;
synch();
}
@Override
public String toString() {
return "RootEntity [v=" + getV() + ", n=" + getName() + "]";
}
}
Running the main you can both serialize and deserialize your entity.
public class TestGson {
public static void main(String[] args) {
String jsonText = "{data:{\"myroot\":{\"v\":123,\"name\":\"mario\"}}}";
Gson gson = new Gson();
RootEntity entity = gson.fromJson(jsonText, RootEntity.class);
System.out.println(entity);
entity.setName("Alex");
entity.setV(150);
String thenBack = gson.toJson(entity);
System.out.println(thenBack);
}
}
This will result in :
so.alpha.TestGson$Foo@4b85612c
StructuredRoot [v=123, name=mario]
Still I don't understand why you would extend the Api class.
Upvotes: 1