无法为JSON创建隐式读取

时间:2018-04-25 20:09:33

标签: scala playframework-2.6

我的服务器代码将收到以下JSON

{
    "signin-info":{
        "email" : "someemail",
        "password": "password"
    }
}

我创建了以下2个案例类来表示这个结构。

case class UserSigninInfo(
  email:String,
  password:String
)
case class UserSignin(
  signinInfo: UserSigninInfo
)

要阅读JSON,我创建了以下2 Reads

  implicit val userSigninInfoReads:Reads[UserSigninInfo] = (
    (JsPath \ "email").read[String] and
    (JsPath \ "password").read[String]
  )(UserSigninInfo.apply _)

  implicit val userSigninReads:Reads[UserSignin] = (
    (JsPath \ "signin-info").read[UserSigninInfo]
  )(UserSignin.apply _)

但对于userSigninReads,我收到以下编译错误。我做错了什么?

overloaded method value read with alternatives:
[error]   (t: models.UserSigninInfo)play.api.libs.json.Reads[models.UserSigninInfo] <and>
[error]   (implicit r: play.api.libs.json.Reads[models.UserSigninInfo])play.api.libs.json.Reads[models.UserSigninInfo]
[error]  cannot be applied to (models.UserSigninInfo => models.UserSignin)
[error]     (JsPath \ "signin-info").read[UserSigninInfo]
[error]                                 `

1 个答案:

答案 0 :(得分:1)

构建主对象读取的解决方案是:

implicit val userSigninReads : Reads[UserSignin] =
  (JsPath \ "signin-info").read[UserSigninInfo].map(UserSignin(_))

这是因为它只有一个字段。

你的建筑是真实的:

((JsPath \ "signin-info").read[UserSigninInfo])(UserSignin.apply _)

只是

(JsPath \ "signin-info").read[UserSigninInfo](UserSignin.apply _)

因为它只是添加了额外的()

read方法确实有两种选择:

def read[T](t: T) = Reads.pure(t)
def read[T](implicit r: Reads[T]): Reads[T] = Reads.at[T](this)(r)

它需要隐式读取或显式值,但是您传递的是函数,这就是编译器抱怨的原因。

将多个字段与and组合使用时,会创建不同的对象,例如FunctionalBuilder[M]#CanBuild2[A, B]代表2个元素,并且apply方法构建最终的Reads实例。

由于您只有一个对象,因此您可以通过从所需路径中读取Reads来创建UserSigninInfo,并将结果放入UserSignin map