首页 > 解决方案 > Jackson scala对象映射器未正确序列化嵌套案例类

问题描述

我有一个这样定义的模式

@JsonDeserialize(using = classOf[ProductDeserializer])
trait GenericProduct{
  @JsonUnwrapped
  def commonAttributes: CommonAttributes
}

有不同种类的产品。例如,下面给出的产品 A 扩展了基本特征产品。同样,还有其他产品 B、C、D。

case class ProductA(commonAttributes: CommonAttributes,
                    extraField1: String,
                    extraField2: String) extends GenericProduct

我的序列化方法是这样的

@Component
class ProductSerializer @Autowired()
(val mapper: ScalaObjectMapper = ObjectMapperSingleton.getMapper) {

    def serialize[T<:GenericProduct](product: T)(implicit m: Manifest[T]): String = {
        mapper
          .writerWithType[T]
          .writeValueAsString(product)
      }
}

如果我传递 A、B、C、D 类型的对象,它就可以正常工作。序列化的 JSON 字符串具有通用属性和产品特定属性。

但是,如果我将产品对象包装在案例类中。例如,从一种方法我返回这样的东西

case class ConsolidatedProducts(newProducts: List[GenericProduct],
                                oldProducts: List[GenericProduct])

它在编译时不会抱怨,但在运行时输出只有公共属性。

问题:这是因为类型擦除吗?如果我将清单隐式传递到调用和使用统一产品的所有地方,那么我可以看到具有所有属性的预期 JSON,这让我相信这是因为类型擦除。

找到了两种方法来解决这个问题

  1. 在任何地方隐式使用 manifest 来保留类型信息
  2. 只需更新writerWithType[T]writerWithType[T.type]

还有其他解决方法吗?我仍然不确定为什么第二种解决方案有效。如果有人可以解释,那就太好了。

标签: scalaserializationjacksonjackson-databind

解决方案


推荐阅读