问题描述
我有一个从MongoDB返回的具有以下文档架构的List [play.api.libs.json.JsObject]:
I have a List[play.api.libs.json.JsObject] returned from a MongoDB with the following document schema:
{
"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案例类中:
I am trying to use an implicit reader to read the data into a WebCategory case class:
case class WebCategory(topGroupName: String,
topGroupID: String,
webCategoryName : String,
webCategoryID : String,
subWebCats:Seq[SubWebCat])
case class SubWebCat(name:String, id:String)
到目前为止,我的代码(距离编译一百万英里)是:
My code so far (which is a million miles from compiling) is:
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)
我什至不知道是否有可能构建一个包含另一个case类作为其值之一的case类.
I don't even know if it is possible to build a case class which includes another case class as one of its values.
非常感谢您的帮助,谢谢!
Would really appreciate some help here, thanks!
好吧,事实证明,我在SubWebCategory上定义了一个空白的伴随对象,(出于我自己的原因)它干扰了阅读器.可能是由于在覆盖的伴随对象中没有应用功能.有人愿意确认吗?
Ok, so it turns out that I had defined a blank companion object on the SubWebCategory which (for reasons beyond me) interfered with the reader. Probably due to there not being an apply function to use in the over ridden companion object. Anyone care to confirm that?
此外,我当时还处于昏迷状态,而WebCategory实际上定义为:
Also, I was being dim and the WebCategory was actually defined as:
case class WebCategory(topGroupName: String,
topGroupID: String,
webCategoryName : String,
webCategoryID : String,
subWebCats:Option[Seq[SubWebCat]])
因此,特拉维斯·布朗(Travis Brown)上面提供的答案应该是(我不好,不是他的!):
so the answer provided by Travis Brown above should have been (my bad, not his!) :
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)
感谢您的帮助,特拉维斯
Thanks for your help, Travis
推荐答案
您实际上非常接近-您只需要进行一些小改动.首先,您可以使用嵌套的案例类,但是每个案例都需要Reads
实例.我将从内部开始:
You're actually very close—you just need a few small changes. First, you can use nested case classes, but you'll need Reads
instances for each of them. I'll start with the inner one:
implicit val subWebCatReader: Reads[SubWebCat] = (
(__ \ 'name).read[String] and (__ \ 'id).read[String]
)(SubWebCat)
请注意,我在路径中使用符号而不是字符串.这完全是个人喜好问题(尽管保持一致始终是件好事).还要注意斜线的方向-它们应该是向后的,而不是向前的.
Note that I'm using symbols instead of strings in the paths; this is entirely a matter of personal preference (it's always good to be consistent, though). Note also the direction of the slashes—they should be backward, not forward.
我们可以将这些更改应用于您的代码,并进行另一项编辑(对读取子类别字段的部分),然后完成:
We can apply these changes to your code and make one additional edit (to the part that reads the subcategory field) and we're done:
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]
-无需浏览地图.
We know how to read a SubWebCat
, so we also know how to read a List[SubWebCat]
—no need to go through a map.
这篇关于使用JSON隐式阅读器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!