我想序列化特定字段或类的空值。
在GSON中,serializeNulls()
选项适用于整个JSON。
示例:
class MainClass {
public String id;
public String name;
public Test test;
}
class Test {
public String name;
public String value;
}
MainClass mainClass = new MainClass();
mainClass.id = "101"
// mainClass has no name.
Test test = new Test();
test.name = "testName";
test.value = null;
mainClass.test = test;
使用GSON创建JSON:
GsonBuilder builder = new GsonBuilder().serializeNulls();
Gson gson = builder.create();
System.out.println(gson.toJson(mainClass));
电流输出:
{
"id": "101",
"name": null,
"test": {
"name": "testName",
"value": null
}
}
所需输出:
{
"id": "101",
"test": {
"name": "testName",
"value": null
}
}
如何达到预期的产出?
优选的解决方案将具有以下性质:
- 默认情况下,* 不要 * 序列化空值,
- 序列化具有特定注解的字段的空值。
6条答案
按热度按时间drnojrws1#
我有一个类似于Aleksey的解决方案,但它可以应用于任何类中的一个或多个字段(Kotlin中的示例):
为应序列化为null的字段创建新注解:
创建一个
TypeAdapterFactory
,它检查类是否具有使用此注解进行注解的字段,并在写入对象时从JsonTree
中删除null
字段和未使用注解进行注解的字段:将适配器注册到Gson示例:
并注解您希望可为空的字段:
序列化结果:
杰森:
sg2wtvxw2#
我有接口来检查对象何时应该序列化为null:
和相应的TypeAdapter(只支持写)
使用方法如下:
在Foo值应序列化为null的类中。请注意,foo值本身不能为null,否则将忽略自定义适配器注解。
5f0d552i3#
对于那些寻找@Joris的优秀答案的Java版本的人来说,下面的代码应该可以做到这一点。它基本上只是Kotlin的翻译,只是对属性的序列化名称的获取方式做了一点改进,以确保当序列化名称与属性名称不同时,它总是能工作(请参见对原始答案的评论)。
这是
TypeAdapterFactory
实现:下面是标记目标属性的
@JsonNullable
注解:我将其实现为对象类上的
@JsonAdapter(NullableAdapterFactory.class)
注解,而不是将其注册为GsonBuilder
示例上的TypeAdapterFactory
,因此我的对象类看起来有点像这样:但是,如果愿意的话,其他方法应该也可以与此代码一起使用。
fslejnso4#
创建
com.google.gson.TypeAdapter
的子类,并使用注解com.google.gson.annotations.JsonAdapter
为必填字段注册它。或者使用GsonBuilder.registerTypeAdapter
注册它。在该适配器中,应实现write
(和read
)。例如:在
MainClass
中,将带有适配器的JsonAdapter
注解添加到Test
类字段:System.out.println(new Gson.toJson(mainClass))
输出是:c0vxltue5#
我从这里的各种答案中得到了一些想法。
该实现:
JsonNullable.isJsonNull() == true
时发生JsonNullable.isJsonNull() == false
时发生Parent
中包含JsonNullable
的发生次数字段为null
TypeAdapterFactory
将未处理的工作正确地委派给delegateAdapter
可能需要序列化为null的对象实现此接口
将值序列化为null的类型适配器工厂
向GSON注册三种类型适配器工厂
序列化为JSON的示例对象
ecfsfe2w6#
再加上@Arvoreniad给出的答案
这两项添加是在将输出设置为true之后重置JsonWriter中的null序列化状态,并使用Gson中的字段命名策略获取字段名。