16

Play JSON API 生成的错误消息类型示例:

scala> import play.api.libs.json._
import play.api.libs.json._

scala> Json.obj("k" -> Json.obj("m" -> 7))
res0: play.api.libs.json.JsObject = {"k":{"m":7}}

scala> (res0 \ "p").as[String]
play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(validate.error.expected.jsstring,WrappedArray())))))
    at play.api.libs.json.JsValue$$anonfun$2.apply(JsValue.scala:67)
    at play.api.libs.json.JsValue$$anonfun$2.apply(JsValue.scala:67)
    at play.api.libs.json.JsResult$class.fold(JsResult.scala:69)
    at play.api.libs.json.JsError.fold(JsResult.scala:10)
    at play.api.libs.json.JsValue$class.as(JsValue.scala:65)
    at play.api.libs.json.JsUndefined.as(JsValue.scala:98)
    at .<init>(<console>:12)
    at .<clinit>(<console>)
    at .<init>(<console>:7)
    // gazillion lines more

scala> (res0 \ "k" \ "m").as[String]
play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(validate.error.expected.jsstring,WrappedArray())))))
    at play.api.libs.json.JsValue$$anonfun$2.apply(JsValue.scala:67)
    at play.api.libs.json.JsValue$$anonfun$2.apply(JsValue.scala:67)
    at play.api.libs.json.JsResult$class.fold(JsResult.scala:69)
    at play.api.libs.json.JsError.fold(JsResult.scala:10)
    at play.api.libs.json.JsValue$class.as(JsValue.scala:65)
    at play.api.libs.json.JsNumber.as(JsValue.scala:108)
    at .<init>(<console>:12)
    at .<clinit>(<console>)
    at .<init>(<console>:7)
    // gazillion lines more

有没有办法从此 API 中获得更好的错误消息?例如,上述两种情况的错误消息可能如下No value found at JsPath \ "p"所示Value found at JsPath \ "k" \ "m" cannot be read as type String

4

1 回答 1

10

是的,在这种情况下使用JsValue.as[T]并不可靠:

res0 \ "p"返回JsUndefined然后将其应用于隐式Reads[String]并显示“嘿,这不是字符串”......这是真的,但不是你所期望的;)

Reads恕我直言,直接使用的更好方式JsPath

scala> ((__ \ "p").read[String]).reads(res0)
res7: play.api.libs.json.JsResult[String] = JsError(List((/p,List(ValidationError(validate.error.missing-path,WrappedArray())))))

scala> ((__ \ "k" \ "m").read[String]).reads(res0)
res8: play.api.libs.json.JsResult[String] = JsError(List((/k/m,List(ValidationError(validate.error.expected.jsstring,WrappedArray())))))

在这里,您可以获得有关缺失路径的更好消息。它甚至会在 JsError 的第一个参数中通知丢失的路径。

关于作为漂亮字符串的消息,您可以使用本地消息来映射键。顺便说一句,这些 Json 错误消息相对于 Play 中的其他错误消息(例如 Forms)并不完全标准化。我认为我们会在 Play 的未来版本中改进它。

最后,当您想向客户端发送 Json 验证错误时,JsError可以使用一个辅助函数JsResult.recoverTotal

scala> ((__ \ "k" \ "m").read[String]).reads(res0).recoverTotal( e => JsError.toFlatJson(e) )
res11: java.io.Serializable = {"obj.k.m":[{"msg":"validate.error.expected.jsstring","args":[]}]}

这只是这种功能的原始版本。如果您需要另一种格式,我建议您查看 toFlatJson 实现并编写自己的。

玩得开心 ;)

于 2013-06-20T12:49:26.227 回答