【问题标题】:scala trouble with play framework JSON serialization from case class案例类中播放框架JSON序列化的scala问题
【发布时间】:2013-11-22 02:51:07
【问题描述】:

播放 2.2.1,scala 2.10

// PersonModel.scala
case class PersonModel(name: String, age: Long)

object PersonModel2 {    

  implicit object PersonModelFormat extends Format[PersonModel] {
    def reads(json: JsValue): PersonModel = PersonModel(
      (json \ "name").as[String],
      (json \ "age").as[Long])
    def writes(u: PersonModel): JsValue = JsObject(List(
      "name" -> JsString(u.name),
      "age" -> JsNumber(u.age)))
  }

sbt 说

[error] PersonModel.scala:15: overriding method reads in trait Reads of type (json: play.api.libs.json.JsValue)play.api.libs.json.JsResult[models.PersonModel];
[error]  method reads has incompatible type
[error]     def reads(json: JsValue): PersonModel = PersonModel(
[error]         ^

【问题讨论】:

  • 解释为什么会出现错误:编译器实际上是在告诉您您正在尝试覆盖方法读取(在 Reads 特征中定义)返回 不同 类型定义的那个。您应该返回一个 JsResult[PersonModel]。因此,您可以使用 JsSuccess(PersonModel(..., ...)) 包装对 PersonModel 构造函数的调用并更改方法的返回类型!

标签: scala playframework


【解决方案1】:

在这种情况下,由于您没有对输出 json 做花哨的事情(例如更改生成的 json 对象中的键名),我会选择:

case class PersonModel(name: String, age: Long)

import play.api.libs.json._
implicit val personModelFormat = Json.format[PersonModel]

这样,你可以,例如

scala> val j = PersonModel("julien", 35)
j: PersonModel = PersonModel(julien,35)
scala> println(Json.toJson(j))
{"name":"julien","age":35}

更多信息可以找到here

HTH,

朱利安

【讨论】:

    【解决方案2】:

    在最近的版本中情况有所改变,我会说变得更好。在2.2.x 中,您可以这样做,使用新的函数式语法 和组合符:

     import play.api.libs.json._
     import play.api.libs.functional.syntax._
    
    
     implicit val PersonModelFormat: Format[PersonModel] = (
         (__ \ "name").format[String] and
         (__ \ "age").format[Long]
     )(PersonModel.apply, unlift(PersonModel.unapply))
    

    短得多!

    2.2.xhttp://www.playframework.com/documentation/2.2.1/ScalaJsonCombinators 的文档很好地解释了更改的理由。

    【讨论】:

      【解决方案3】:

      对于单次使用,有一个内联解决方案:

      Json.writes[PersonModel].writes(personModelInstance)  // returns JsObject
      

      来自文档:
      宏编译器通过将您自己编写的确切代码注入编译链来替换 Json.writes[User]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-11
        • 2013-08-04
        • 2017-03-29
        • 1970-01-01
        • 2016-07-26
        • 2014-01-13
        相关资源
        最近更新 更多