使用 Play 解析命名 JSON 对象的列表
Parsing a list of named JSON objects with Play
我有一个来自外部 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
对象的列表,但我不知道如何处理这个。
听起来您需要编写 Reads[Seq[Promotion]]
的自定义实例。您可以使用 reader 宏来创建 Reads[Promotion]
,然后在手动遍历 json 树并遍历促销编号的自定义实现中使用它。
如果在 json 密钥中不需要 ID,您可以使用 values: Iterable[JsValue]
或 JsObject
。所以:
要使用数组转换为 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)
对于List[Promotion]
(你必须有隐式Promotion
reader,例如使用宏implicit val PromotionRead = Json.reads[Promotion]
或者你可以使用自己的显式reader 作为 as[Promotion]
的参数),您的 reader 将是:
(__ \ "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)
我有一个来自外部 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
对象的列表,但我不知道如何处理这个。
听起来您需要编写 Reads[Seq[Promotion]]
的自定义实例。您可以使用 reader 宏来创建 Reads[Promotion]
,然后在手动遍历 json 树并遍历促销编号的自定义实现中使用它。
如果在 json 密钥中不需要 ID,您可以使用 values: Iterable[JsValue]
或 JsObject
。所以:
要使用数组转换为 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)
对于
List[Promotion]
(你必须有隐式Promotion
reader,例如使用宏implicit val PromotionRead = Json.reads[Promotion]
或者你可以使用自己的显式reader 作为as[Promotion]
的参数),您的 reader 将是:(__ \ "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)