2

我正在解析一个json。我想将它的值转换为其他类型。IE

//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 无法在 scala.runtime.BoxesRunTime.unboxToLong 中转换为 java.lang.Long(未知来源)

4

4 回答 4

4

I had the same problem and remembered that Play framework had some functionality that did something similar. After digging through the source I found this Class.

Basically, we can do something like this:

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!
  }
}

Can be called like:

JSONCaster.fromJson[Long](json, "seq")

The downside is we have to define implicit converters for all the types we want to cast to. The upside being this keeps the interface really clean and reusable.

于 2018-04-09T18:44:02.037 回答
1

看看在 Spray 中实现的编组/解组。您可能不需要重新发明解决方案,如果这样做,您可以查看他们的源代码以了解他们是如何实现它的。

Spray 的编组/解组与对象图序列化类似,并且不仅仅使用 JSON,因此在实现中存在一些额外的固有复杂性。

您还可以绕过手动解析 JSON 并尝试lift-json

lift-json 更接近 JSON,尽管extract它可以像 Spray 的 marshaller/unmarshaller 一样运行。

于 2013-07-18T12:37:06.513 回答
0

我在Derek Wyatt 的博客中找到了最好的解决方案——这就是 monad 很棒的原因之一

于 2013-07-21T06:55:44.897 回答
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])
}
于 2020-12-09T16:11:53.303 回答