【问题标题】:How to parse an array of json in scala play framework?如何在scala play框架中解析json数组?
【发布时间】:2021-10-28 13:33:08
【问题描述】:

我有一个这样的 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并获取密钥的value amount?对 scala 和 play 框架来说非常新。任何帮助都会很棒。谢谢

【问题讨论】:

  • 您将 JSON 读作案例类还是 JsArray
  • 尝试了 Json.parse(obj) 但这不起作用,因为 obj 是一个字符串数组
  • 请阅读documentation
  • Json.parse("[]") 确实有效。使用您尝试过的代码编辑您的帖子,否则我们无能为力。
  • 您到底想要什么结果? Sara 是“验证者”的奖励中所有金额值的列表,还是这些金额的总和?还是 Sara 验证的所有“奖励对象”的列表?

标签: json scala playframework traversal


【解决方案1】:

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

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,它会返回一个Option,然后您可以安全地处理它。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多