0

Play 2.1 Scala で JSON の Format オブジェクトを書くのに問題があります。私の(非常に単純化された)JSONは次のようになります。

{
  "id": "id-1",
  "data": {
    "foo": "teststr1",
    "bar": "teststr2"
  }
}

これを少し単純でフラットな形式にシリアライズ/デシリアライズしたい:

case class TestData(id: String, foo: String, bar: String)

これに対する私の最初の試みは次のようになります。

implicit val testCaseFormat: Format[TestData] = (
  (__ \ "id").format[String] and
  (__ \ "data" \ "foo").format[String] and
  (__ \ "data" \ "bar").format[String]
)(TestData.apply, unlift(TestData.unapply))

データを読み取るときは問題なく動作しますが、書き込み時には最後の「データ」値 ( bar) のみが出力 JSON に存在します。おそらく、data後続の値ごとにオブジェクトが上書きされるためです。

{
   "id" : "id-1",
   "data":{
     "bar":"teststr2"
   }
 }

Reads分離とWritesオブジェクトに頼らずに、この平坦化と非平坦化を行う正しい方法はありますか? 私の実際のデータ構造は非常に大きいので(複雑すぎませんが)、簡潔さは良いです。

4

1 に答える 1

2

私が正しく理解している場合は、通常の方法でフォーマットを作成できます/作成する必要があります。

(__ \ "id").format[String] and
(__ \ "data").format(
  (__ \ "foo").format[String] and
  (__ \ "bar").format[String]
  tupled
)

そして、別のapplyandunapplyメソッドを提供するだけです。

def specialApply(data:(String, (String, String))) = {
  val(id, (foo, bar)) = data
  TestData(id, foo, bar)
}

def specialUnapply(data:TestData):Option[(String, (String, String))] =
  Option(data) map { testData =>
    (testData.id, (testData.foo, testData.bar))
  }

編集

apply および unapply メソッドを適切に構成することにより、コンパニオン オブジェクトにメソッドを追加することを回避できます。

implicit val testCaseFormat: Format[TestData] = (
    // ...
)(TestData.tupled.compose { data:(String, (String, String)) => 
    val (id, (foo, bar)) = data
    (id, foo, bar)
  }), unlift(TestData.unapply))
于 2013-02-16T11:24:45.497 に答える