Play Framework: How to convert strings to numbers while validating JSON

匿名 (未验证) 提交于 2019-12-03 08:59:04

问题:

Given the following JSON..

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

... I need to convert the values of ask and bid to numbers:

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

To do that, I've created a validator that reads the string value and passes it to method toNumber, which validates and converts the given string:

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

The code above only validates the value but of course does not replace the original string with the converted number. How do I convert string values to numbers while validating?

EDIT

Just wanted to share the solution provided by 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))       }     }   ) } 

回答1:

If you make toNumber a Reads[JsNumber] instead of a Reads[Double] (simply by wrapping number in JsNumber), then you can use transform together with 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)))))) 

In a sense, transformers are validators. Instead of checking if something is valid, and then transforming it, you can use transform to simply transform the value, and get a JsError if the transformation is invalid. Read more about transform here.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!