Play Framework:在验证JSON时将字符串转换为数字不起作用

时间:2015-04-26 13:13:28

标签: json scala playframework

给出以下JSON ......

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

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

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

正如已经讨论过的here,我只需要创建一个这样的验证器:

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())))))

1 个答案:

答案 0 :(得分:1)

回顾the docs,看起来你应该使用"然后"而不是"〜"。见"案例7"。