从case类进行play框架JSON序列化时出现scala问题

从case类进行play框架JSON序列化时出现scala问题,scala,playframework,Scala,Playframework,播放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

播放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]         ^

我认为,在最近的版本中,情况发生了变化。在
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.x
的文档很好地解释了这一变化的原因。

我认为,在最近的版本中,情况发生了变化。在
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.x
的文档很好地解释了更改的基本原理。

在本例中,由于您没有对输出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}
可以找到更多信息

嗯,


Julien

在本例中,由于您没有对输出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}
可以找到更多信息

嗯,


Julien

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

Json.writes[PersonModel].writes(personModelInstance)  // returns JsObject
来自文档:

宏编译器取代Json。通过将您自己编写的代码注入编译链,写入[User]。对于单次使用,有一个内联解决方案:

Json.writes[PersonModel].writes(personModelInstance)  // returns JsObject
来自文档:

宏编译器替换Json。通过向编译链中注入您自己将编写的确切代码来写入[User],以解释出现错误的原因:编译器实际上告诉您,您正在尝试重写方法读取(在reads trait中定义),返回的类型与定义的类型不同。您应该返回一个JsResult[PersonModel]。因此,您可以使用JsSuccess(PersonModel(…,…)包装对PersonModel构造函数的调用,并更改方法的返回类型!解释出现错误的原因:编译器实际上是在告诉您,您正在尝试重写方法reads(在reads trait中定义),该方法reads返回的类型与定义的类型不同。您应该返回一个JsResult[PersonModel]。因此,您可以使用JsSuccess(PersonModel(…,…)包装对PersonModel构造函数的调用,并更改方法的返回类型!