我正在解析一个json。我想将它的值转换为其他类型。 即
//json = JSON String
val seq = net.liftweb.json.parse(json).\\("seq").values.toString.toLong
val userName = net.liftweb.json.parse(json).\\("name").values.toString
val intNum = net.liftweb.json.parse(json).\\("intId").values.toInt
我想用通用方法更加“scala”方式来投射它,我试过这样的事情:
object Converter{
def JSONCaster[T](json:String,s:String):T={
net.liftweb.json.parse(json).\\(s).values.toString.asInstanceOf[T]
}
}
但是出现了投射错误:
java.lang.ClassCastException:java.lang.String无法强制转换为 java.lang.Long at scala.runtime.BoxesRunTime.unboxToLong(未知 源)
答案 0 :(得分:3)
我遇到了同样的问题,并记得Play框架有一些功能可以做类似的事情。在挖掘源代码后,我发现了这个Class。
基本上,我们可以这样做:
object JSONCaster {
def fromJson[T](json: String, s: String)(implicit converter: Converter[T]): T = {
converter.convert(net.liftweb.json.parse(json).\\(s).values.toString)
}
trait Converter[T] { self =>
def convert(v: String): T
}
object Converter{
implicit val longLoader: Converter[Long] = new Converter[Long] {
def convert(v: String): Long = v.toLong
}
implicit val stringLoader: Converter[String] = new Converter[String] {
def convert(v: String): String = v
}
implicit val intLoader: Converter[Int] = new Converter[Int] {
def convert(v: String): Long = v.toInt
}
// Add any other types you want to convert to, even custom types!
}
}
可以像:
一样调用JSONCaster.fromJson[Long](json, "seq")
缺点是我们必须为我们想要转换的所有类型定义隐式转换器。这样做的好处是使界面非常干净和可重复使用。
答案 1 :(得分:1)
看一下在Spray中实现的marshalling/unmarshalling。您可能不需要重新发明解决方案,如果这样做,您可以查看their source以了解它们是如何实现的。
Spray的编组/解组类似于对象图序列化,并且不仅仅使用JSON,因此在实现中还有一些额外的固有复杂性。
您也可以手动解析JSON并尝试lift-json。
lift-json更接近JSON虽然通过extract
它可以像Spray的marshaller / unmarshaller那样操作。
答案 2 :(得分:0)
答案 3 :(得分:0)
在这里,我在scala中有一个通用方法,可以使用liftweb / lift-json。 作为一个主意,您需要提供隐式清单。
import net.liftweb
private def jsonToObjectsSeq[T](jsonAsString: String)(implicit man: Manifest[T]): Seq[T] = {
parse(jsonAsString)
.children
.map(_.extract[T])
}