我々はAccountStatus
にInt
を変換するfromInt
を使用する必要があるためので、このコードはobject AccountStatus
コードブロックの内部を追加する必要があります。これは、AccountStatusのために定義されReads
です:
implicit object AccountStatusReads extends Reads[AccountStatus] {
def reads(jsValue: JsValue): JsResult[AccountStatus] = {
(jsValue \ "as").validate[Int].map(fromInt)
}
}
Reads
何? JSON値をカプセル化するplayクラスであるJSValueをJSONから何らかの型に逆シリアル化する方法を定義するのはtrait
です。この特性は、ある種のjsonを取り込み、何らかのタイプのJsResult
を返す、1つのメソッド、reads
メソッドのみを必要とします。したがって、上記のコードではReads
があり、JSONのフィールドを検索してas
と呼び、これを整数として読み取ろうとしています。そこから、すでに定義されたfromIntメソッドを使用して、AccountStatus
に変換されます。だから、例えば、あなたがこれを行うことがScalaのコンソールで:
scala> Json.parse("""{"as":20}""").as[AccountStatus]
java.lang.RuntimeException: Out of bound AccountStatus Value.
at scala.sys.package$.error(package.scala:27)
at AccountStatus$.fromInt(<console>:42)
at AccountStatusReads$$anonfun$reads$1.apply(<console>:27)
at AccountStatusReads$$anonfun$reads$1.apply(<console>:27)
at play.api.libs.json.JsResult$class.map(JsResult.scala:81)
at play.api.libs.json.JsSuccess.map(JsResult.scala:9)
at AccountStatusReads$.reads(<console>:27)
at play.api.libs.json.JsValue$class.as(JsValue.scala:65)
at play.api.libs.json.JsObject.as(JsValue.scala:166)
... 42 elided
を: import play.api.libs.json._
// import wherever account status is and the above reader
scala> Json.parse("""{"as":1}""").as[AccountStatus]
res0: AccountStatus = Active
このリーダーは、それはあなたのコードは、バインドされた番号のあなたを上与えるエラーを処理していない主な理由は、しかし完璧ではありません
これを処理するには、Reads
でエラーを処理します。私はあなたが望むなら、どのようにして表示することができますが、最初にFormat
の他の部分はWrites
です。 This traitは、それと逆のことを除いて、驚くことはなく読み込みに似ています。あなたのクラスはAccountStatus
で、JsValue
(JSON)を作成しています。したがって、writes
メソッドを実装するだけで済みます。これがそうのようにJSONにそのクラスをシリアル化するために使用することができ
implicit object AccountStatusWrites extends Writes[AccountStatus] {
def writes(as: AccountStatus): JsValue = {
JsObject(Seq("as" -> JsNumber(as.as)))
}
}
は次に:
今 scala> Json.toJson(Draft)
res4: play.api.libs.json.JsValue = {"as":0}
、これは実際に離れて行くためにあなたのエラーを取得するのに十分です。どうして? Json.format[Account]
はすべてあなたのためにやったことがあります!しかし、アカウント。これはケースクラスで22フィールド未満のため、これを行うことができます。 Account
のすべてのフィールドには、(Reads
とWrites
を使用して)JSONとの間で変換する方法があります。一部のフォーム(ステータスフィールド)にフォーマッタがないため、アカウントに自動的に作成されたフォーマットを表示できないというエラーメッセージが表示されました。
あなたはにこれを行う必要がありますか? AccountStatus
はケースクラスではないので、Json.format[AccountStatus]
を呼び出すことはできません。また、そのサブクラスは各オブジェクトであるため、ケースクラスではないため、unapply
メソッドは定義されていません。したがって、シリアライズとデシリアライズの方法をライブラリに説明する必要があります。
あなたがスカラーを初めて使ったと言われたので、私は暗黙のコンセプトがやや外国語であると想像します。コンパイラが暗黙のうちに必要なものを見つけることができないと不満を抱いているのを見て、何をすべきかを把握するために読んでみることをお勧めします。
ラウンド
ボーナスだから、あなたは本当にそれが自分の仕事やりたくないかもしれませんし、あなたがJson.format[AccountStatus]
を行うことができますので、それを行うことを避けるための方法があります。 Json.format
は、汚れた作業を行うためにapply
とunapply
メソッドを使用しています。スカラーでは、これらの2つのメソッドはケースクラスに対して自動的に定義されます。しかし、自分で定義することはできませんし、無料であなたに与えるすべてのものを手に入れることはできません。
だから、apply
とunapply
はタイプシグネチャに似ていますか?クラスごとに変更されますが、この場合はapply
はInt => AccountStatus
(intからAccountStatusに移行する関数)と一致する必要があります。だから、それがそうのように定義されています:
def apply(i: Int): AccountStatus = fromInt(i)
と適用を解除するには、この逆のに似ていますが、それはあなたが「ドン定義されたこれらの両方を持つ
def unapply(as: AccountStatus): Option[Int] = Option(as.as)
のように見えるので、それは、Option[Int]
を返す必要があります読み書きを定義する必要はなく、代わりに
// this is still inside the AccountStatus object { ... }
implicit val asFormat = Json.format[AccountStatus]
と呼ぶことができ、同様の方法で動作します。
.P.S。私は今日旅行していますが、これが意味をなさない場合はコメントを残しておいてください。後であなたに連絡しようとします。
暗黙の書き込みと読み取りを定義する必要があります書式)を入力してください。 – EdgeCaseBerg
@EdgeCaseBergどうすればいいですか?私は全く新しいスカラーです。 –
私はちょっと答えを投稿します。あなたのために何かを書きましょう。 – EdgeCaseBerg