2016-10-08 25 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中的外部类型。

相关问题