本文介绍了从Play JSON API获得更好的错误消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Examples of the kind of error messages produced by 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等.

Is there a way to get better error messages out of this API? For example, the error messages for above two cases could look like No value found at JsPath \ "p", Value found at JsPath \ "k" \ "m" cannot be read as type String etc.

推荐答案

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

yes using JsValue.as[T] isn't robust in this case:

res0 \ "p"返回JsUndefined,然后将其应用于隐式Reads[String],并说嘿,这不是字符串"……是对的,但并非您所期望的;)

res0 \ "p" returns JsUndefined which is then applied to an implicit Reads[String] and it says "hey that's not a String"... That's true but not what you expect ;)

IMHO直接在JsPath上使用Reads的更好方法:

the better way IMHO uses Reads on JsPath directly:

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中第一个参数中缺少的路径.

Here you have a better message about missing-path.It even notifies the missing path in first param in JsError.

关于消息作为漂亮的字符串,您可以使用本地消息来映射密钥.顺便说一句,那些Json错误消息相对于Play中的其他错误消息(例如表单)还不是很标准化.我认为我们会在以后的Play版本中对其进行改进.

Concerning messages as nice strings, you can use a local message to map the key.BTW, those Json errors message are not quite standardized with respect to other error messages in Play such as Forms. I think we will improve it in a future release of Play.

最后,当您要将Json验证错误发送给客户端时,在JsError中有一个辅助功能与JsResult.recoverTotal一起使用

Finally, when you want to send Json validation errors to the client, there is a helper function in JsError to use with 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的实现并编写自己的实现.

This is just a raw version of this kind of function. If you need an another format, I advise to look at toFlatJson implementation and write your own.

玩得开心;)

这篇关于从Play JSON API获得更好的错误消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 06:14