玩:如何验证Json

时间:2014-01-08 23:07:05

标签: json scala playframework

我们假设我们有以下JSON代码段...

{
  "name": "Joe",
  "surname": "Cocker",
  "email": "joe.cocker@gmail.com"
}

...并想验证它:

object MyObject {

  def validate(jsValue: JsValue) = myReads.reads(jsValue)

  private val myReads: Reads[(String, String, String)] = (
    (__ \ 'name).read[String] ~
    (__ \ 'surname).read[String] ~
    (__ \ 'email).read(email)
  ) tupled
}

myReads.reads(jsValue)返回JsFailureJsSuccess(("Joe", "Cocker", "joe.cocker@gmail.com")) ...但如果成功,我不希望我的输入JSON转换为元组...我只想验证它并保持原样。这可能吗?

2 个答案:

答案 0 :(得分:4)

所以,听起来你想要Reads[JsValue]

object MyObject {

  def validate(jsValue: JsValue) = myReads.reads(jsValue)

  private val myReads: Reads[JsValue] =
    (__ \ 'name).read[String] ~>
    (__ \ 'surname).read[String] ~>
    (__ \ 'email).read(email) ~>
    implicitly[Reads[JsValue]]
}

为了解释这里发生了什么,~>运算符是andKeep的别名,这实际上意味着“如果以前的操作成功,请应用以下操作并保留其结果,但不是结果前一个“。它与~不同,后者是and的别名,并将两个结果与一个函数(在您的情况下,将其转换为元组)组合在一起。

and做的另一件事是合并失败。这可能对您有用,在这种情况下,您可能希望这样做:

object MyObject {

  def validate(jsValue: JsValue) = myReads.reads(jsValue)

  private val myReads: Reads[JsValue] = (
    (__ \ 'name).read[String] ~
    (__ \ 'surname).read[String] ~
    (__ \ 'email).read(email)
  ).tupled ~> implicitly[Reads[JsValue]]
}

这与上述不同,因为解析名称,姓氏和电子邮件的失败都被组合在一起,因此,例如,如果您只发送了name属性,则失败对象会说{{1并且surname丢失了,而在另一个解决方案中,它会在发现email丢失后立即停止解析,并将其作为消息返回。

答案 1 :(得分:1)

如果您不想定义实施James答案所需的额外读者,您可以通过简单的方式完成Chris在评论中的建议:

def validate(jsValue: JsValue) = myReads.reads(jsValue) map(_=>jsValue)