尝试从http://www.playframework.com/documentation/2.2.x/ScalaJsonCombinators运行Json读取和写入的Json Combinator示例:
def test = Action {
case class Creature(name: String,isDead: Boolean,weight: Float, email: String, favorites: (String, Int), friends: List[Creature] = Nil, social: Option[String] = None)
import play.api.libs.json._
import play.api.libs.functional.syntax._
implicit val creatureWrites: Writes[Creature] = (
(__ \ "name").write[String] and
(__ \ "isDead").write[Boolean] and
(__ \ "weight").write[Float] and
(__ \ "email").write[String] and
(__ \ "favorites").write(
(__ \ "string").write[String] and
(__ \ "number").write[Int]
tupled
) and
(__ \ "friends").lazyWrite(Writes.traversableWrites[Creature](creatureWrites)) and
(__ \ "social").write[Option[String]]
)(unlift(Creature.unapply))
val gizmo = Creature("gremlins", false, 1.0F, "gizmo@midnight.com", ("alpha", 85), List(), Some("@gizmo"))
val gizmojs = Json.toJson(gizmo)
Ok(gizmojs toString)
}
我收到以下编译错误:
[error] ....:forward reference extends over definition of value creatureWrites
[error] (__ \ "friends").lazyWrite(Writes.traversableWrites[Creature](creatureWrites))
Reads
和Format
存在类似的问题。
请帮忙。
答案 0 :(得分:3)
那是因为您将隐式值定义为本地成员。类和对象允许前向引用,而本地块不允许
因此,只需将隐式读写定义为类成员,而不是本地
看看我的测试
规范:
import play.api.libs.json._
import play.api.libs.functional.syntax._
import org.specs2.mutable.Specification
case class Creature(
name: String,
isDead: Boolean,
weight: Float,
email: String,
favorites: (String, Int),
friends: List[Creature] = Nil,
social: Option[String] = None)
class FooSpec extends Specification {
implicit val creatureWrites: Writes[Creature] = (
(__ \ "name").write[String] and
(__ \ "isDead").write[Boolean] and
(__ \ "weight").write[Float] and
(__ \ "email").write[String] and
(__ \ "favorites").write(
(__ \ "string").write[String] and
(__ \ "number").write[Int]
tupled
) and
(__ \ "friends").lazyWrite(Writes.traversableWrites[Creature](creatureWrites)) and
(__ \ "social").write[Option[String]]
)(unlift(Creature.unapply))
implicit val favouriteReads: Reads[(String, Int)] =
(__ \ "string").read[String]and
(__ \ "number").read[Int] tupled
implicit val creatureReads = Json.reads[Creature]
val gizmo = Creature("gremlins", false, 1.0F, "gizmo@midnight.com", ("alpha", 85), List(), Some("@gizmo"))
val gizmojs = Json.toJson(gizmo)
"writes" should {
"write scala value as string" in {
Json.parse(gizmojs.toString).as[Creature] must be_==(gizmo)
}
}
}
结果:
[success] Total time: 10 s, completed Jan 1, 2014 11:25:25 PM
[ops-ui] $ testOnly FooSpec
[info] FooSpec
[info] writes should
[info] + write scala value as string
[info] Total for specification FooSpec
[info] Finished in 1 second, 813 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 6 s, completed Jan 1, 2014 11:25:45 PM
您可以轻松定义读/写
implicit val favouriteWrites =
(__ \ "string").write[String] and
(__ \ "number").write[Int] tupled
implicit val creatureWrites: Writes[Creature] = Json.writes[Creature]
implicit val favouriteReads: Reads[(String, Int)] =
(__ \ "string").read[String]and
(__ \ "number").read[Int] tupled
implicit val creatureReads = Json.reads[Creature]
答案 1 :(得分:1)
你是完全正确的,它没有记录的那样。我认为Play的JSON组合器仍然处于不稳定的状态,因此文档可能会受到影响。
快速修复:将creatureWrites
更改为def
,因此允许“转发引用”(这是一个递归函数调用):
implicit def creatureWrites: Writes[Creature] = (
...
)