这是一个非常简单的JSON片段......
[
{
"email": "fred@flintstones.com",
"name": "fred",
"trash": "ignore"
}
]
...需要在处理之前进行验证:
val validateUser: Reads[JsValue] = (
(__ \ 'email).read(email) ~
(__ \ 'name).read[String]
).tupled ~> implicitly[Reads[JsValue]]
验证程序有效......但生成的JsValue
仍然包含trash
字段,应该过滤掉该字段:
scala> val user = Json.obj(
| "email" -> "fred@flintstones.com",
| "name" -> "fred", "trash" -> "ignore")
user: play.api.libs.json.JsObject = {"email":"fred@flintstones.com","name":"fred","trash":"ignore"}
scala> val userValidator: Reads[JsValue] = (
| (__ \ 'email).read(email) ~
| (__ \ 'name).read[String]).tupled ~> implicitly[Reads[JsValue]]
userValidator: play.api.libs.json.Reads[play.api.libs.json.JsValue] = play.api.libs.json.Reads$$anon$3$$anon$4@77d7654e
scala> userValidator.reads(user)
res0: play.api.libs.json.JsResult[play.api.libs.json.JsValue] = JsSuccess({"email":"fred@flintstones.com","name":"fred","trash":"ignore"},)
然后,我试图像这样修改验证器......
val validateUser: Reads[(String, String)] = (
(__ \ 'email).read(email) ~
(__ \ 'name).read[String]
).tupled
...这次生成的元组不再按预期包含trash
字段:
scala> val userValidator: Reads[(String,String)] = (
| (__ \ 'email).read(email) ~
| (__ \ 'name).read[String]).tupled
userValidator: play.api.libs.json.Reads[(String, String)] = play.api.libs.json.Reads$$anon$8@24ccd12b
scala> userValidator.reads(user)
res1: play.api.libs.json.JsResult[(String, String)] = JsSuccess((fred@flintstones.com,fred),)
现在问题是:如何在没有JsValue
字段的情况下让验证器返回trash
?为什么~> implicitly[Reads[JsValue]]
会保留它?
答案 0 :(得分:0)
根据我的理解,验证器的功能不是转换JSON,而是验证它是否具有某些字段,并且它们是预期的类型。
如果您想转换JSON以删除“垃圾”,您可以:
userValidator.reads(user).map(js => js - "trash")
或仅包含某些字段:
userValidator.reads(user).map(js => Json.obj("name" -> js \ "name", "email" -> js \ "email"))
你可能已经看过this文章了,但是它非常有用我还是把它包括在内。
答案 1 :(得分:0)
您的解析器验证每个输入并在成功时接受原始输入。
您的问题是关于JSON转换(在official documentation中描述)
您必须保留有效输入,如下所示:
val validateUser = (
(( __ \ 'email ).read(email) ~> ( __ \ 'email ).json.pickBranch) ~
((__ \ 'name).read[String] ~> ( __ \ 'name ).json.pickBranch)
) reduce
答案 2 :(得分:0)
Dan和Isammoc的解决方案都有效......但是看看Json文档,我认为正确的方法应该如下:
val emptyObj = __.json.put(Json.obj())
...
val validateUser = (
(( __ \ 'email).json.pickBranch(Reads.of[JsString] keepAnd Reads.email)) ~
(( __ \ 'name).json.pickBranch) ~
(( __ \ 'optional).json.pickBranch or emptyObj)
).reduce
正如您所看到的,我还添加了电子邮件验证并定义了emtpyObj
来模拟JsPath.readNullable
。我希望有所帮助。