14

ケース クラスから作成された 2 つの JsValue があります。つまり、ブックとブックの詳細です。

val bookJson = Json.tojson(Book)
val bookDetailJson = Json.tojson(BookDetail)

フォーマットは次のようになります。

//Book
{
  id: 1,
  name: "A Brief History of Time"
}

//BookDetail
{
  bookId: 1,
  author: "Steven Hawking",
  publicationDate: 1988,
  pages: 256
}

play-framework 2.10 でそれらを単一の Json にマージするにはどうすればよいですか? すなわち

//Book with detail
{
  id: 1,
  name: "A Brief History of Time",
  bookId: 1,
  author: "Steven Hawking",
  publicationDate: 1988,
  pages: 256
}

私は変換を試みていましたが、2 番目の JsValue を反復処理できませんでした:

val mapDetail = (__).json.update(
                  __.read[JsObject].map { o =>
                  o.deepMerge( JsObject(Seq(("detail", bookDetailJson))) )
                })

bookJson.validate(mapDetail).get

それは私が本当に望んでいない1レベル下になります.

//Book with detail
{
  id: 1,
  name: "A Brief History of Time",
  detail: {
            bookId: 1,
            author: "Steven Hawking",
            publicationDate: 1988,
            pages: 256
          }
}

この Json 変換で提供できるトリックがあれば教えてください。どうもありがとう!

4

2 に答える 2

18

Play には現在、JSON に関する多くの新機能があります。これは、私が示すようにFormat[A]暗黙的に、または暗黙的なFormat[A]/Reads[A]/Writes[A].

JSON オブジェクトを表すケース クラスを作成します。

case class Book(id: Int, name: String)
case class BookDetail(id: Int, author: String, publicationDate: Int, pages: Int)

暗黙的なものを含むコンパニオン オブジェクトを作成して、必要なときに自動的にスコープに含まれるようにしますFormat[A]Format/Reads/Writes

object Book { 
  implicit val fmt: Format[Book] = Json.format[Book] 
}

object BookDetail { 
  implicit val fmt: Format[BookDetail] = Json.format[BookDetail] 
}

今、あなたはこのようなことをすることができます、

val bookJson = Json.toJson(Book(1, "A Brief History Of Time"))
val bookDetailJson = Json.toJson(BookDetail(1, "Steven Hawking", 1988, 256))
bookJson.as[JsObject].deepMerge(bookDetailJson.as[JsObject])

そして、あなたはこのようなオブジェクトを持つでしょう、

{
  id: 1,
  name: "A Brief History Of Time",
  author: "Steven Hawking",
  publicationDate: 1988,
  pages: 256
}

REPL でこれを試しましたが、動作しません。Play アプリケーションでは問題なく動作します。また、実稼働シナリオではasOpt[T]、 の代わりに使用する可能性がありas[T]ます。

asOpt[T]より適している理由の例を次に示します。たとえば、書籍の有効な JSON オブジェクトを取得する代わりに、

val bookJson = Json.toJson("not a book")

あなたはで終わるでしょう

[JsResultException: JsResultException(errors:List((,List(ValidationError(validate.error.expected.jsobject,WrappedArray())))))]

しかし、代わりにメソッドを useasOpt[T]に変更するとします。

bookJson.asOpt[JsObject].getOrElse(Json.obj()).deepMerge(bookDetailJson.asOpt[JsObject].getOrElse(Json.obj()))

これで、少なくとも部分的な JSON オブジェクトになり、

{
  id: 1,
  author: "Steven Hawking",
  publicationDate: 1988,
  pages: 256
}

そのため、不適切にフォーマットされた JSON をどのように処理したいかによって、いずれかのオプションを選択できます。

于 2013-10-23T20:03:07.460 に答える