播放2.1-RC2:将JsValue转换为Scala值

时间:2013-01-12 08:29:56

标签: json scala playframework playframework-2.0 playframework-2.1

我是一名游戏初学者并尝试将我的网络应用程序从Play 2.0.4迁移到新的闪亮的Play 2.1-RC2。由于新的JSON处理,我的代码无法编译。

我已阅读Mandubians BlogPlay 2.1 Migration guidePlay JSON library documentation (beta),但我仍然不确定迁移代码的最佳方法是什么。

F.ex。我有一个名为File的模型,带有隐式读对象(Play 2.0):

object File {
    implicit object FileReads extends Reads[File] {
      def reads(json: JsValue) = File(
        (json \ "name").as[String],
        (json \ "size").as[Long]
     )
   }
}

我在控制器中使用它(Play 2.0):

val file = webserviceResult.json.as[models.File]

Play 2.1 Migration指南告诉我用这样的JsSuccess()重构它(Play 2.1?):

object File {
    implicit object FileFormat extends Format[File] {
      def reads(json: JsValue) = JsSuccess(File(
        (json \ "name").as[String],
        (json \ "size").as[Long]
     ))
   }
}

但是我现在如何使用这种隐式转换?

或者最好使用implicit val - 来自Twitter-examplePlay for Scala-book中的内容吗?什么是将JsValue转换为Scala值的最佳方法?

1 个答案:

答案 0 :(得分:7)

  

或者使用像Play for Scala-book的Twitter示例中的隐式val-stuff更好?

是的,对于经典转换,这是一个很好的解决方案(简单而简洁)。

但是使用“Json Macro Inception”:

可以更简单地实现此转换
import play.api.libs.json._
import play.api.libs.functional.syntax._

case class File(name: String, size: Long)
implicit val fileFormat = Json.format[File]

val json = Json.parse("""{"name":"myfile.avi", "size":12345}""") // Your WS result

scala> json.as[File]
res2: File = File(myfile.avi,12345)

警告:您不能将您的编码器放在随播对象中,这是当前Json API的限制。

我建议在所有json格式化程序中使用一个对象,并在必要时导入它。

仅供参考,原始形成者应该这样写:

implicit val rawFileRead: Format[File] = ( 
    (__ \ "name").format[String] and 
    (__ \ "size").format[Long]
)(File.apply _, unlift(File.unapply _)) // or (File, unlift(File.unapply))

检查这两个测试类,有许多有趣的例子: