Play Framework,JSON使用覆盖应用方法读取组合器

时间:2014-09-07 13:31:14

标签: json scala playframework playframework-2.3

我想尝试这样的想法:

case class Obj(name: String, list: List[Integer], isPossible: Boolean) {    
  override def apply(name: String, list: List[Integer]): Obj = {
    Obj(name, list, list.exists((x: Integer) => x >= 10 && x <= 100))
  }
}

implicit val objReads: Reads[Obj] = (
(__ \ "name").read[String] and
(__ \ "list").read[List[Integer]]
)(Book.apply _)

但它没有编译,它给我一个错误:

Overloaded method value [apply] cannot be applied to  ((String, List[Integer], Boolean) => models.Api.Obj)

是否可以这样做,或者我必须在case class和read combinator中拥有相同数量的字段,这是不可能的

1 个答案:

答案 0 :(得分:1)

这里有一些问题。首先,案例类的apply方法是在它的伴随对象中定义的,而不是案例类本身。第二个问题是,一旦在伴随对象中定义apply方法,它将导致Obj.apply _中出现模糊的引用错误。这是因为您的apply声明是重载,而不是覆盖,因为签名不匹配。

解决此问题的一种方法是从isPossible的构造函数中删除Obj,而不是使其成为方法或val。您仍然可以以相同的方式访问它。

case class Obj(name: String, list: List[Int]) {
    val isPossible: Boolean = list.exists((x: Int) => x >= 10 && x <= 100)
}

object Obj {
    implicit val objReads: Reads[Obj] = (
        (__ \ "name").read[String] and
        (__ \ "list").read[List[Int]]
    )(Obj.apply _)
}

这个问题唯一的问题是isPossible将不再包含在JSON写入中,可以像这样修复:

implicit val objWrites: Writes[Obj] = (
    (__ \ "name").write[String] and
    (__ \ "list").write[List[Int]] and 
    (__ \ "isPossible").write[Boolean]
)( obj => (obj.name, obj.list, obj.isPossible) )

或者,您可以将重载的apply重命名为其他内容,并将其用于Reads而不是Obj.apply。但是,我认为将isPossible保留为val会更好,因为它的计算将在对象创建时完成,而不是在传递给构造函数时。这样可以确保您无法仅使用Obj("test", List(1), true)的无效状态调用isPossible