Closed dr-jerry closed 2 years ago
@dr-jerry
Maybe, we can use jsonFormatN for class which contains primitive values only. If a class contains original class, should write/read function ourself. e.g. see Providing JsonFormats for unboxed types
case class Foo(i: Int, foo: Foo)
object PlayerJsonProtocol extends DefaultJsonProtocol {
import OthersProtocols.FooProtocol
implicit val fooFormat: JsonFormat[Foo] = lazyFormat(jsonFormat(Foo, "i", "foo"))
}
object OthersProtocols {
implicit object FooProtocol extends JsonFormat[Foo] {
def write(f: Foo): JsValue = JsObject(
"i" -> JsNumber(f.i),
"foo" -> write(f.foo)
)
def read(value: JsValue): Foo =
value match {
case JsObject(fields) =>
(for {
i <- fields.get("i").map(_.convertTo[Int])
foo <- fields.get("foo").map(read)
} yield Foo(i, foo)).get
case JsNull => None.orNull
case _ => deserializationError(s"unexpected json type for Foo, json: ${value}")
}
}
}
check by test
class PlayerJsonProtocolTest extends FunSuite {
val jsonString = """
|{
| "i": 1,
| "foo": {
| "i": 2,
| "foo": null
| }
|}
|""".stripMargin
test("something test"){
println(jsonString.parseJson.convertTo[Foo])
assert(
jsonString.parseJson.convertTo[Foo] ==
Foo(1, Foo(2, None.orNull))
)
}
}
No. the above code works as intended. Maybe the issue is that using just Foo
as a constructor isn't working all the time?
Try jsonFormat2(Foo.apply _)
instead.
Maybe the issue is that using just
Foo
as a constructor isn't working all the time?
I.e. when Foo has a companion object. Without a companion object it works just as state above.
case class Foo(i: Int, foo: Foo)
could not find implicit value for evidence parameter