【问题标题】:json4s extractor for partial fields (when we care to preserve the original Json)部分字段的 json4s 提取器(当我们关心保留原始 Json 时)
【发布时间】:2017-01-18 01:19:06
【问题描述】:

在解析 Json 字符串时,在某些情况下,我们只想解析字段的子集(我们知道我们需要的字段)并延迟其余字段的任何语义解析/映射。

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

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)。这会起作用,但它会完全忽略该值,我们理想地希望保留它,以便我们可以将它正确地分派给另一个服务。 所以这个解决方案对我们不起作用。

【问题讨论】:

    标签: scala json4s


    【解决方案1】:

    parse() 将 JSON 解析为 json4s AST 并返回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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多