我有大量的json文档和映射到json的适当的jaskson模型。在某些情况下,无法使用所有对象构建所需的json文档,因为某些数据不存在。
例如我有以下模型:
@Scheduled(cron = "${FileConfig.FileEnum.getScheduleTime()}" )
public void scheduleFetchFiles() {
...//method body
}
并且有可能只填充第一个实例:
在通常的情况下,它将被序列化如下:
class First {
private firstField;
private secondField;
etc...
}
class Second {
private firstField;
private secondField;
etc...
}
class General {
private First first;
private Second second;
etc...
}
但我的目标是将General类序列化为:
{
"first":{
"firstField":"some_value",
"secondField":"some_value"
},
"second":null
}
可以通过General类中的以下更改来实现此目的,以便默认使用默认构造函数初始化其成员:
{
"first":{
"firstField":"some_value",
"secondField":"some_value"
},
"second":{
"firstField":"null",
"secondField":"null"
}
}
但是这种方法会对现有模型造成太多变化,我不确定它是最好的方法。是否可以创建一些自定义的自定义序列化程序?
根据https://stackoverflow.com/users/1898563/michael建议编辑:
因此,主要思想是创建能够检查实例是否为null的序列化程序,如果它为null,它应该能够使用默认构造函数创建新实例,注意:此序列化程序不应该基于特定的class General {
private First first = new First();
private Second second = new Second()
etc...
}
类,它应该适用于除了简单类型之外将被序列化的任何对象。
答案 0 :(得分:2)
是的,可以创建一个使用反射来执行此操作的自定义序列化程序。您可以通过扩展StdSerializer来实现此目的。您的实现可能如下所示:
public class NullSerializer<T> extends StdSerializer<T> {
public NullSerializer() {
this(null);
}
public NullSerializer(Class<T> t) {
super(t);
}
@Override
public void serialize(T item, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException,
IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException)
{
jgen.writeStartObject();
// For all fields of the class you're serializing
for (final Field field : item.getClass().getDeclaredFields())
{
field.setAccessible(true);
Object value = field.get(item);
// if the value is null, create a new instance
if (value == null)
{
value = field.getType().getConstructor().newInstance();
}
// write it
jgen.writeObject(value);
}
jgen.writeEndObject();
}
}
这取决于每个字段都有一个公共默认构造函数。您可能希望捕获一些异常,而不是像我已经完成的那样将它们声明为抛出签名。
您需要使用ObjectMapper注册此序列化程序。 This article解释了如何做到这一点。
我不认为这是一个特别优雅的解决方案,但它应该满足您的要求。我会首先避免使用可空的字段,但在您的情况下可能不可能。