hay dos clases Foo
y Bar
. Foo
contiene un campo de Bar
. La pregunta es, ¿cómo implemento un json implícito? Writes
para clase Foo
?
Aquí está el código:
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
)
}
}
}
Cuando intento compilar, me sale el siguiente error:
No se ha encontrado ningún deserializador Json para modelos de tipo. Barra. Trate de implementar un Escrituras implícitas o Formato para este tipo.
No entiendo este error del compilador, ya que implementé una clase implícita de Escrituras para modelos. Barra. ¿Cuál es el problema aquí?
Respuestas
29 para la respuesta № 1Es una cuestión de visibilidad, al declarar las Escrituras implícitas [Foo] no está haciendo visibles las Escrituras [Barras] implícitas:
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
}
}
Además, si está utilizando Play 2.1+, asegúrese de verificar el nuevo uso de las macros de 2.10 ": http://www.playframework.com/documentation/2.1.0/ScalaJsonInception
Si está satisfecho con el uso de las clases de casos y los nombres de val / vars que se utilizan como claves en la salida json, como en su caso BTW, entonces puede usar las dos líneas de una línea:
implicit val barFormat = Json.writes[Bar]
implicit val fooFormat = Json.writes[Foo]
Eso te dará el equivalente exacto:
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
}
}