对于这个JSON
{
"dokvotering": {
"votering": [
{
"rm": "2013/14",
"beteckning": "AU2"
},
{
"rm": "2013/14",
"beteckning": "AU2"
}
]
}
}
我正在尝试使用像这样的JSON组合器
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._
import play.api.data.validation.ValidationError
implicit val dokVoteringReads: Reads[DokVotering] = (
(__ \ "docvotering" \ "Votering" ).lazyRead( list[Votering](voteringReads) )
)(DokVotering)
implicit val voteringReads:Reads[Votering] = (
(__ \ "Votering" \ "rm").read[String] ~
(__ \ "Votering" \ "beteckning").read[String]
)(Votering)
}
case class DokVotering(votering: List[Votering])
case class Votering(
rm: String,
beteckning: String
)
出了哪些错误:
Error:(23, 7) type mismatch;
found : se.ce.dto.DokVotering.type
required: play.api.libs.json.Reads[?]
)(DokVotering)
^
为这个阵列结构做组合器的正确方法是什么?
答案 0 :(得分:2)
如果按照自己的方式进行,似乎存在问题,因为DokVotering
没有除Votering
列表之外的其他属性。如果你添加另一个参数,一切都很好。否则,您将不得不稍微更改隐式读取:
implicit val voteringReads: Reads[Votering] = (
(JsPath \ "rm").read[String] and
(JsPath \ "beteckning").read[String]
)(Votering.apply _)
implicit val dokVoteringReads: Reads[DokVotering] =
(JsPath \ "dokvotering" \ "votering").read[List[Votering]] map (DokVotering.apply _)
或者,如果您愿意,可以使用Play的魔术JSON Macro Inception功能。 (嗯,这不是真正的魔术,但它使用Scala宏,并且很大程度上感觉就像魔法一样。)
使用此功能,您的implicits将根据Votering
和DokVotering
的案例类进行定义。像这样:
implicit val voteringReads = Json.reads[Votering]
implicit val dokVoteringReads = Json.reads[DokVotering]
唯一的问题是,这并没有处理JSON的嵌套特性,所以你会像这样进行转换:
(json \ "dokvotering").validate[DokVotering] match {...}
以适应这种情况。