如何为将生成嵌套自定义字段的案例类定义`Write`?

时间:2014-04-17 06:00:57

标签: json playframework dsl

Play框架提供了一些用于读写JSON的DSL,例如

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

case class User(name:String, age:Option[Int])

implicit val userWrites = (
  (__ \ "name" ).write[String] and
  (__ \ "age"  ).writeNullable[Int]
  )(unlift(User.unapply))

val user= new User("Freewind", Some(100))
Json.toJson(user)

它将生成一个json:

{"name":"Freewind","age":100}

但是如何定义userWrites以生成这样的JSON:

{
   "name" : "Freewind",
   "age"  : 100,
   "nested" : {
       "myname" : "Freewind",
       "myage"  :  100
   }
}

我尝试了一些解决方案,但没有一种可以解决。

1 个答案:

答案 0 :(得分:0)

您可以使用JSON transformers实现这一目标,例如此代码:

object Test {

  def main(args: Array[String]): Unit = {

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

    case class User(name: String, age: Option[Int])

    implicit val userWrites = (
      (__ \ "name").write[String] and
      (__ \ "age").writeNullable[Int])(unlift(User.unapply))

    val jsonTransformer = (__).json.update(
      __.read[JsObject].map { o => o ++ Json.obj("nested" -> Json.obj()) }) and
      (__ \ 'nested).json.copyFrom((__).json.pick)      reduce

    val user = new User("Freewind", Some(100))
    val originalJson = Json.toJson(user)
    println("Original: " + originalJson)
    val transformedJson = originalJson.transform(jsonTransformer).get
    println("Tansformed: " + transformedJson)

  }

}

输出将是:

  

原文:{“name”:“Freewind”,“age”:100}

     

Tansformed:{“name”:“Freewind”,“age”:100,“nested”:{“name”:“Freewind”,“age”:100}}