我正在使用一个类层次结构,其中一个类定义了一组实例
public class Base {
String id;
String name;
String type;
}
public class Group<T extends Base> extends Base {
Collection<T> elements;
}
还有许多其他类型都派生自基类,并且可以添加到组中。每种类型都有其自己的属性
Gson默认序列化对于非组对象非常有效,但是对于组对象,我只需要使用基类属性对集合元素进行序列化,而排除所有其他属性。
问题:
编辑:
@Paul。我认为您的建议不适用于我的情况。 我简化了模型。
这是对该模型的更详尽的描述。
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());
}
}
Node接口用作复合节点的基础。考虑Foo和Foo的群组...
public interface FooBase extends Node {
}
public class Foo extends BaseObject implements FooBase {
String prop1;
}
public class FooGroup extends Group<FooBase> implements FooBase{
}
所以可以说我有一个包含一些Foo和Foo组的FooGroup。 我需要序列化的对象看起来像这样:
{
"id": "",
"type": "",
"name": "",
"description": " ",
"objects": [
{
"type": "",
"name": "",
"id": ""
},
{
"type": "",
"name": "",
"id": ""
},
{
"type": "",
"name": "",
"id": ""
},
{
"type": "",
"name": "",
"id": ""
}
]
}
我认为@Expose在这里不起作用,因为description字段也将在对象集合中公开
我能够通过注册自定义JsonSerializer来做到这一点 但这是正确/最简单的方法吗?
如果这是可行的方法,是否有办法只注册一个序列化程序来处理所有Group类派生类?
答案 0 :(得分:1)
Gson具有一个为此专门制作的@Expose批注。首先,将基类的字段标记为公开:
public class Base {
@Expose
String id;
@Expose
String name;
@Expose
String type;
}
然后,在创建Gson对象时,使其忽略未公开的字段:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
别忘了还公开elements
数组:
public class Group<T extends Base> extends Base {
@Expose
Collection<T> elements;
}
串行化现在将按预期工作。为了测试这一点,让我们创建一个扩展Base
的小型帮助器类:
public class BaseExtension extends Base {
private String notExposed;
public BaseExtension(String notExposed) {
this.notExposed = notExposed;
}
}
现在,让我们创建Group
个BaseExtension
(为清楚起见,请使用Guava):
BaseExtension b1 = new BaseExtension("BaseExt1");
BaseExtension b2 = new BaseExtension("BaseExt2");
BaseExtension b3 = new BaseExtension("BaseExt3");
Group group = new Group<>(Lists.newArrayList(b1, b2, b3));
如果我们对此序列化,则会得到三个没有notExposed
属性的元素-实际上,这些元素将完全为空,因为id
,name
和type
不会尚有值:
System.out.println(gson.toJson(group));
// Produces { "elements" : [ {}, {}, {} ] }
将值添加到Base
类中,以查看更多有用的输出。