【问题标题】:JSON deserializer for AnormAnorm 的 JSON 反序列化器
【发布时间】:2013-03-12 01:29:03
【问题描述】:

首先,我对 Play 2 Scala 还是很陌生。我正在尝试编写一个将我的模型对象转换为 JSON 的方法。

根据这个博客http://mandubian.com/2012/10/01/unveiling-play-2-dot-1-json-api-part2-writes-format-combinators/ 这是我尝试过的

    case class Facility(id:Pk[Int],name:String)

object Facility{

    implicit val facilityWriter = (
     (__ \ "id").write[Pk[Int]] and
     (__ \ "name").write[String]
)(unlift(Facility.unapply))

然后它给了我一个错误,说没有为 Pk[Int] 找到 JSON 反序列化器

所以我尝试过这样的事情(经过一番谷歌搜索)

implicit object PkFormat extends Format[Pk[Int]] {

    def reads(json:JsValue): Pk[Int] = Id(json.as[Int])
    def writes(id:Pk[Int]):JsNumber = JsNumber(id.get)
}

我不明白到底发生了什么,也找不到关于如何序列化/反序列化异常的示例。

【问题讨论】:

    标签: json playframework-2.0 anorm


    【解决方案1】:

    JSON 序列化器/反序列化器支持 JSON 规范涵盖的所有基本值。如果你想序列化一个自定义类型,你必须告诉序列化器怎么做。

    Play 的 JSON 序列化器使用称为 type class 的 Scala(最初是 Haskell)模式。简而言之,它允许多态性而无需子类化。这是通过在范围内引入隐式值来实现的,即要处理新类型,您定义一个隐式值/方法/对象。在您的具体示例中,您为Pk[Int] 定义了一个类型类实例。

    您可以在代码中手动转换Pk[Int],或者在许多其他框架中直接在Pk 类中实现转换,但是类型类方法更简洁(因为JSON 转换是一个单独的问题)并且更容易重用(现在你可以在任何你想要的地方转换Pk[Int],即使Pk 类本身不支持它,想象一下扩展一个闭源系统)。

    至于您的代码,它应该可以正常工作,只需确保您在范围内具有必要的导入:

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

    【讨论】:

    • 感谢您的解释。不得不深入研究隐式和类型类,但完全值得。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    相关资源
    最近更新 更多