scala - 使用 JSON 隐式读取器

标签 scala playframework-2.1

我有一个从 MongoDB 返回的列表 [play.api.libs.json.JsObject],具有以下文档模式:

{
  "web_category_id" : "blah",
  "web_category_name" : "abcabc",
  "top_group_id" : "blah",
  "top_group_name" : "namehere",
  "sub_web_category" : [
    {
      "name" : "blah",
      "id" : "idblah"
    },
            {
      "name" : "another blah",
      "id" : "another idblah"
    } 

  ]

}

我正在尝试使用隐式读取器将数据读入 WebCategory 案例类:

case class WebCategory(topGroupName: String,
                       topGroupID: String,
                       webCategoryName : String,
                       webCategoryID : String,
                       subWebCats:Seq[SubWebCat])

case class SubWebCat(name:String, id:String)

到目前为止我的代码(距离编译还有一百万英里)是:

implicit val webCategoryReader = (
  (__/ "top_group_name").read[String] and
  (__/ "top_group_id").read[String] and
  (__/ "web_category_name").read[String] and
  (__/ "web_category_id").read[String] and
  (__/ "sub_web_category").read[List[Map[String, String]].map("name", "id"))
)(WebCategory)

我什至不知道是否可以构建一个包含另一个案例类作为其值之一的案例类。

在此非常感谢您的帮助,谢谢!

编辑:

好吧,事实证明我在 SubWebCategory 上定义了一个空白的伴随对象,它(出于我以外的原因)干扰了读者。可能是因为在过度使用的伴随对象中没有可使用的应用函数。有人想确认一下吗?

此外,我当时很昏暗,WebCategory 实际上定义为:

case class WebCategory(topGroupName: String,
                   topGroupID: String,
                   webCategoryName : String,
                   webCategoryID : String,
                   subWebCats:Option[Seq[SubWebCat]])

所以上面 Travis Brown 提供的答案应该是(我的错,不是他的!):

implicit val webCategoryReader: Reads[WebCategory] = (
  (__ \ "top_group_name").read[String] and
  (__ \ 'top_group_id).read[String] and
  (__ \ 'web_category_name).read[String] and
  (__ \ 'web_category_id).read[String] and
  (__ \ 'sub_web_category).read[Option[List[SubWebCat]]]
    )(WebCategory)

谢谢你的帮助,特拉维斯

最佳答案

您实际上非常接近 - 您只需要进行一些小的更改。首先,您可以使用嵌套的案例类,但您需要为每个案例类提供 Reads 实例。我将从内部开始:

implicit val subWebCatReader: Reads[SubWebCat] = (
  (__ \ 'name).read[String] and (__ \ 'id).read[String]
)(SubWebCat)

请注意,我在路径中使用的是符号而不是字符串;这完全是个人喜好问题(不过,保持一致总是好的)。还要注意斜线的方向——它们应该是向后的,而不是向前的。

我们可以将这些更改应用于您的代码并进行一次额外的编辑(对读取子类别字段的部分),然后我们就完成了:

implicit val webCategoryReader: Reads[WebCategory] = (
  (__ \ "top_group_name").read[String] and
  (__ \ 'top_group_id).read[String] and
  (__ \ 'web_category_name).read[String] and
  (__ \ 'web_category_id).read[String] and
  (__ \ 'sub_web_category).read[List[SubWebCat]]
)(WebCategory)

我们知道如何读取 SubWebCat,所以我们也知道如何读取 List[SubWebCat] — 无需通过 map 。

关于scala - 使用 JSON 隐式读取器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22788970/

相关文章:

scala - 如何使用 `flatMap` 实现延迟计算的成本估算?

java - lambda 反序列化 - lambda 表达式是否总是脱糖为 Scala 的静态方法?

java - 启动 fresh play 2.1 项目时出错

scala - 如何删除在 Play 框架和 slick 的单元测试中创建 session 的代码

scala - Flyway 在 sbt 中找不到我的迁移文件

java - 如何在 Scala 中使用 Java 包 com.example...object

java - 在 Java Play Framework Scala 模板中转义 HTML

java - 如何更改游戏框架名称?

json - Play 2.1和reactivemongo 0.8计数文档

playframework-2.1 - 我们可以离线为play2.1.1应用程序创建一个war文件吗?