1

给定lift-json2.0 和以下 Scala 类和密封特性:

sealed trait Location

case class Coordinate(latitude: Double,
                      longitude: Double) extends Location

case class Address(...) extends Location

我希望能够在不确定具体实现的情况下反序列化 Location 对象:

deserialize[Location](""" { "latitude":0.0, "longitude":0.0 } """)

应该产生相当于:

val location: Location = Coordinate(0.0, 0.0)

有什么办法吗?

4

3 回答 3

2

这可能不是您想要的,但是:

implicit val formats = net.liftweb.json.DefaultFormats
  .withHints(ShortTypeHints(List(classOf[Geo], classOf[Address])))

使您能够编写

val loc: Location = read(write(Geo(0.0, 0.0)))

然而,你的 json 然后得到一个 TypeHint:

{"jsonClass":"Geo","latitude":0.0,"longitude":0.0}

这种格式可以玩一些,here is a nice post about type hints。

于 2013-11-19T14:40:07.537 回答
1

@“Dave Whittaker”和@“Rin malavi”总体上是对的。此外,如果您想要一个临时解决方案,您可以使用:

str.extractOpt[Address] getOrElse str.extract[Coordinate]
于 2013-11-21T05:58:43.033 回答
1

Lift-Json 不会自动检测要反序列化的子类,因为没有直接的方法可以做到这一点。您可能有 2 个 Location 子类,它们接受纬度和经度构造函数参数,或其他一些歧义。

类型提示绝对是一种方法。如果您不想用 scala 特定信息混淆 JSON,您也可以将字符串表示反序列化为 JValue,然后检查结构以确定要绑定到哪个类。

def location(str: String): Location = {
  val jv = JsonParser.parse(string)
  jv match {
     case jo: JObject if jo.children.size == 2 => Extraction.extract[Coordninate](jo)
     case _ => Extraction.extract[Address](jv)
  }
}

如果你不能根据数量来选择你的类型,那会更复杂,但你明白了。

于 2013-11-20T15:38:23.290 回答