Play 2.1.1 中的 Json Writes

4
我最近开始使用Play框架,并正在使用Play 2.1.1和Slick 1.0.0实现一个网站。我现在正试图理解Json Writes,因为我想在其中一个控制器中返回Json。
我一直在查看几个关于此主题的参考文献(如这篇这篇),但是无法弄清楚自己做错了什么。
我有一个模型,看起来像这样:
case class AreaZipcode(  id: Int,
                     zipcode: String,
                     area: String,
                     city: String
                    )

object AreaZipcodes extends Table[AreaZipcode]("wijk_postcode") {

    implicit val areaZipcodeFormat = Json.format[AreaZipcode]

    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
    def zipcode = column[String]("postcode", O.NotNull)
    def area = column[String]("wijk", O.NotNull)
    def city = column[String]("plaats", O.NotNull)

    def autoInc = * returning id

    def * = id ~ zipcode ~ area ~ city <> (AreaZipcode.apply _, AreaZipcode.unapply _)
}

您可以看到我试图使用的隐式val,但是当我尝试通过这样做在我的控制器中返回Json时:
Ok(Json.toJson(areas.map(a => Json.toJson(a))))

我仍然面临着这个错误信息:

No Json deserializer found for type models.AreaZipcode. Try to implement an implicit     Writes or Format for this type. 

我尝试了几种其他的方法来实现Writes。例如,我尝试使用以下代码替代上面的隐式val:

implicit object areaZipcodeFormat extends Format[AreaZipcode] {

    def writes(a: AreaZipcode): JsValue = {
      Json.obj(
        "id" -> JsObject(a.id),
        "zipcode" -> JsString(a.zipcode),
        "area" -> JsString(a.area),
        "city" -> JsString(a.city)
      )
    }
    def reads(json: JsValue): AreaZipcode = AreaZipcode(
      (json \ "id").as[Int],
      (json \ "zipcode").as[String],
      (json \ "area").as[String],
      (json \ "city").as[String]
    )

请问有人可以指点我方向吗?

1个回答

11

JSON Inception来拯救!你只需要编写

import play.api.libs.json._
implicit val areaZipcodeFormat = Json.format[AreaZipcode]

搞定了。多亏了Scala 2.10的宏魔法,不再需要编写自己的ReadsWrites了。(我建议您阅读Play有关处理JSON的文档,其中解释了很多内容。)

编辑: 我没有注意到您已经在AreaZipcodes对象内部有了Json.format。您需要将该行移出AreaZipcodes或将其导入到当前上下文中,即

import AreaZipcodes.areaZipcodeFormat

谢谢快速响应!我已经盯着那些文档看了一段时间。感谢您提出的解决方案!但是,如果我将初始代码块中的隐式val替换为您的隐式对象,Play会开始抱怨Json对象上的format方法。有什么想法吗? - gorow
只是一个细节,更简洁的语法:implicit val areaZipCodeFormat = Json.format [AreaZipcode] - Julien Lafont
抱歉,复制和粘贴时出了错。@JulienLafont,感谢您指出这个问题。 - Carsten
@Carsten 在进行更正后,这行代码与我在初始问题中提供的完全相同。不知何故,仍然会出现我描述的错误信息 :-( - gorow
很遗憾,这对我似乎不起作用。为什么?type WeightedTerm = (String,TermWeight) implicit val WeightedTermFormat = Json.format[WeightedTerm] 会产生编译错误找不到与未应用参数匹配的apply函数 - Jonathan Stray
显示剩余2条评论

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