【问题标题】:Play 2.1-RC2: Converting JsValue to Scala Value玩 2.1-RC2:将 JsValue 转换为 Scala 值
【发布时间】:2012-12-26 19:58:24
【问题描述】:

我是一名游戏初学者,并尝试将我的 Web 应用程序从 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 迁移指南告诉我用这样的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]
     ))
   }
}

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

还是像Play for Scala-book 中的Twitter-example 那样使用implicit val-stuff 更好?将 JsValue 转换为它的 Scala 值的最佳方法是什么?

【问题讨论】:

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


    【解决方案1】:

    还是像 Play for Scala 书中的 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))
    

    查看这两个测试类,有很多有趣的例子:

    【讨论】:

    • 谢谢,这对我帮助很大。在import play.api.libs.functional.syntax._ 之后,很多编译器错误都消失了。但是我仍然对只有 one 参数的案例类有问题:implicit val rawFileRead: Format[File] = ( (__ \ "name").format[String])(File.apply _, unlift(File.unapply _)) 之类的东西不能编译 Overloaded method value [read] cannot be applied to (String => File)。但也许这应该是另一个 SO-question...
    • 宏不适用于单个字段 caseclass (groups.google.com/forum/#!starred/play-framework/hGrveOkbJ6U) 我不确定,但请检查票证中的代码
    猜你喜欢
    • 1970-01-01
    • 2013-09-15
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    相关资源
    最近更新 更多