以下验证器检查传入的 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
有效地包装了一个整数数组?
编辑
根据 Travis 的要求,下面是 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 ]
}
最佳答案
您可以使用这个助手。其写法与play.api.libs.json.Reads.list[A](隐式读取: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
关于json - Play &Json : How to validate an array of integers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25291784/