播放Json:读取多个可选嵌套对象

播放Json:读取多个可选嵌套对象,json,scala,Json,Scala,我们有一个case类和Json组合符,类似于以下内容: case class Thing(param1: Option[BigDecimal], param2: Option[BigDecimal]) object Thing { implicit val writes: Writes[Thing] = Json.writes[Thing] implicit val reads: Reads[Thing] = ( (__ \ "parent"

我们有一个case类和Json组合符,类似于以下内容:

case class Thing(param1: Option[BigDecimal],
                 param2: Option[BigDecimal])

object Thing {
  implicit val writes: Writes[Thing] = Json.writes[Thing]

  implicit val reads: Reads[Thing] = (
    (__ \ "parent" \ "param1").readNullable[BigDecimal] and
    (__ \ "param2").readNullable[BigDecimal]
    )(Thing.apply _)
{ 
    "parent": {
        "param1: 1111.11
     },
    "param2": 2222.22
}
Json reads combinator for Thing将处理与以下内容匹配的传入Json:

case class Thing(param1: Option[BigDecimal],
                 param2: Option[BigDecimal])

object Thing {
  implicit val writes: Writes[Thing] = Json.writes[Thing]

  implicit val reads: Reads[Thing] = (
    (__ \ "parent" \ "param1").readNullable[BigDecimal] and
    (__ \ "param2").readNullable[BigDecimal]
    )(Thing.apply _)
{ 
    "parent": {
        "param1: 1111.11
     },
    "param2": 2222.22
}
param1
不存在时,标准的ReadNullable会按照我们的需要工作,从而创建
Thing(None,2222.22)
。但是,
parent
对象也是可选的,如果路径不存在,则像上面那样显式读取路径会导致路径缺失异常。我们需要它来生成一个
事件(None,2222.22)
,就像
param1
字段不存在一样

我们可以使用递归读取,如
(_\\“param1”)
来通过此异常,但理想情况下,我们希望保留显式路径,因为其他Json对象在同一级别上具有类似(如果不是相同的)字段


以这种方式使用Json组合符可以做到这一点吗?

您可以通过以下方式创建两个case类。
案例类事件(参数1:选项[BigDecimal])

case类ParentJson(parent:Option[Thing],param2:Option[BigDecimal])

您可以将
.readNullable[BigDecimal]
替换为
read(Reads.optionNoError[BigDecimal])
以将错误映射为无。

这种方法有两个问题。1) 我们仍然需要BigDecimal上的类型安全性,因此,尽管这会在出现错误时强制该字段为“None”,但如果
param1
不是一个大的小数,它将不会保留正确的JSException。2) 如果
parentObject
对象不存在,它仍然会返回路径缺失异常,而不是默认为无