使用JSON隐式阅读器

时间:2014-04-01 14:32:28

标签: scala playframework-2.1

我有一个带有以下文档架构的MongoDB返回的List [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)

感谢您的帮助,Travis

1 个答案:

答案 0 :(得分:2)

你实际上非常接近 - 你只需要做一些小改动。首先,您可以使用嵌套的案例类,但每个案例都需要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] - 无需浏览地图。