无法使用“写入”将通用案例类转换为json

时间:2014-01-27 06:06:18

标签: json scala playframework playframework-2.2

我有一个类,我希望能够转换为json:

case class Page[T](items: Seq[T], pageIndex: Int, pageSize: Int, totalCount: Long)

object Page {

  implicit val jsonWriter: Writes[Page[_]] = Json.writes[Page[_]]
}

错误为No apply function found matching unapply parameters

4 个答案:

答案 0 :(得分:9)

您可以为此类通用案例类Format[Page[T]]定义Page[T]

import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit def pageFormat[T: Format]: Format[Page[T]] =
  ((__ \ "items").format[Seq[T]] ~
    (__ \ "pageIndex").format[Int] ~
    (__ \ "pageSize").format[Int] ~
    (__ \ "totalCount").format[Long])(Page.apply, unlift(Page.unapply))

虽然此解决方案需要更多输入,但它会使您的案例类Page[T]无法隐式参数列表或需要定义Page[T]的具体子类。

答案 1 :(得分:3)

我更喜欢this solutiontrait,但如果你想让你的案例类通用,你可以使用2种方法中的一种。

如果您不必使用Page[_],即您始终在toJsonPage[Int]上呼叫Seq[Page[String]],而不是Page[_]Seq[Page[_]]

object Page {
  implicit def pageWriter[T: Writes](): Writes[Page[T]] = Json.writes[Page[T]]
}

如果您必须序列化Page[_]

case class Page[T](items: Seq[T],
                   pageIndex: Int,
                   pageSize: Int,
                   totalCount: Long)(
      implicit val tWrites: Writes[T])

object Page {
  implicit def pageWriter[T]: Writes[Page[T]] = new Writes[Page[T]] {
    def writes(o: Page[T]): JsValue = {
      implicit val tWrites = o.tWrites
      val writes = Json.writes[Page[T]]
      writes.writes(o)
    }
  }
}

答案 2 :(得分:1)

我认为你没有任何类型参数的通用编写器。我建议如下:

trait Page[T] {
  val items: Seq[T]
  val pageIndex: Int
  val pageSize: Int
  val totalCount: Long
}

case class IntPage(items: Seq[Int], pageIndex: Int, pageSize: Int, totalCount: Long) extends Page[Int]

object Page {
  implicit def jsonWriter = Json.writes[IntPage]
}

答案 3 :(得分:0)

也许你可以这样写:

    case class Page(items: JsValue, pageIndex: Int, pageSize: Int, totalCount: Long)

放置JsValue而不是Seq [T]

这是我的代码示例:

    case class ResponseObject(state:Int = 1,data:JsValue)

    case class City(id:Int,name:String,sort:String){
      require(id > 0)
    }

      def list = Action {
        implicit val cityFormat:Format[City] = Json.format[City]
        implicit val responseFormat=Json.format[ResponseObject]
        Ok(Json.toJson(ResponseObject(data=Json.toJson(City.list)))).as("application/json")
      }