【问题标题】:Parsing a list of named JSON objects with Play使用 Play 解析命名 JSON 对象的列表
【发布时间】:2016-03-15 21:23:00
【问题描述】:

我从一个我无法控制的外部 API 获得这个 JSON,其中包含未定义数量的命名子对象,如下所示:

{
  // ...
  "promotions": {
    "5": {
      "id": 5,
      "name": "Promo",
      "translations": {
        "fr": "Promo2",
        "de": "Promo2",
        // ...
      }
    },
    "6": {
      "id": 6,
      "name": "Promo2",
      "translations": {
        "fr": "Promo2",
        "de": "Promo2",
        // ...
      }
    },
    // ...
  }
}    

我希望使用 Play JSON 库(使用 Reads 组合器)将 promotions 的内容转换为 Promotion 对象列表,但我不知道如何处理。

【问题讨论】:

    标签: json scala parsing playframework playframework-2.0


    【解决方案1】:

    如果 json 键中不需要 id,您可以使用 values: Iterable[JsValue] 或 JsObject。所以:

    1. 要转换为带有数组的 Json,您可以使用转换器

      (__ \ "promotions").json.update(
        __.read[JsObject].map(_.values.toList).map(JsArray)
      )
      

      结果将是:

      scala> res28: play.api.libs.json.JsResult[play.api.libs.json.JsObject] = JsSuccess({"promotions":[{"id":5,"name":"Promo","translations":{"fr":"Promo2","de":"Promo2"}},{"id":6,"name":"Promo2","translations":{"fr":"Promo2","de":"Promo2"}}]},/promotions)
      
    2. 对于List[Promotion](你必须有隐式Promotion阅读器,例如使用宏implicit val PromotionRead = Json.reads[Promotion]或者你可以使用自己的显式阅读器作为as[Promotion]的参数),你的阅读器将是:

      (__ \ "promotions").read[JsObject].map(_.values.toList.map(_.as[Promotion]))
      

      结果(对于case class Promotion(id: Long, name: String)):

      scala> res40: play.api.libs.json.JsResult[List[Promotion]] = JsSuccess(List(Promotion(5,Promo), Promotion(6,Promo2)),/promotions)
      

    【讨论】:

      【解决方案2】:

      听起来您需要编写Reads[Seq[Promotion]] 的自定义实例。您可以使用阅读器宏来创建 Reads[Promotion],然后在自定义实现中使用它,该实现手动遍历 json 树并遍历您的促销编号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-05
        • 1970-01-01
        • 2019-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多