我有以下JSON对象:
{"values": "123,456,789"}
我想使用play框架的JSON库将此JSON对象转换为具有以下签名的类Foo
的实例:
case class Foo(value1: Double, value2: Double, value3: Double)
在documentation about JSON combinators中,只有转换的示例,其中类的构造函数签名与提取的JSON值匹配。如果我遇到这种情况,我必须编写以下Reads函数:
import play.api.libs.json._
import play.api.libs.functional.syntax._
implicit val fooReads: Reads[Foo] = (
(JsPath \ "values").read[String]
)(Foo.apply _)
但是,首先我必须将字符串"123,456,789"
拆分为三个单独的字符串,并在创建类Double
的实例之前将它们中的每一个转换为Foo
值。如何使用JSON组合器完成此操作?我无法找到相关的例子。尝试将函数文本作为参数传递不起作用:
// this does not work
implicit val fooReads: Reads[Foo] = (
(JsPath \ "values").read[String]
)((values: String) => {
val Array(value1, value2, value3) = values.split(",").map(_.toDouble)
Foo(value1, value2, value3)
})
答案 0 :(得分:2)
编译器感到困惑,并认为您将函数作为(通常是隐式)参数传递给read
方法。您可以通过明确使用Reads.map
代替ApplicationOps.apply
来解决此问题:
implicit val fooReads: Reads[Foo] = {
(JsPath \ "values").read[String] map { values =>
val Array(value1, value2, value3) = values.split(",").map(_.toDouble)
Foo(value1, value2, value3)
}
}
答案 1 :(得分:1)
或者,您可以重载伴随对象的apply
方法,该方法不需要对隐式读取代码进行任何更改。相反,将字符串转换为一组值的逻辑将包含在apply
中。
import play.api.libs.json._
import play.api.libs.functional.syntax._
case class Foo(value1: Double, value2: Double, value3: Double)
object Foo {
def apply(values: String) = {
values =>
val Array(value1, value2, value3) = values.split(",").map(_.toDouble)
Foo(value1, value2, value3)
}
implicit val fooReads: Reads[Foo] = (
(JsPath \ "values").read[String]
)(Foo.apply _)
}