播放框架:验证JSON时将字符串转换为数字不起作用
给定以下JSON播放框架:验证JSON时将字符串转换为数字不起作用,json,scala,playframework,Json,Scala,Playframework,给定以下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
{
"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))
}
}
)
}
}
"ask":"428.00",
"bid":424.20
}
问题是只有最后一个节点(bid
)实际转换为数字。。。生成的JSON如下所示:
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))
}
}
)
}
}
"ask":"428.00",
"bid":424.20
}
我错过什么了吗
编辑
仅当JSON结构仅包含要转换为数字的字符串时,才使用和。。。然而,如果JSON结构已经包含数字字段,则不会。给定以下JSON[last
已经是数字]:
}
"ask":"428.00",
"bid":"424.20",
"last": 430.05
}
如果我像这样修改我的验证器[将~
替换为,然后
并删除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())))))
回顾一下,看起来你应该使用“和”,而不是“~”。参见“案例7”。我讨厌play json中所有的应用程序,因为当它不起作用时,实现是完全不透明的——至少对我来说是这样。我不是专家,但当我在玩json时遇到这种问题时,是因为我使用了一些组合成语,去掉了左边的部分——在本例中是“~”。查看文档,看看你是否应该使用其他方法。如果这是正确的,考虑把帖子改名为“……组合更新不工作……”,以便其他有相同问题的人更可能找到它。它部分地工作…如果Json结构只包含要转换为数字的字符串,那么它可以工作。。。但是,如果Json结构同时包含要转换的字符串和数字,那么它就不存在了-请参阅我更新的帖子。@j3d我不是专家,但我不知道你想用pickbranch做什么。pickbranch只提取一个JsPath+它的JsValue@j3d我知道它的作用,我不知道你想用它做什么。如果你根本不包括它,你会得到ask/bid/last作为数字,我认为这是你想要的。