部分字段的 json4s 提取器(当我们关心保留原始 Json 时)

json4s extractor for partial fields (when we care to preserve the original Json)

解析 Json 字符串时,在某些情况下,我们只对解析字段的子集(我们知道我们需要的字段)感兴趣,而延迟其余部分的任何语义 parsing/mapping的领域。

例如我们想检查键值事件中的键以进行(比如)负载平衡,但在那个时间点我们没有足够的信息来完全解析这些值(我们假设一些应用程序更进一步会知道什么与值有关):

val json = """{ "key": {"a": true, "b": 123}, "value": [1,2,3,4] }"""

case class Key(a: Boolean, b: Int)
case class Event(key: Key, value: ???) // value can be any valid Json

import org.json4s._
import org.json4s.native.JsonMethods._

implicit val formats = DefaultFormats

val parsedJson = parse(json)

parsedJson.extract[Event]

问题是如何表示我们还不知道(或不关心)解析的字段?我们添加什么作为 value 的类型?

注意: 一种解决方案是将事件更改为 case class Event(key: Key)。这会起作用,但它会完全忽略我们理想情况下希望保留的值,以便我们可以将它正确地分派给另一个服务。 所以这个解决方案对我们不起作用。

parse() 将 JSON 解析为 json4s AST 和 returns JValue.

AFAIK 您不能部分解析 JSON,因为解析为 AST 包括 JSON 验证,为此您需要将整个 JSON 字符串解析为 AST 树。

但是您可以从 AST 中部分提取。这里有两个选择。

第一。将 value 字段设置为 JValue 以延迟提取。您可以稍后通过在此 JValue 实例上调用 extract() 来完成此操作。

case class Event(key: Key, value: JValue)

val event = parsedJson.extract[Event]
val value = event.value.extract[Seq[Int]]

第二。将 Event 拆分为两个 类 并分别提取它们。

case class EventKey(key: Key)
case class EventValue(value: Seq[Int])

val parsedJson = parse(json)
val eventKey = parsedJson.extract[EventKey]
val eventValue = parsedJson.extract[EventValue]