は、私は3つのメンバを持つダミーのクラスFoo
を持っている:Foo
オブジェクトをシリアル化するとき、私はいくつかの興味深い行動を見つける Option [String]型のメンバーがシリアル化されていないのはなぜですか?
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]
}
として
FooType
が定義されている
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]
}
。私はJSONにFoo
をシリアル化した場合、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オブジェクトを印刷すると、nextId
フィールドがJSONオブジェクトにありません:
println(Json.prettyPrint(jsonFoo))
{
"id" : "id",
"fooType" : {
"a" : "a",
"b" : "b"
}
}
ただし、nextId
フィールドはtoOption
で解析できます。つまり、
assert((jsonFoo \ "nextId").toOption.isEmpty)
メンバの1つがネイティブに直列化できない場合、オブジェクトをJSONから正しく解析するにはどうすればよいですか。
興味深い。 Playでは 'None'を' null'や 'JsNull'オブジェクトにシリアライズすると思うかもしれませんが、私は今カスタムライターを定義しなければならないことを見ています。答える時間をとってくれてありがとう! – erip
これは片方向に過ぎません。 JSONの欠落したフィールドまたは 'null'は' Option'にマップされますが、 'Option'は2つのうちの一方にしかマッピングできません。デザイナーは、より合理的なこととしてフィールドを省略しました。 –
意味があります。それが正しく解析できる限り、それはうまくいく - それは要点です。 – erip