Play:如何在反序列化JSON对象时处理可能的失败

时间:2014-01-03 22:31:30

标签: json scala playframework deserialization

下面是一个在Play控制器中对JSON进行序列化/反序列化的案例类:

case class User(
  id: Option[BSONObjectID],
  email: String,
  password: Password
)

object User {
  ...
  implicit val userReads: Reads[User] = (
    (__ \ '_id).readNullable[BSONObjectID] ~
    (__ \ 'email).read[String](email) ~
    (__ \ 'password).read(
      (
        (__ \ 'hashtext).read[String] ~
        (__ \ 'salt).readNullable[String]
    )(Password.apply(_: String, _: Option[String]).get))
  )(User.apply _)
}

上面的代码编译并正常工作......但我想知道如何在应用密码时处理可能的失败。如果您查看Password.scala,您会看到我将构造函数设为私有,并在随附对象中创建了一个apply方法,该方法返回Try ...但当然我不能认为它总是返回Success并只调用get。话虽如此,我应该调用getOrElse并抛出异常吗?

object User {
  ...
  implicit val userReads: Reads[User] = (
    ...
    (__ \ 'password).read(
      (
        (__ \ 'hashtext).read[String] ~
        (__ \ 'salt).readNullable[String]
    )(Password.apply(_: String, _: Option[String]).getOrElse{throw new Exception}))
  )(User.apply _)
}

或者在从JSON反序列化对象时是否有更好的选项来处理失败?

1 个答案:

答案 0 :(得分:3)

您应该使用JsResult,这与Try非常相似。它有两种子类型:JsSuccessJsError

val json = Json.parse("...")

json.validate[User] match {
  case JsSuccess(user, _) => println("Got a user: " + user)
  case JsError(errors)    => println("Errors! " + errors.mkString)
}

您可以在filter中使用Reads来检查条件:reference

“操纵JsResult [A]”下的一个例子是here