Scala Play 2.3框架Json递归验证

时间:2014-12-12 12:06:45

标签: json scala playframework playframework-2.0

我的json在字段重复中具有相同的结构。

case class RuleJson(`type`: String, attribute: Int, operator: Option[String], value: String, is_value_processed: String, aggregator: String, conditions: RuleJson)


object RuleJson  {  
  implicit val reads = Json.reads[RuleJson]
}

因此条件键将具有相同的RuleJson案例结构。 (虽然是可选的)

我得到“没有模型的隐式读取.RuleJson可用。”错误。

我的JSON是

{
    "type": "salesrule/rule_condition_combine",
    "attribute": null,
    "operator": null,
    "value": "1",
    "is_value_processed": null,
    "aggregator": "all",
    "conditions": [
        {
            "type": "salesrule/rule_condition_product_subselect",
            "attribute": "qty",
            "operator": "==",
            "value": "5",
            "is_value_processed": null,
            "aggregator": "all",
            "conditions": [
                {
                    "type": "salesrule/rule_condition_product",
                    "attribute": "quote_item_price",
                    "operator": "==",
                    "value": "200",
                    "is_value_processed": false
                }
            ]
        }
    ]
}

因此,如果你看到条件字段在重复,我如何在scala 2.3中验证这样的JSON?

1 个答案:

答案 0 :(得分:1)

这里的关键是更改您的案例类,使其实际匹配您想要读取的数据(例如,使可选值Option[String]等),然后使用lazyRead[T]函数读取值您目前正在构建Reads。这是一个适用于您的数据的案例类(根据需要进行了更改):

case class RuleJson(
  `type`: String,
  attribute: Option[String],
  operator: Option[String],
  value: String,
  isValueProcessed: Option[Boolean],
  aggregator: Option[String],
  conditions: Seq[RuleJson]
)

object RuleJson {
  implicit val reads: Reads[RuleJson] = (
    (__ \ "type").read[String] and
    (__ \ "attribute").readNullable[String] and
    (__ \ "operator").readNullable[String] and
    (__ \ "value").read[String] and
    (__ \ "is_value_processed").readNullable[Boolean] and
    (__ \ "aggregator").readNullable[String] and
    (__ \ "conditions").lazyReadNullable[Seq[RuleJson]](Reads.seq(RuleJson.reads))
      .map(opt => opt.toSeq.flatten)
  )(RuleJson.apply _)
}

这里有两点需要注意:

  • conditions被定义为Seq[RuleJson],但由于它在源JSON中可能根本不存在,因此它被读作可选值而空案例映射到空序列
  • 由于我们为递归结构定义了一个读者,我们使用lazyReadNullable作为条件列表,并将其显式引用给我们当前正在构建的Reads。如果我们不使用lazy...变量,则读取可能会因空指针错误而崩溃,因为它会引用尚未定义的内容(lazy变体基本上使用Scala按名称调用参数在需要之前不进行评估。)