Documentation

You are viewing the documentation for the 2.2.x release series. The latest stable release series is 2.4.x.

§Play JSON ライブラリの基礎

§概要

JSON を使いたければ、play.api.libs.json にある JSON ライブラリを基にした Play の型クラスを使うことをおすすめします。

JSON 文字列をパースするために、Play は超高速な Java ベースの JSON ライブラリ、Jerkson を使います。

このアプローチの利点として、Scala ユーザーは Play の JSON サポートがお膳立てする特上の型安全性と関数型の側面を楽しむことができる一方、Java と Scala の両方の Play は同じ基礎となるライブラリ (Jackson) を共有することができます。

§JSON は AST (_Abstract Syntax Tree: 抽象構文木_)

例として、この JSON を見てください:

{ 
  "user": {
    "name" : "toto",
    "age" : 25,
    "email" : "[email protected]",
    "isAlive" : true,
    "friend" : {
  	  "name" : "tata",
  	  "age" : 20,
  	  "email" : "[email protected]"
    }
  } 
}

これは、以下の二つの仕組みを使った木構造として見ることができます:

正確な JSON 標準について詳しく知りたい場合は、json.org へアクセスしてください

§Json データ型

play.api.libs.json には、これらの構造を反映した 7 つの JSON データ型が含まれています。

§JsObject

標準で説明されている name/value ペアのセットです。例:

{ "name" : "toto", "age" : 45 }

§JsNull

JSON の null を表現します。

§JsBoolean

truefalse の値を取る真偽値です。

§JsNumber

JSON は short, int, long, float, double そして BigDecimal を区別しないので、BigDecimal を含む JsNumber として表現されます。Play の JSON API は、より正確な型の Scala オブジェクトに変換します。

§JsArray

配列は、あらゆる Json 値の型の列です (同じ型である必要はありません) 。例:

[ "alpha", "beta", true, 123.44, 334]

§JsString

標準的な文字列です。

§その他のデータ型

§JsUndefined

これは JSON 標準の一部ではなく、抽象構文木においてエラーとなったノードを表現するために API が内部でのみ使用します。

§JsValue

この他すべての型の親となる型です。

§JSON を使う

Play の JSON API の入り口となるのは play.api.libs.json.Json です。このクラスは次のメソッドを提供します:

§JSON 文字列のパース

どのような JSON 文字列でも JsValue として簡単にパースすることができます:

Unable to find label parse-json in source file code/ScalaJson.scala

この処理結果と対応付けられた json は、以下に続くサンプルコードで使用します。

§JSON ディレクトリの構築

§無骨な方法

上記した Json オブジェクトの例は、別の方法でも作成することができます。以下は無骨なアプローチです。

Unable to find label construct-json-case-class in source file code/ScalaJson.scala

§推奨する方法

Play は JSON を作成する簡素化された文法も提供しています。上記の JsObject は以下を使って構築することができます:

Unable to find label construct-json-dsl in source file code/ScalaJson.scala

§JSON のシリアライズ

JsValue を JSON 文字列表現にシリアライズするのは簡単です:

Unable to find label serialise-json in source file code/ScalaJson.scala

§JSON ツリー内パスへのアクセス

JsValue さえ手に入れば、JSON ツリーの中を探索することができます。この API は、JsValue を探索することを除けば、Scala で NodeSeq を使って XML ドキュメントを探索するために提供されている API と似ています。

§シンプルな \ パス

\ メソッドを使ってオブジェクトのプロパティを渡り歩くことができます:

Unable to find label traverse-path in source file code/ScalaJson.scala

§再帰的な \\ パス

Unable to find label recursive-traverse-path in source file code/ScalaJson.scala

§JsValue から Scala 値への変換

JSON ツリーを渡り歩いていると JsValue を見つけることができますが、JsValue から Scala の型へ変換したくなるかもしれません。
例えば、JsStringString に、または JsNumberLong に変換したくなることでしょう。

§json.as[T] による安全でない変換

JsValue をもっとも簡単に値に変換するのは、以下のようにして as[T] メソッドを使う方法です、

Unable to find label as-method in source file code/ScalaJson.scala

しかし、このメソッドは安全ではないので、パスが見つからなかったり、変換が不可能だった場合は、エラーを含む JsResultException がスローされます。

このエラーは、期待しているであろう path.not.found を返さないことに注意してください。これは、このドキュメントの後の方で登場する JSON コンビネーターとは異なります。
これは、(json \ "user" \ "nameXXX")JsNull を返却し、暗黙の Reads[String] は検出されたエラーで説明されている通り JsString を待ち受けていることによるものです。

§Option[T] による、より安全な変換

asOpt[T] メソッドは as[T] と似ていますが、パスが見つからなかったり、変換が不可能だった場合は、例外をスローする代わりに None を返します:

Unable to find label as-opt in source file code/ScalaJson.scala

§validate[T] による、もっとも安全な変換

asOpt[T] は、より安全ですが、検出されたエラー等を失ってしまいます。

validate[T] は、JsResult[T] を返すことで、JsValue をもっとも安全で堅牢な方法を提供します:

§JsResult[T] をひと言で

JsResult[T] は二つの値を持つことができます:

注意 : JsPath については後ほど説明しますが、JSON における XMLPath とまったく同じものです。
json \ "user" \ "name"
と書く場合、以下のように書くことができます :
(JsPath \ "user" \ "name")(json)
user に続けて name を検索する JsPath を作成し、これを与えられた json に適用します。

このため、成功した変換は次のように見えることでしょう:

Unable to find label validate-success in source file code/ScalaJson.scala

パスが見つからない場合は、次のようになります:

Unable to find label validate-failure in source file code/ScalaJson.scala

mapflatMap が提供されているので、内包表記を使って値を簡単に取り出すことができます:

Unable to find label validate-compose in source file code/ScalaJson.scala

§再帰的なパス \\ の変換

\\ はサブツリーを再帰的に検索し、標準的な Scala 関数のコレクションである、発見した JsValue の Seq[JsValue] を返します。

Unable to find label recursive-as in source file code/ScalaJson.scala

§Scala 値から JsValue への変換

Scala から JSON への変換は、ちょうど T から JsValue に変換するために利用できる、暗黙的な型クラス Writes[T] に基づいた Json.toJson[T](implicit writes: Writes[T]) 関数によって行われます。

§とてもシンプルな JsValue を作る

Unable to find label convert-simple-type in source file code/ScalaJson.scala

Play の JSON API が暗黙の Writes[Int] を提供するので、このように変換することができます

§Create a JSON array from a Seq[T]

Unable to find label convert-seq in source file code/ScalaJson.scala

Play の JSON API が暗黙の Writes[Seq[Int]] を提供するので、このように変換することができます

ここで、Seq[Int] は問題なく Json 配列に変換することができました。しかし、 Seq が異質な値を含むとすると、より複雑です:

import play.api.libs.json._

val jsonArray = Json.toJson(Seq(1, "Bob", 3, 4))

これをコンパイルしようとすると、次のエラーが発生します:

No Json deserializer found for type Seq[Any]. Try to implement an implicit Writes or Format for this type.

これは 、Seq[Any] を Json に変換する手段がないためです (Any は Json でサポートされていないものまで含むことができますよね?)

シンプルな解決方法は、これを Seq[JsValue] として扱うことです:

Unable to find label convert-hetro-seq in source file code/ScalaJson.scala

Play の JSON API が暗黙の Writes[Seq[JsValue]] を提供するので、このように変換することができます

Next: Json の読み/書き/フォーマットの結合


このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。