web-dev-qa-db-ja.com

ケースクラスにフィールドが1つしかない場合に、jsonをケースクラスに変換する方法

プレイ2.1では、読み取りはJsonをオブジェクトにマーシャルするために使用されます。しかし、ケースクラスにフィールドが1つしかない場合、どうすればこれを行うことができますか。 1つのフィールド 'および'が使用されていないため、より多くのフィールドで機能するイデオムは機能しません。したがって、FunctionBuilderを取得できません。

次のコードは、タイプの不一致を示しています。どうすればこれを修正できますか?

case class Data(stamm: Seq[String])


implicit val dataReads  = (
  (__ \ "stamm").read(Reads.list[String])
)(Data)
35
nebenmir

Jsonコンビネータは、単一フィールドのケースクラスでは機能しません。

Pascal(このAPIの作成者)はこの状況をここで説明しています https://groups.google.com/forum/?fromgroups=#!starred/play-framework/hGrveOkbJ6

このように機能するいくつかの回避策があります:

case class A(value: List[Int])
val areads = (__ \ 'value).read[List[Int]].map{ l => A(l) } // covariant map
29
Julien Lafont

Julienが答えたように、これを使用して単一フィールドのケースクラスを読み取ることができます。

case class Person(name: String)

val personReads: Reads[Person] = 
  (__ \ "name").read[String].map { name => Person(name) }

あなたが書きたいのであれば、単なる補足です:

val personWrites: Writes[Person] = 
  (__ \ "name").write[String].contramap { (person: Person) => person.name }

またはフォーマット(読み取りと書き込み):

val personFormat: Format[Person] = 
  (__ \ "name").format[String].inmap(name => Person(name), (person: Person) => person.name)

書き込みとフォーマットの場合、これをインポートする必要があります。

import play.api.libs.functional.syntax._
47
yokomizor

@yokomizorの回答に基づいて、Formatterを作成する最も簡単な解決策を見つけました。

case class Person(name: String)
val personFormatter: Format[Person] =
  (__ \ "full_name").format[String].inmap(Person.apply, unlift(Person.unapply))
8
Zoltán

受け入れられているものよりもさらに簡単な解決策:

case class A(value: String)
val reads = (__ \ "key").read[String].map(A.apply)
1
mjoliver