如何在不知道具体类型的情况下在scala中使用lift json进行反序列化?

如何在不知道具体类型的情况下在scala中使用lift json进行反序列化?,json,scala,lift,json-deserialization,lift-json,Json,Scala,Lift,Json Deserialization,Lift Json,给定lift json2.0和以下Scala类&sealedtrait: sealed trait Location case class Coordinate(latitude: Double, longitude: Double) extends Location case class Address(...) extends Location 我希望能够在不确定具体实现的情况下反序列化Location对象: deserialize[Loca

给定
lift json
2.0和以下Scala类&sealedtrait:

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)

有什么办法吗?

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

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会得到一个类型提示:

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

这种格式在某种程度上可以使用,这里有一个

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

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会得到一个类型提示:

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

这种格式在某种程度上可以使用,这里有一个提升Json不会自动检测到要反序列化到的子类,因为没有直接的方法来实现这一点。您可能有两个子类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)
  }
}

如果您不能基于arity来选择类型,那将更加复杂,但您已经了解了一般的想法。

Lift-Json不会自动检测要反序列化的子类,因为没有直接的方法。您可能有两个子类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)
  }
}
如果你不能根据算术来选择你的类型,那就更复杂了,但你得到了大致的想法。

“Dave Whittaker”和“Rin malavi”大体上是正确的。此外,如果您需要临时解决方案,您可以使用:

str.extractOpt[Address] getOrElse str.extract[Coordinate]
@"戴夫·惠塔克"和"林·马拉维"总的来说是对的。此外,如果您需要临时解决方案,您可以使用:

str.extractOpt[Address] getOrElse str.extract[Coordinate]

顺便说一句,现在有一些新闻:他们声称“支持特征(例如,类型trait Animal的数据值将解析实现类Dog和Cat)”顺便说一句,现在有一些新闻:他们声称“支持特征(例如,类型trait Animal的数据值将解析实现类Dog和Cat)”