如何在 scala play 框架中解析 json 的数组?

How to parse an array of json in scala play framework?

我有一个像这样的 json 对象数组

[
  {
    "events": [
      {
        "type": "message",
        "attributes": [
          {
            "key": "action",
            "value": "withdraw_reward"
          },
          {
            "key": "sender",
            "value": "bob"
          },
          {
            "key": "module",
            "value": "distribution"
          },
          {
            "key": "sender",
            "value": "bob"
          }
        ]
      },
      {
        "type": "credit",
        "attributes": [
          {
            "key": "recipient",
            "value": "ross"
          },
          {
            "key": "sender",
            "value": "bob"
          },
          {
            "key": "amount",
            "value": "100"
          }
        ]
      },
      {
        "type": "rewards",
        "attributes": [
          {
            "key": "amount",
            "value": "100"
          },
          {
            "key": "validator",
            "value": "sarah"
          }
        ]
      }
    ]
  },
  {
    "events": [
      {
        "type": "message",
        "attributes": [
          {
            "key": "action",
            "value": "withdraw_reward"
          },
          {
            "key": "sender",
            "value": "bob"
          },
          {
            "key": "module",
            "value": "distribution"
          },
          {
            "key": "sender",
            "value": "bob"
          }
        ]
      },
      {
        "type": "credit",
        "attributes": [
          {
            "key": "recipient",
            "value": "ross"
          },
          {
            "key": "sender",
            "value": "bob"
          },
          {
            "key": "amount",
            "value": "100"
          }
        ]
      },
      {
        "type": "rewards",
        "attributes": [
          {
            "key": "amount",
            "value": "200"
          },
          {
            "key": "validator",
            "value": "Ryan"
          }
        ]
      }
    ]
  }
]

如何遍历类型,检查 type 是否等于 rewards 然后遍历 attributes 并验证 validator 是否等于 sarah 并获取键 amountvalue? scala 和 play 框架很新。任何帮助都会很棒。谢谢

您可以将 JSON 解析为 case 类 的结构以便于处理,然后像这样提取所需的字段:

val json = 
"""[
 {"events":[
            {
              "type":"message","attributes":[
                   {"key":"action","value":"withdraw_reward"}, 
                   {"key":"sender","value":"bob"}, 
                   {"key":"module","value":"distribution"}, 
                   {"key":"sender","value":"bob"}
            ]},
           {
             "type":"credit","attributes":[
                  {"key":"recipient","value":"ross"},
                  {"key":"sender","value":"bob"},
                  {"key":"amount","value":"100"}
           ]},
           {
             "type":"rewards","attributes":[
                  {"key":"amount","value":"100"}, 
                  {"key":"validator","value":"sara"}
           ]}
        ]
 },
   {"events":[
            {
              "type":"message","attributes":[
                        {"key":"action","value":"withdraw_reward"}, 
                   {"key":"sender","value":"bob"}, 
                   {"key":"module","value":"distribution"}, 
                   {"key":"sender","value":"bob"}
            ]},
           {
             "type":"credit","attributes":[
                  {"key":"recipient","value":"ross"},
                  {"key":"sender","value":"bob"},
                  {"key":"amount","value":"100"}
           ]},
           {
             "type":"rewards","attributes":[
                  {"key":"amount","value":"200"}, 
                  {"key":"validator","value":"Ryan"}
           ]}
        ]
 }
]
"""
case class EventWrapper(events: Seq[Event])
case class KeyValue(key: String, value: String)
case class Event(`type`: String, attributes: Seq[KeyValue])
 import play.api.libs.json._

    implicit val kvReads: Reads[KeyValue] = Json.reads[KeyValue]
    implicit val eventReads: Reads[Event] = Json.reads[Event]
    implicit val eventWrapperReads: Reads[EventWrapper] = Json.reads[EventWrapper]

    val rewardAmountsValidatedBySara = Json
      .parse(json)
      .as[Seq[EventWrapper]]
      .flatMap {
        _.events.collect {
          case Event(t, attributes) if t == "rewards" && attributes.contains(KeyValue("validator", "sara")) =>
            attributes.collect {
              case KeyValue("amount", value) => value
            }
        }.flatten
      }

    val amount = rewardAmountsValidatedBySara.head

对于您的示例,rewardAmountsValidatedBySara 将生成仅包含字符串 "100" 的字符串列表。您可以使用 .head 检索(可能不安全),如上所示。

通常你不会这样做,因为它可能会在空列表上抛出异常,所以最好使用 .headOption which returns an Option which you can然后安全处理。

请注意,隐式 Reads 是宏,它会自动转换为代码,指示 Play Json 框架如何将 JsValue 读入定义的案例 类,请参阅the documentation了解更多信息。