检查对象是否在 json4s/lift-json 中具有字段



我有一个包含一些字段的 json,我想检查其中一些是否存在。我正在提取值并针对 JNothing 对其进行测试,但它太冗长了:

val json: JValue = ...
val jsonIsType1 = (json  "field1") != JNothing && (json  "field2") != JNothing

有没有更紧凑的方法来使用 json4s/lift-json 检查 json 对象中是否存在字段?理想情况下是这样的:

val jsonIsType1 = json.has("field1") && json.has("field2")

JValue 没有 'has' 运算符,但 Scala 隐式的强大功能允许你添加该功能而不会有太多麻烦。

下面是一个示例:

implicit class JValueExtended(value: JValue) {
  def has(childString: String): Boolean = {
    (value  childString) != JNothing
  }
}

使用示例:

scala> val json = Json.parse("""{"field1": "ok", "field2": "not ok"}""")
scala> json.has("field1")
res10: Boolean = true

您还可以在 a 中组合多个读取/验证步骤以进行理解。下面是两个函数,一个返回Option[_],另一个返回Boolean。第一个还允许处理数据,而后者只进行验证。

import org.json4s.jackson.JsonMethods._
val text =
  """
    |{
    |  "foo": "bar",
    |  "baz": "fnord",
    |  "qux": true
    |}
  """.stripMargin
val json = parse(text)
def readFoo(x: JValue): Option[(String, String, Boolean)] = for {
  JObject(_) <- x.toOption
  JString(foo) <- (x  "foo").toOption
  JString(baz) <- (x  "baz").toOption
  JBool(qux) <- (x  "qux").toOption
  if (qux == true)
} yield (foo, baz, qux)
def validateOnly(x: JValue): Boolean = (for {
  JObject(_) <- x.toOption
  JString(foo) <- (x  "foo").toOption
  JString(baz) <- (x  "baz").toOption
  JBool(qux) <- (x  "qux").toOption
  if (qux == true)
} yield true) getOrElse false
println(readFoo(json))            // Some((bar,fnord,true))
println(readFoo(json).isDefined)  // true
println(validateOnly(json))       // true

相关内容

  • 没有找到相关文章

最新更新