2016-10-08 21 views
0

我們有一個現有的類A,以前是唯一可能出現在我們的REST API端點的JSON輸出中的某個位置的類型。但是,我現在將它擴展爲一個通用基類B,以便一系列不同類型(全部從B繼承)可以出現在輸出中的該位置。如何在lift-json中爲自定義序列化程序添加類型提示?

我向Formats添加了一個類型提示,但即使Formats方法在兩個方向上都正確查找了類型提示信息,但在由lift-json進行序列化時,類型提示被忽略。

事實證明,lift-json沒有將類型提示字段添加到JSON的原因是因爲在我們的Formats實例中還有一個爲該類配置的自定義序列化程序,並且自定義序列化器會覆蓋類型提示。

那麼我們怎麼能有一個類都有一個自定義的序列化器,併發出併產生類型提示以允許它的類型被明確地識別(在客戶端和服務器上)?

回答

0

這不是很充分證明了,而是在TypeHints特點有兩個方法:

def deserialize: PartialFunction[(String, JObject), Any] = Map() 
def serialize: PartialFunction[Any, JObject] = Map() 

這些方法可以實現TypeHints特徵(或延長TypeHints提供的默認實現的時候時,可以覆蓋)爲指定了類型提示的JSON對象指定自定義序列化和反序列化邏輯。默認實現(上面顯示)只是部分函數,​​它們不匹配任何東西,所以它們沒有任何效果。

沒有與deserializeserialize方法Serializer,這就是我們的代碼以前使用的一些差異:

  1. 這些方法不採取Formats的說法,這意味着它必須依靠範圍內的Formats實例。

  2. 他們在JObject操作上的轉換JSON的一面,而不是它的超JValue(很明顯,當你想想看 - 因爲任何一個類型提示不可避免地必須是一個JSON對象,而不是字符串或數字或其他)。

  3. 笑看類型參數,只是在轉換的斯卡拉側Any工作 - 那是因爲他們只是處理需要自定義序列化邏輯在一個大的部分功能,所有類型暗示的類型。

  4. 相反的TypeInfo,所述deserialize局部函數採用一個String,這是類型提示字段的值。

我想大多數的這些差異,因爲這是舊的電梯JSON的代碼,從Serializer性狀出現之前,當只有一個辦法做到自定義序列化。

那麼什麼工作對我來說是:

def typeHints(implicit formats: Formats) = new OurTypeHintsImpl( ...類型提示信息 ... ) {

override def deserialize = {

case ("type-hint-for-A", o: JObject) => ... 現有的反串行化代碼 ...

}

override def deserialize = {

case A( ... ) => ... 現有串行代碼 ...

}

,並添加另一種類型既類型的提示和自定義序列化邏輯,它只是需要一個新的分支case添加到這兩個的以上。

通過這種方法,正確類型的提示是通過舉JSON自動添加,但你仍然得到完全自主如何系列化和deserialisation的其餘部分完成。所以我認爲這對大多數情況來說是最方便和適合的方法(但它確實需要一些重構)。它也應該能夠重新實現類型提示自定義Serializer,但爲什麼另起爐竈?

警告:匹配類型的案例在默認情況下對泛型類型有限制,但這通常不應該爲此目的考慮 - 除非您不是獨立序列化包含在另一個類型中的泛型類型,而是將其合併轉換成JSON中的外部類型。

相關問題