我有一个包含一些字段的 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