给出以下JSON ......
{
"nickname": "mj",
"firstname": "Mike",
"lastName": "Jordan",
"trash": "ignore"
}
...我需要解析并验证它以便
nickname
,firstName
和lastName
之外的任何字段都会被过滤掉 - 在上面的示例中,trash
必须删除nickname
(可选)必须至少包含3个字符以下是我的代码:
import play.api.libs.json._
import play.api.libs.functional.syntax._
def orEmpty = reads | __.json.put(Json.obj())
val js = Json.parse("""{ "nickname": "mj", "firstname": "Mike", "lastName": "Jordan" }""")
val validateUser = (
((__ \ 'nickname).json.pickBranch(Reads.of[JsString] <~ Reads.minLength[String](3)) orEmpty) ~
((__ \ 'firstName).json.pickBranch) ~
((__ \ 'lastName).json.pickBranch)
)
validateUser.reads(js).fold(
valid = { validated => JsSuccess(js) },
invalid => { errors => JsError(errors) }
)
问题是,如果nickname
无效,因为短于3个字符,orEmpty
适用,并且不会报告任何错误。我需要的是保持nickname
可选(这就是我定义orEmpty
的原因),但是当定义时,当且仅当nickanme
通过Reads.minLength
时,验证才会成功检查。
答案 0 :(得分:2)
假设Play Framework 2.4.x.我认为在2.3.x中阅读可空字段有点不同但是它的想法是一样的。
如果您认为JSON验证器和变换器实际上只是Reads[T <: JsValue]
,那么理由更容易。
总的来说,您需要考虑的是nickname
字段实际上是可选的,您需要表示它。基本上,您要找的是将nullableReads
与Reads.minLength
一起撰写,将昵称读作Option[String]
。
因此,您可以将要验证的结构表示为:
case class ToValidate(nickname: Option[String], firstname: String, lastname: String)
并定义你是读者:
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
implicit val toValidateReads: Reads[ToValidate] = (
(__ \ "nickname").readNullable[String](minLength(3)) ~
(__ \ "firstname").read[String] ~
(__ \ "lastname").read[String]
)(ToValidate.apply _)
然后你可以改变你的意见:
val js = Json.parse("""{ "nickname": "mj", "firstname": "Mike", "lastname": "Jordan" }""")
val v = js.validate[ToValidate]
println(v) // JsError(List((/nickname,List(ValidationError(List(error.minLength),WrappedArray(3))))))