1

有了这个jackson-module-scala包装

object Json {
  private val ma = new ObjectMapper with ScalaObjectMapper
  ma.registerModule(DefaultScalaModule)
  ma.setSerializationInclusion(Include.NON_NULL)

  def jRead[T: Manifest](value: String): T = ma.readValue[T](value)
  def jWrite(value: Any) = ma.writer.writeValueAsString(value)
  def jNode(value: String) = ma.readTree(value)
}

我尝试阅读子类型(这只是没有实际工作的简化用例):

object TestJTrait extends App {
  trait T1
  object TestJ { def apply[X <: T1: Manifest](s: String): X = jRead[X](s) }
  case class C1(i: Int) extends T1
  TestJ(jWrite(C1(42)))
}

但是这种尝试会导致错误:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate abstract type [simple type, class scala.runtime.Nothing$] (need to add/enable type information?)
 at [Source: {"i":42}; line: 1, column: 2]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
    at com.fasterxml.jackson.databind.deser.std.ThrowableDeserializer.deserializeFromObject(ThrowableDeserializer.java:73)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3051)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2160)
    at com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper$class.readValue(ScalaObjectMapper.scala:180)

任何人都可以建议一种解决方法来获得预期的行为吗?

4

2 回答 2

1

由于 T1 是一个特征(抽象类型),在反序列化时它会尝试创建 T1 的实例,它没有关于 C1 的信息。你需要暗示它。

TestJ[C1](jWrite(C1(42))应该有帮助

于 2014-08-20T18:10:52.413 回答
1

如果你也有case class C2(i: Int) extends T1,怎么会选择阅读C1C2?如果你不知道,它怎么会知道你不知道呢?毕竟,C2它可能在您程序中的任何地方,可能在一个尚未加载的类中(也可以C1!)。Manifest in[X <: T1: Manifest]也无济于事,因为无法推断类型参数。

于 2014-08-20T20:06:06.400 回答