public class EmptyStringSerializer implements JsonSerializer<String> {
@Override
public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
if (src == null || src.isEmpty())
return JsonNull.INSTANCE;
return new JsonPrimitive(src);
}
}
然后将其作为 TypeAdapter 使用:
Gson gson = new GsonBuilder()
.registerTypeAdapter(String.class, new EmptyStringSerializer())
.create();
3条答案
按热度按时间dauxcl2d1#
有点。据我所知,Gson不允许你控制太多的对象字段,而唯一的控制我知道你可以有它
@JsonAdapter
。例如,尽管对某些人来说这看起来很乏味,但它让你完全控制你的数据传输对象,让你选择如何处理这个或那个字符串。示例类型适配器如下:
这里需要注意的是,它不能从空值恢复空字符串(不幸的是,您在这里遇到了不可逆的转换),所以您可能还想看看https://github.com/google/gson/blob/master/extras/src/main/java/com/google/gson/typeadapters/PostConstructAdapterFactory.java,以便在读取时恢复
@JsonAdapter(EmptyStringTypeAdapter.class)
注解的字段。示例测试:输出量:
前 Package :
JSON格式:{}
在以下时间后打包:null null -- [!]不是“”'”
前 Package :喷火
JSON:{“foo”:“foo”}
在以下之后打包:foo null -- [!]不是foo“”
前 Package :棒
JSON:{“bar”:“bar”}
在以下之后打包:空栏-- [!]不是“”栏
前 Package :脚踏杆
JSON:{“foo”:“foo”,“bar”:“bar”}
Package 后:foo bar
[,喷,巴]
["",“foo”,“bar”]
[,喷,巴]
然而,我不认为编写复杂的(反)序列化策略是一个好的选择,您可能对重新设计DTO和数据(反)序列化感兴趣。此外,
""
是 * 一个值 *,而null
不是--我永远不会混合它们,我会修改为什么您的系统是这样设计的(它看起来确实像一个空/空值混合问题)。e37o9pze2#
感谢@Lyubomyr的回答,但我发现了一个更适合我们用例的解决方案:
如果我们将所有空字符串和对象设置为null,那么序列化后剩下的JSON只包含具有实际数据的节点:
如果你有很多空字段,这可以在序列化和发送/写入数据库时节省时间(和空间)。
zyfwsgd63#
由于您希望在序列化过程中省略空字符串,因此只能实现 JsonSerializer,而不能实现完整的 TypeAdapter。
然后将其作为 TypeAdapter 使用:
(This方法依赖于从序列化中省略空值。)