给定以下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))
}
}
)
}
上面的代码只验证该值,但当然不会用转换后的数字替换原始字符串。如何在验证时将字符串值转换为数字?
编辑
我只想分享Ben提供的解决方案:
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))
}
}
)
}
发布于 2015-04-17 12:21:37
如果您将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
这里的信息。
https://stackoverflow.com/questions/29695520
复制相似问题