2017-08-08 158 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

相關問題