【问题标题】:Scala play json combinators for validating equalityScala 使用 json 组合器来验证相等性
【发布时间】:2014-01-09 14:49:01
【问题描述】:

我正在使用 play 2.2.0 读取来验证我的应用程序中的传入请求。

我正在尝试使用 json API 实现一个非常简单的东西。 我有一个这样的json:

{
  "field1": "some value",
  "field2": "some another value"
}

我已经有 Reads 来检查其他东西,比如最小长度

case class SomeObject(field1: String, field2: String)
implicit val someObjectReads = (
  (__ \ "field1").read(minLength[String](3)) ~
  (__ \ "field2").read(minLength[String](3))
)(SomeObject)

我想创建一个解析器组合器,它将匹配两个字段的值,如果值相等则返回JsSuccess,否则返回JsError,并将其与现有的Reads 组合。

我怎样才能做到这一点?

更新:澄清问题并更改代码。

【问题讨论】:

  • 恕我直言,这种验证应该由 API 客户端在将数据发送到 API 之前完成。
  • @IonuțG.Stan 是的,你是对的(客户端确实如此),但我想为此实现客户端和服务器端验证。
  • 是的,我理解,但如果您的 API 将被 3rd 方开发人员使用,您不能强制他们实际向用户显示“确认密码”字段。他们也可以使用单个输入字段中的值来填充password 和passwordConfirm。无论如何,这显然是你最终的选择。我只是想对这个问题提出不同的看法。
  • @IonuțG.Stan 嗯,这实际上是一个好点。我想我将来会从服务器中删除这个验证(api 尚未公开,所以它是安全的)。不过,我很想看到解析器组合器的示例,因为我想学习如何在将来编写这样的东西。
  • Reads 是一元的,flatMap 和 verifying 的某种组合应该相对简单。

标签: json scala playframework playframework-2.0


【解决方案1】:

您可以使用filter 对解析后的值进行进一步验证:

import play.api.data.validation._
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._

case class SomeObject(field1: String, field2: String)
implicit val someObjectReads = (
  (__ \ "field1").read(minLength[String](3)) ~
  (__ \ "field2").read(minLength[String](3))
)(SomeObject).filter(
  ValidationError("field1 and field2 must be equal")
) { someObject =>
  someObject.field1 == someObject.field2
}

如果您希望针对每个字段列出错误消息,则必须使用flatMap,例如:

implicit val someObjectReads = (
  (__ \ "field1").read(minLength[String](3)) ~
  (__ \ "field2").read(minLength[String](3))
)(SomeObject).flatMap { someObject =>
  Reads { _ =>
    if (someObject.field1 == someObject.field2) {
      JsSuccess(someObject)
    } else {
      JsError(Seq(
        JsPath("field1") -> Seq(ValidationError("field1 and field2 must be equal")),
        JsPath("field2") -> Seq(ValidationError("field1 and field2 must be equal"))
      ))
    }
  }
}

【讨论】:

  • 詹姆斯,非常感谢您的回答!您能否详细说明验证错误类型消息的格式?我想以类似 { "field1": "field1 and field2 must be equal", "field2": "field1 and field2 must be equal" } 的格式获取错误,而您的示例给出了类似 List(( ,List(field1 和 field2 必须相等))).
  • ValidationError 只是一个消息键和一些参数,在上面我没有费心使用消息键,但你可以说 ValidationError("validation.equals, "field1", "field2 "),并在您的消息文件中定义“validation.equals={0} 和 {1} 必须相等”。
  • ValidationError 已弃用,应使用 JsibValidationError。但非常好的答案!
猜你喜欢
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多