使用Play Scala API和Json将对象序列化

3
我尝试在Scala的Play 2.0应用程序中将我的模型序列化为Json。这是我的代码示例:
package models

import play.api.libs.json._

case class Task(id: Long, label: String, date: String)

object Task {

  ...

  implicit object TaskFormat extends Format[Task] {
    def reads(json: JsValue): Task = Task(
      (json \ "id").as[Long],
      (json \ "label").as[String],
      (json \ "date").as[String])

    def writes(t: Task): JsValue = JsObject(Seq(
      "id" -> JsNumber(t.id),
      "label" -> JsString(t.label),
      "date" -> JsString(t.date)))
  }
}

很不幸,当我运行应用程序时,出现了以下错误:
verriding method reads in trait Reads of type (json: play.api.libs.json.JsValue)play.api.libs.json.JsResult[models.Task]; method reads has incompatible type

我还没有找到解决方案。API文档(http://www.playframework.org/documentation/api/2.0/scala/play/api/libs/json/package.html)似乎也建议采取我现在的方法。

有人发现我的错误了吗?

谢谢,
Joel

2个回答

6
错误信息告诉你问题所在:返回类型必须是。
play.api.libs.json.JsResult[models.Task]

所以,根据我的观察,你返回的是Task,而不是将其包装在JsResult中。
我不使用Play,但是这就是编译器试图告诉你的。
那么,问题是什么?如果你查看Play 2.0文档,它说reads返回一个T。但是,如果你查看GitHub源代码,你会发现从2012年8月21日起已更改为JsResult[T]
因此,你正在使用比人们撰写建议时更新的版本。
我不确定新API是否在网上,但你可以在这里浏览JSON源代码。

好吧,也许我现在真的看不到它,但这对我没有什么帮助。我知道编译器告诉我的内容,但我不知道如何返回JsResult[Task]。网络上所有的文档似乎都有与我相同的代码(例如http://www.playframework.org/documentation/2.0.1/ScalaJsonGenerics,https://dev59.com/Mmct5IYBdhLWcg3wk-Zq)。 - jokr
@jomikr - 我编辑了我的答案,因为我弄清楚了发生了什么。 - Rex Kerr
1
感谢您指出这一点。我没有想到他们会以这种方式更改API。最终查看了源代码,我得到了解决方案:def reads(json: JsValue) = JsSuccess(Task( (json \ "id").as[Long], (json \ "label").as[String], (json \ "date").as[String])) - jokr

1
根据this帖子,实现Play 2.1中的Reads[T]的更正确方法是:
implicit val productReads: Reads[Product] = (
    (__ \ "ean").read[Long] and
    (__ \ "name").read[String] and
    (__ \ "description").read[String]
)(Product.apply _)

不要忘记额外的导入:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接