【问题标题】:Scala Play 2.3 framework Json validate recursivelyScala Play 2.3 框架 Json 递归验证
【发布时间】:2015-02-11 03:30:16
【问题描述】:

我的 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 案例结构。 (虽然是可选的)

我收到“没有可用的 models.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
                }
            ]
        }
    ]
}

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

【问题讨论】:

标签: json scala playframework playframework-2.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 名称调用参数,而在需要之前进行评估。)

【讨论】:

    猜你喜欢
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 2014-07-29
    • 2019-01-11
    • 1970-01-01
    • 2017-02-03
    相关资源
    最近更新 更多