Play Framework:在验证 JSON 时将字符串转换为数字不起作用
Play Framework: Converting strings to numbers while validating JSON does not work
鉴于以下 JSON...
{
"ask":"428.00",
"bid":"424.20"
}
...我需要将 ask
和 bid
的值转换为数字:
{
"ask": 428.00,
"bid": 424.20
}
正如已经讨论过的 ,我只需要像这样创建一个验证器:
def validate = (
((__ \ 'ask).json.update(toNumber)) ~
((__ \ 'bid).json.update(toNumber))
).reduce
private def toNumber(implicit reads: Reads[String]) = {
Reads[JsNumber](js =>
reads.reads(js).flatMap { value =>
parse[Double](value) match {
case Some(number) => JsSuccess(JsNumber(number))
case _ => JsError(ValidationError("error.number", value))
}
}
)
}
问题是只有最后一个节点 (bid
) 被实际转换为数字...结果 JSON 如下所示:
}
"ask":"428.00",
"bid":424.20
}
我是不是漏掉了什么?
编辑
仅当 JSON 结构仅包含要转换为数字的字符串时,使用 andThen
才有效...而如果 JSON 结构已包含数字字段,则不会。鉴于以下 JSON [last
已经是数字]:
}
"ask":"428.00",
"bid":"424.20",
"last": 430.05
}
如果我像这样修改我的验证器[将 ~
替换为 andThen
并删除 reduced
]...
def validate = (
((__ \ 'ask).json.update(toNumber)) andThen
((__ \ 'bid).json.update(toNumber)) andThen
((__ \ 'last).json.pickBranch(Reads.of[JsNumber]))
)
...然后在尝试验证上面的 JSON 时出现以下错误:
JsError(List((/bid/last,List(ValidationError(error.path.missing,WrappedArray())))))
查看 the docs,您似乎应该使用 "andThen",而不是“~”。参见 "Case 7"。
鉴于以下 JSON...
{
"ask":"428.00",
"bid":"424.20"
}
...我需要将 ask
和 bid
的值转换为数字:
{
"ask": 428.00,
"bid": 424.20
}
正如已经讨论过的
def validate = (
((__ \ 'ask).json.update(toNumber)) ~
((__ \ 'bid).json.update(toNumber))
).reduce
private def toNumber(implicit reads: Reads[String]) = {
Reads[JsNumber](js =>
reads.reads(js).flatMap { value =>
parse[Double](value) match {
case Some(number) => JsSuccess(JsNumber(number))
case _ => JsError(ValidationError("error.number", value))
}
}
)
}
问题是只有最后一个节点 (bid
) 被实际转换为数字...结果 JSON 如下所示:
}
"ask":"428.00",
"bid":424.20
}
我是不是漏掉了什么?
编辑
仅当 JSON 结构仅包含要转换为数字的字符串时,使用 andThen
才有效...而如果 JSON 结构已包含数字字段,则不会。鉴于以下 JSON [last
已经是数字]:
}
"ask":"428.00",
"bid":"424.20",
"last": 430.05
}
如果我像这样修改我的验证器[将 ~
替换为 andThen
并删除 reduced
]...
def validate = (
((__ \ 'ask).json.update(toNumber)) andThen
((__ \ 'bid).json.update(toNumber)) andThen
((__ \ 'last).json.pickBranch(Reads.of[JsNumber]))
)
...然后在尝试验证上面的 JSON 时出现以下错误:
JsError(List((/bid/last,List(ValidationError(error.path.missing,WrappedArray())))))
查看 the docs,您似乎应该使用 "andThen",而不是“~”。参见 "Case 7"。