【发布时间】:2017-07-17 02:14:04
【问题描述】:
我有一个虚拟类Foo,它有三个成员:
import play.api.libs.json.Json
case class Foo(id: String, fooType: FooType, nextId: Option[String])
object Foo {
implicit val fooReads = Json.reads[Foo]
implicit val fooFormat = Json.format[Foo]
}
FooType 定义为
import play.api.libs.json.Json
case class FooType(a: String, b: String)
object FooType {
implicit val fooTypeReads = Json.reads[FooType]
implicit val fooTypeFormat = Json.format[FooType]
}
我在序列化Foo 对象时发现了一些有趣的行为。如果我将Foo序列化为JSON,解析JSONified Foo,我发现所有成员都被正确解析:
val id = "id"
val fooType = FooType("a", "b")
val nextId = None
val foo = Foo(id, fooType, nextId)
val jsonFoo = Json.toJson(foo)
val parsedFoo = Json.parse(jsonFoo.toString).as[Foo]
assert(parsedFoo == foo)
assert(parsedFoo.id == id)
assert(parsedFoo.fooType == fooType)
assert(parsedFoo.nextId.isEmpty)
这很好,因为这是我所期望的。
但是,在我的下一个测试中,我发现 nextId 字段根本不可可序列化:
val id = "id"
val fooType = FooType("a", "b")
val nextId = None
val foo = Foo(id, fooType, nextId)
val jsonFoo = Json.toJson(foo)
assert((jsonFoo \ "id").as[String] == id)
assert((jsonFoo \ "fooType").as[FooType] == fooType)
assert((jsonFoo \ "nextId").as[Option[String]].isEmpty)
这会失败并出现以下错误:
Error:(38, 35) No Json deserializer found for type Option[String]. Try to implement an implicit Reads or Format for this type.
assert((jsonFoo \ "nextId").as[Option[String]].isEmpty)
Error:(38, 35) not enough arguments for method as: (implicit fjs: play.api.libs.json.Reads[Option[String]])Option[String].
Unspecified value parameter fjs.
assert((jsonFoo \ "nextId").as[Option[String]].isEmpty)
同样,我发现当我打印Json.toJson(foo)转储的JSON对象时,JSON对象中缺少nextId字段:
println(Json.prettyPrint(jsonFoo))
{
"id" : "id",
"fooType" : {
"a" : "a",
"b" : "b"
}
}
不过,我可以用toOption 解析nextId 字段;即,
assert((jsonFoo \ "nextId").toOption.isEmpty)
如果我的对象之一不是本机可反序列化的,如何从 JSON 中正确解析我的对象?
【问题讨论】:
标签: json scala serialization optional play-json