4

Play 2.1.1 では、Json の読み取りと書き込みの仕組みがオーバーホールされました。

基本的に、次のようなラッパー オブジェクトがあります。

case class CombinedUser(user: SocialUser, userdetails: UserDetails)

ご覧のとおり、json にシリアライズおよびデシリアライズしたい 2 つのクラスが含まれています。

しかし、新しいデザインを使用してサブクラスのフィールドを取得および設定する方法がわかりません。

例えば

implicit val combinedUser2Reads = (
  (__ \ "email").read[String] and
  (__ \ "providerid").read[String] and
  (__ \ "firstname").read[String] and
  (__ \ "lastname").read[String] and
  (__ \ "fullname").read[String] and
  (__ \ "avatarurl").read[String] and
  (__ \ "address1").read[String] and
  (__ \ "address2").read[String] and
  (__ \ "address3").read[String] and
  (__ \ "city").read[String] and
  (__ \ "country").read[String] and
  (__ \ "phone").read[String] and
  (__ \ "publickey").as[String]
)(CombinedUser2.apply _)

ほとんどのサブクラス フィールド、すべての文字列を含む json blob が必要です。

適用するものを使用しているため、マッピングの前にサブクラスを作成する方法がわかりません。

どんな助けや指導も大歓迎です。

ありがとう

トム

4

1 に答える 1

8

次の方法で実行できます。

case class SocialUser(firstName: String, lastName: String)
case class UserDetails(avatarUrl: String, phone: String)
case class CombinedUser(user: SocialUser, userDetails: UserDetails)  
implicit val combinedUserReads: Reads[CombinedUser] = (
  (__ \ "user").read((
    (__ \ "firstName").read[String] and
    (__ \ "lastName").read[String]
  )(SocialUser)) and
  (__ \ "userDetails").read((
    (__ \ "avatarUrl").read[String] and
    (__ \ "phone").read[String]
  )(UserDetails))
)(CombinedUser)

ただし、分離して作成することをお勧めしますReads

implicit val socialUserReads = (
  (__ \ "firstName").read[String] and
  (__ \ "lastName").read[String]
)(SocialUser)    
implicit val userDetailsReads = (
  (__ \ "avatarUrl").read[String] and
  (__ \ "phone").read[String]
)(UserDetails)
implicit val combinedUserReads: Reads[CombinedUser] = (
  (__ \ "user").read[SocialUser] and
  (__ \ "userDetails").read[UserDetails]
)(CombinedUser)

編集:単純なケースクラスの場合、次のことが可能です

implicit val socialUserReads = Json.format[SocialUser]
implicit val userDetailsReads = Json.format[UserDetails]
implicit val combinedUserReads = Json.format[CombinedUser]

ここでは、JSON 読み取りなどの非常に包括的な紹介を行います。

部分オブジェクトはどうですか?コンストラクターのすべてのフィールドに入力したくない場合は、空を渡すか、コンストラクターなどをオーバーロードできますか?

使用Option:

case class CombinedUser(user: SocialUser, userDetails: Option[UserDetails])
//reads
implicit val combinedUserReads: Reads[CombinedUser] = (
  (__ \ "user").read[SocialUser] and
  (__ \ "userDetails").readOpt[UserDetails]
)(CombinedUser)
//writes
implicit val combinedUserWrites: Writes[CombinedUser] = (
  //socialUserWrites and userDetailsWrites must be in scope
  (__ \ "user").write[SocialUser] and
  (__ \ "userDetails").write[Option[UserDetails]]
)(unlift(CombinedUser.unapply))

val json = Json.obj(
  "user" -> Json.obj(
    "firstName" -> "Homer",
    "lastName" -> "Simpson"
  )
)
Json.fromJson[CombinedUser](json)
//JsSuccess(CombinedUser(SocialUser(Homer,Simpson),None),)
于 2013-04-15T18:10:55.170 に答える