【问题标题】:Scala: Map part of Json to Object with playframeworkScala:使用 playframework 将 Json 的一部分映射到 Object
【发布时间】:2020-12-27 17:24:39
【问题描述】:

我对 Scala 比较陌生。我想将我的 Json 的一部分映射到我的对象。代码如下所示:

    def seasons = (json \\ "season")

案例类:

  case class Season(startDate: LocalDate, endDate: LocalDate)

json 结构:

[
      {
        "id": "",
        "name": "",
        "season": {
          "start": "0",
          "end": "0"
        }
      }
]

我想以某种方式结束一个 List[Season],所以我可以循环遍历它。

问题 #2

json-structure:

[
      {
        "id": "",
        "name": "",
        "season": {
          "start": "0",
          "end": "0"
        }
      },
      {
        "id": "",
        "name": "",
        "season": {
          "start": "0",
          "end": "0"
        }
      }...
]

Json(顺便说一句,这是一个 JsValue)带来了多个区域,如上所示。提供Case分类(Region持有Season),命名与json中相同。 格式如下所示:

implicit val seasonFormat: Format[Season] = Json.format[Season]
implicit val regionFormat: Format[Region] = Json.format[Region]

那么我需要调用什么来获取 List[Region]?我在定义格式时想到了regionsJson.as[List[Region]] 之类的东西,它为我提供了读/写的可能性。但不幸的是,它不起作用。

这样做的最佳方法是什么?我已经用 JsArray 试过了,但是我在映射它时遇到了困难......

任何意见将不胜感激!

【问题讨论】:

  • 问题2的解决方案:regionsJSON.validate[List[Region]].map(_.toList)

标签: json scala playframework mapping


【解决方案1】:

我对您原来的 case class 添加了一些更改,并将其字段重命名以匹配 json 字段。

以下代码将json解析为Seq[Session]

import java.time.LocalDate
import play.api.libs.json._

case class Season(start: LocalDate, end: LocalDate)
implicit val sessionFormat: Format[Season] = Json.format[Season]

val json =
  """
    |[
    |      {
    |        "id": "",
    |        "name": "",
    |        "season": {
    |          "start": "2020-10-20",
    |          "end": "2020-10-22"
    |        }
    |      }
    |]
    |""".stripMargin

val seasonsJson: collection.Seq[JsValue] = Json.parse(json) \\ "season"
val seasons: collection.Seq[Season] = seasonsJson.map(_.as[Season])
seasons.foreach(println)

请注意,我更改了您的 json 数据,而不是 0,这不是一个有效的日期,我提供了 iso 格式的日期 yyyy-mm-dd

以上代码适用于 play-json 版本 2.9.0。

---更新---

跟进@cchantep 的评论。

如果无法在case类中映射json,方法as将产生异常,一个非异常选项是使用asOpt,它不会抛出异常但如果映射不可行则返回None

【讨论】:

  • .as 不安全/不推荐
  • 好的 - 所以我需要一种隐式格式才能获得映射。如果我想将完整的 JSON 映射到对象列表怎么办? JSON 是一个 JsValue。我是否也定义了格式?
  • @Remo。这些对象应该是具体类型。这些类型都必须提供隐式格式。只有在方法as[T]asOpt[T] 中使用的泛型类型T 才需要隐式格式。因此,JsValue 不需要它
  • @IvanStanislavciuc 据我了解您的评论,这就是我所做的。不幸的是,它仍然无法正常工作,因为我收到了 JSValidationError(error.expected.jsobject)。更新了问题以获得更多见解。你能帮我解决这个问题吗?
  • @IvanStanislavciuc 明白了 :) regionJSON.validate[List[Region]].map(_.toList)。就这么简单。
猜你喜欢
  • 2016-05-25
  • 2023-04-06
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
相关资源
最近更新 更多