将 Play 框架与 Scala 结合使用,如何使 Json 验证消息人性化?

Using Play framework with Scala, how can I humanize a Json Validation message?

当前有以下隐式读取值:

 implicit val abridgedProductReads: Reads[Product] =
(
    (JsPath \ "ean"        ).read[Long]   and
    (JsPath \ "name"       ).read[String](minLength[String](5)) and
    (JsPath \ "description").read[Option[String]]
  )(abridgedProductApply _)

以及以下用于编写验证错误的内容:

      implicit val JsPathWrites          = Writes[JsPath]         (path  => JsString(path.toString))
  implicit val ValidationErrorWrites = Writes[ValidationError](error => JsString(error.message))

  implicit val jsonValidateErrorWrites =
  (
      (JsPath \ "path"  ).write[JsPath] and
      (JsPath \ "errors").write[Seq[ValidationError]]
      tupled
  )

当我提交一个太短的名称时,我收到一条 Json 消息,例如:

[{"path":"/name","errors":"error.minLength"}]

我目前正在使用以下 CoffeeScript:

extractError = (message) ->
    errorObj = $.parseJSON(message)
    error = "Unextracted"
    try error = errorObj[0].path + " has error: " + errorObj[0].errors
    catch e then error = message
    error

向用户呈现为:

/name has error: error.minLength

但我想对其进行自定义以使其更友好(例如 "Name must be at least five characters"),而无需在客户端假设这将是唯一出现的错误。以后我可能会增加更多的字段和更多的验证规则。

理想情况下,我希望 Play 为用户友好的错误提供服务,而不是编写 CoffeeScript 来尝试解释它收到的错误。

最好的方法是什么?

您似乎想要定义自定义验证约束。

def customMinLength[M]( m: Int )
                      (
                       implicit reads: Reads[M],
                       p: M => scala.collection.TraversableLike[_, M]
                      ) =
  filterNot[M]( ValidationError(
    "Well.... you see... I want to tell you in a very humanized way that your string is shorter than what it should be. For your information its length should be at least " + m.toString,
    m
  ) )( _.size < m )

implicit val abridgedProductReads: Reads[Product] = (
  (JsPath \ "ean"        ).read[Long]   and
  (JsPath \ "name"       ).read[String](customMinLength[String](5)) and
  (JsPath \ "description").read[Option[String]]
)(abridgedProductApply _)