【问题标题】:Play Framework: How to convert strings to numbers while validating JSONPlay Framework:如何在验证 JSON 时将字符串转换为数字
【发布时间】:2015-04-17 09:34:56
【问题描述】:

鉴于以下 JSON..

{
    "ask":"428.00",
    "bid":"424.20"
}

...我需要将askbid的值转换为数字:

{
    "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))
      }
    }
  )
}

【问题讨论】:

  • 有必要一步到位吗? (你想要Try/Either 作为结果吗?我认为验证的结果不适合这个任务。)
  • ...如果我可以验证字符串实际上包含数字...然后转换整个 JSON...

标签: json scala playframework


【解决方案1】:

如果您将toNumber 设为Reads[JsNumber] 而不是Reads[Double](只需将number 包装在JsNumber 中),那么您可以将transformupdate 一起使用:

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,而不是检查某些内容是否有效,然后对其进行转换。阅读更多关于transformhere的信息。

【讨论】:

  • 非常感谢!我已经用你的解决方案更新了我的帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
相关资源
最近更新 更多