2017-08-08 128 views
1

我有巨大的json文档和映射到该json的相应jaskson模型。在某些情况下,不可能使用所有对象构建所需的json文档,因为某些数据不存在。Jackson:将空对象序列化为空

比如我有以下型号:

class First { 

    private firstField; 
    private secondField; 
    etc... 
} 

class Second { 

    private firstField; 
    private secondField; 
    etc... 
} 

class General { 

    private First first; 
    private Second second; 
    etc... 
} 

而且有可能来填充只一审:

在通常情况下,它会被序列化是这样的:

{ 
    "first":{ 
     "firstField":"some_value", 
     "secondField":"some_value" 
    }, 
    "second":null 
} 

但我的目标是序列化一般类是这样的:

{ 
    "first":{ 
     "firstField":"some_value", 
     "secondField":"some_value" 
    }, 
    "second":{ 
     "firstField":"null", 
     "secondField":"null" 
    } 
} 

有可能,以便在默认情况下使用默认的构造函数的成员初始化依照一般类的变化来实现这一点:

class General { 

     private First first = new First(); 
     private Second second = new Second() 
     etc... 
    } 

但这种方法会导致围绕现有车型太多的变化,我不确定这是最好的方法。是否有可能创建一个自定义序列化器,它将自己做到这一点?

编辑根据https://stackoverflow.com/users/1898563/michael建议:

所以,主要的想法是创建序列化,将能够检查实例是否为空,如果是空它应该能够创建一个使用默认的新实例构造函数,说明:该序列化程序不应该基于特定的Second类,它应该可以用于除了简单类型之外的将被序列化的任何对象。

回答

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解释如何做到这一点。


我不认为这是一个特别优雅的解决方案,但它应该满足您的要求。我会首先避免使用可空字段,但在您的情况下这可能不可行。

+0

谢谢,为了快速回答,可能我的问题没有以适当的方式描述,实际上有序列化程序的主要想法,它将能够检查除简单类型之外的任何对象,无论它是否为null,并且它是否为null,它应该是能够使用默认构造函数创建新对象,所以它不应该基于某种特定的第二类型,它应该能够处理每个将被序列化的新对象。 – fashuser

+0

没问题。那么你需要编辑你的问题。 – Michael

+0

完成,根据您的建议更新 – fashuser

相关问题