4

我正在尝试使用 json4s 以 json 格式解析不同类型的事件。我编写了一些案例类来表示所有从基类继承的不同事件Event

  abstract class Event{ def EventType : String }
  case class StartSession(val EventType: String, val Platform: String) extends Event
  case class AdView(val EventType: String, val EventSubtype: String) extends Event

这是我用来解析StartSession事件的函数:

  def parser(json: String): Event = {
    val parsedJson = parse(json)
    val s = parsedJson.extract[StartSession]
    return s
  }

这个函数将正确解析一个像{"EventType":"StartSession","Platform":"Portal"}

我正在寻找一种方法来概括解析器函数,以便我可以使用它来解析所有类型的事件,Event然后对函数的返回值进行模式匹配。

4

1 回答 1

2

类型提示提供了问题的解决方案。如果你有一个多态类型,比如Event,类型提示(这里EventType)告诉 json4s 一个 json 对象应该被反序列化成哪个实际类型。

作为参考,请查看json4s 的 github 页面。有一个名为“序列化多态列表”的部分。

由于类型提示仅在反序列化时才需要,我们可以去掉EventType.Event

abstract class Event
case class StartSession(Platform: String) extends Event
case class AdView(EventSubtype: String) extends Event

我们需要将一个Formats实例带入extract. 实例告诉 json4s 如何进行反序列化。在我们的例子中,我们需要专门化typeHintFieldNametypeHints. 第一个是我们类型提示的键,在示例中是"EventType". 后者是从字符串值到类的映射。如果我们使用类名作为值,那么ShortTypeHints就可以了。否则,我们可以实现我们自己的、专门的TypeHints.

具体解决方案如下所示:

def main(args: Array[String]): Unit ={
  val json =
    s"""
       |[
       |  {
       |    "EventType": "StartSession",
       |    "Platform": "Portal"
       |  },
       |  {
       |    "EventType": "AdView",
       |    "EventSubtype": "SpecializedView"
       |  }
       |]
     """.stripMargin
  implicit val formats = new DefaultFormats {
    override val typeHintFieldName: String = "EventType"
    override val typeHints: TypeHints =
      ShortTypeHints(
        List(classOf[StartSession], classOf[AdView])
      )
  }
  val parsedJson = parse(json)
  val s = parsedJson.extract[List[Event]]
  println(s)
}
于 2014-11-11T03:41:53.000 回答