给出以下JSON ..
{
"ask":"428.00",
"bid":"424.20"
}
...我需要将ask
和bid
的值转换为数字:
{
"ask": 428.00,
"bid": 424.20
}
为此,我创建了一个验证器,它读取字符串值并将其传递给方法toNumber
,方法def validate = (
((__ \ 'ask).json.pickBranch(Reads.of[JsString] <~ toNumber)) ~
((__ \ 'bid).json.pickBranch(Reads.of[JsString] <~ toNumber))
).reduce
private def toNumber(implicit reads: Reads[String]) = {
Reads[Double](js =>
reads.reads(js).flatMap { value =>
parse[Double](value) match {
case Some(number) => JsSuccess(number)
case _ => JsError(ValidationError("error.number", value))
}
}
)
}
验证并转换给定的字符串:
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))
}
}
)
}
上面的代码只验证值,但当然不会用转换后的数字替换原始字符串。在验证时如何将字符串值转换为数字?
修改
只是想分享Ben提供的解决方案:
{{1}}
答案 0 :(得分:1)
如果您使toNumber
成为Reads[JsNumber]
而不是Reads[Double]
(只需将number
包裹在JsNumber
中),那么您可以使用transform
与update
一起使用:
val transformer = (__ \ "ask").json.update(toNumber)
val json = Json.parse(""" { "ask" : "44" } """)
json.transorm(transformer) //JsSuccess({"ask":44.0},/ask)
val json = Json.parse(""" { "ask" : "foo" } """)
json.transorm(transformer) //JsError(List((/ask,List(ValidationError(error.number,WrappedArray(foo))))))
从某种意义上说,变形金刚是验证者。您可以使用transform
简单地转换值,而不是检查某些内容是否有效,然后对其进行转换,如果转换无效,则可以使用JsError
。详细了解transform
here。