以下验证程序检查传入的JSON是否正确:
val validateAccount = (
((__ \ 'id).json.pickBranch(Reads.of[JsString] <~ objectId) orEmpty) ~
((__ \ 'openingTime).json.pickBranch(Reads.of[JsString] <~ utcDateTime) orEmpty) ~
((__ \ 'roles).json.pickBranch(Reads.of[JsArray]) orEmpty) ~
((__ \ 'permissions).json.pickBranch(Reads.of[JsArray]) orEmpty)
).reduce
roles
以及permissions
应该是一个整数数组...那么如何验证JsArray
是否有效地包装整数数组?
修改
根据特拉维斯的要求,下面是orEmpty
...
implicit class ReadsExtensions(val reads: Reads[JsObject]) extends AnyVal {
import play.api.libs.functional.syntax._
/**
* Returns either a successful `Reads` or an empty object.
* @return Either a successful `Reads` or an empty object.
*/
def orEmpty = reads | __.json.put(Json.obj())
/**
* Returns either a successful `Reads` or an empty object if allowed.
*
* @param b A Boolean value indicating whether or not an empty
* object is allowed when a `Reads` fails.
* @return Either a successful `Reads` or an empty object if `b`
* is `true`.
*/
def orEmptyIf(b: Boolean) = if (b) orEmpty else reads
}
...这里有一个要验证的JSON示例:
{
"id": "12d54f56cc456a2967e34a21",
"openingTime": "2014-08-12T21:10:24Z",
"roles": [ 0, 1, 3, 4],
"permissions": [ 0, 1, 2 ,3 ]
}
答案 0 :(得分:2)
您可以使用此帮助程序。它的写法与play.api.libs.json.Reads.list[A](implicit reads: Reads[A]): Reads[List[A]]
类似,但返回JsArray
而不是List
。
def jsArray[A <: JsValue](implicit r: Reads[A]): Reads[JsArray] = new Reads[JsArray] {
def reads(json: JsValue) = json.validate[JsArray].flatMap { case JsArray(seq) =>
type Errors = Seq[(JsPath, Seq[ValidationError])]
def locate(e: Errors, idx: Int) = e.map { case (p, valerr) => JsPath(idx) ++ p -> valerr }
seq.zipWithIndex.foldLeft(Right(Vector.empty): Either[Errors, Vector[JsValue]]) {
case (eith, (jsVal, idx)) => (eith, jsVal.validate[A](r)) match {
case (Right(vs), JsSuccess(v, _)) => Right(vs :+ v)
case (Right(_), JsError(e)) => Left(locate(e, idx))
case (Left(e), _: JsSuccess[_]) => Left(e)
case (Left(e1), JsError(e2)) => Left(e1 ++ locate(e2, idx))
}
}.fold(JsError.apply, { res =>
JsSuccess(JsArray(res.toSeq))
})
}
}
然后你可以使用它
val validateAccount = (
((__ \ 'id).json.pickBranch(Reads.of[JsString] <~ objectId) orEmpty) ~
((__ \ 'openingTime).json.pickBranch(Reads.of[JsString] <~ utcDateTime) orEmpty) ~
((__ \ 'roles).json.pickBranch(jsArray(Reads.of[JsNumber])) orEmpty) ~
((__ \ 'permissions).json.pickBranch(jsArray(Reads.of[JsNumber])) orEmpty)
).reduce