有两个课Foo和Bar。Foo包含的字段Bar。问题是,如何Writes为类实现隐式json Foo?
Foo
Bar
Writes
这是代码:
package models import play.api.libs.json._ case class Foo(id: String, bar: Bar) object Foo { implicit val implicitFooWrites = new Writes[Foo] { def writes(foo: Foo): JsValue = { Json.obj( "id" -> foo.id, "bar" -> foo.bar ) } } } case class Bar(x: String, y: Int) object Bar { implicit val implicitBarWrites = new Writes[Bar] { def writes(bar: Bar): JsValue = { Json.obj( "x" -> bar.x, "y" -> bar.y ) } } }
当我尝试编译时,出现以下错误:
没有为类型模型找到Json反序列化器。尝试为此类型实现隐式的Writes或Format。
我不了解此编译器错误,因为我为models.Bar类实现了隐式Writes。这里有什么问题?
这是可见性的问题,当您声明隐式Writes [Foo]时,您不会使其对隐式Writes [Bar]可见:
scala> :paste // Entering paste mode (ctrl-D to finish) import play.api.libs.json._ case class Bar(x: String, y: Int) object Bar { implicit val implicitBarWrites = new Writes[Bar] { def writes(bar: Bar): JsValue = { Json.obj( "x" -> bar.x, "y" -> bar.y ) } } } case class Foo(id: String, bar: Bar) object Foo { import Bar._ implicit val implicitFooWrites = new Writes[Foo] { def writes(foo: Foo): JsValue = { Json.obj( "id" -> foo.id, "bar" -> foo.bar ) } } } // Exiting paste mode, now interpreting. import play.api.libs.json._ defined class Bar defined module Bar defined class Foo defined module Foo scala> Json.prettyPrint(Json.toJson(Foo("23", Bar("x", 1)))) res0: String = { "id" : "23", "bar" : { "x" : "x", "y" : 1 } }
另外,如果您使用的是Play 2.1+,请确保检查出2.10宏的全新用法:http : //www.playframework.com/documentation/2.1.0/ScalaJsonInception
如果您对案例类的使用感到满意,并且将val / vars名称用作json输出中的键(例如在案例BTW中),则可以使用两个单行代码:
implicit val barFormat = Json.writes[Bar] implicit val fooFormat = Json.writes[Foo]
这将为您提供完全相同的内容:
scala> import play.api.libs.json._ import play.api.libs.json._ scala> case class Bar(x: String, y: Int) defined class Bar scala> case class Foo(id: String, bar: Bar) defined class Foo scala> implicit val barWrites = Json.writes[Bar] barWrites: play.api.libs.json.OWrites[Bar] = play.api.libs.json.OWrites$$anon$2@257cae95 scala> implicit val fooWrites = Json.writes[Foo] fooWrites: play.api.libs.json.OWrites[Foo] = play.api.libs.json.OWrites$$anon$2@48f97e2a scala> Json.prettyPrint(Json.toJson(Foo("23", Bar("x", 1)))) res0: String = { "id" : "23", "bar" : { "x" : "x", "y" : 1 } }