在解析Json字符串时,有些情况下我们只想解析字段的一部分(我们知道需要的字段)并延迟其余字段的任何语义解析/映射。
E.g。我们希望检查键值事件中的键(比如说)负载均衡,但是在那个时候我们没有足够的信息来完全解析值(我们假设一些应用程序将在未来发展知道如何处理这些价值观点:
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)
。这将有效,但它将完全忽略我们理想的保留值,以便我们可以将其正确地发送到另一个服务。 因此,此解决方案对我们无效。
答案 0 :(得分:1)
parse()
将JSON解析为json4s AST并返回JValue
。
AFAIK您无法部分解析JSON,因为解析为AST包含JSON验证,因此您需要将整个JSON字符串解析为AST树。
但是你可以从AST中部分提取。这里有两个选择。
<强>第一即可。将value
字段设为JValue
以推迟提取。您可以稍后在此extract()
个实例上调用JValue
来执行此操作。
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]