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
  }

この関数は、次のようなjsonを正しく解析します{"EventType":"StartSession","Platform":"Portal"}

Eventパーサー関数を一般化して、継承するすべてのタイプのイベントを解析し、関数の戻り値に対してパターン マッチングを実行できるようにする方法を探しています。

4

1 に答える 1

2

型ヒントは、問題の解決策を提供します。などのポリモーフィック型がある場合Event、型ヒント (ここではEventType) は、json オブジェクトを実際にどの型に逆シリアル化する必要があるかを json4s に伝えます。

参考までに、json4s の github ページをご覧ください「 Serializing polymorphic Lists 」というセクションがあります。

EventType型ヒントは逆シリアル化にのみ必要なので、 でフィールドを取り除くことができますEvent

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

Formatsインスタンスを のスコープに入れる必要がありますextract。インスタンスは、json4s に逆シリアル化の実行方法を指示します。私たちの場合、特殊化する必要がありますtypeHintFieldNametypeHints. 1 つ目は型ヒントのキーで、この例では"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 に答える