Reputation: 443
I am working with a class hierarchy in which one of the classes defines a group of instances
public class Base {
String id;
String name;
String type;
}
public class Group<T extends Base> extends Base {
Collection<T> elements;
}
there are many other types that derive from the base class and can be added to the group. Each type has it's own properties
Gson default serialization works great for non-group objects, but for Group objects I need the collection elements to be serialized with ONLY the Base class properties and exclude all the other properties.
Questions:
Edit:
@Paul. I think your suggestion would not work in my case. I oversimplified the model.
Here is a more elaborate description of the model.
public interface Node {
BaseObject getAsBaseObject();
}
public class Base {
String id;
String name;
String type;
}
public class BaseObject extends Base implements Node {
String description;
@Override
public BaseObject getAsBaseObject() {
return this;
}
}
public class Group<T extends Node> extends BaseObject {
Collection<BaseObject> elements;
void addElement(T element) {
elements.add(element.getAsBaseObject());
}
}
The Node interface is used as a base for composite nodes. Consider Foo and groups of Foo's...
public interface FooBase extends Node {
}
public class Foo extends BaseObject implements FooBase {
String prop1;
}
public class FooGroup extends Group<FooBase> implements FooBase{
}
So lets say I have a FooGroup containing some Foo's and Foo groups. I need the serialized object to look something like this:
{
"id": "",
"type": "",
"name": "",
"description": " ",
"objects": [
{
"type": "",
"name": "",
"id": ""
},
{
"type": "",
"name": "",
"id": ""
},
{
"type": "",
"name": "",
"id": ""
},
{
"type": "",
"name": "",
"id": ""
}
]
}
I think the @Expose wont work here cause the description field would also be exposed in the objects collection
I was able to do it by registering a custom JsonSerializer but is it the right/simplest approach?
if this is the way to go, is there a way to register only one serializer to handle all the Group class derivatives?
Upvotes: 1
Views: 693
Reputation: 2031
Gson has an @Expose annotation specifically made for this. First, mark the fields of your base class as exposed:
public class Base {
@Expose
String id;
@Expose
String name;
@Expose
String type;
}
Then, when creating your Gson object, make it ignore fields you haven't exposed:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Don't forget to also expose the elements
array:
public class Group<T extends Base> extends Base {
@Expose
Collection<T> elements;
}
Serialization will work as expected now. To test this, let's create a small helper class which extends Base
:
public class BaseExtension extends Base {
private String notExposed;
public BaseExtension(String notExposed) {
this.notExposed = notExposed;
}
}
Now, lets create a Group
of BaseExtension
s (using Guava for clarity):
BaseExtension b1 = new BaseExtension("BaseExt1");
BaseExtension b2 = new BaseExtension("BaseExt2");
BaseExtension b3 = new BaseExtension("BaseExt3");
Group group = new Group<>(Lists.newArrayList(b1, b2, b3));
If we serialize this we get three elements without the notExposed
property - in fact, the elements will be completely empty, as id
, name
and type
do not have values yet:
System.out.println(gson.toJson(group));
// Produces { "elements" : [ {}, {}, {} ] }
Add values to your Base
class to see some more useful output.
Upvotes: 1