用于数组的JSON组合器

时间:2014-07-30 04:53:15

标签: playframework

对于这个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)
      ^

为这个阵列结构做组合器的正确方法是什么?

1 个答案:

答案 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将根据VoteringDokVotering的案例类进行定义。像这样:

implicit val voteringReads = Json.reads[Votering]
implicit val dokVoteringReads = Json.reads[DokVotering]

唯一的问题是,这并没有处理JSON的嵌套特性,所以你会像这样进行转换:

(json \ "dokvotering").validate[DokVotering] match {...}

以适应这种情况。