Anorm 的 JSON 反序列化器

3
首先,我对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)
}

我不太明白具体发生了什么,也找不到一个有关如何序列化/反序列化anorm的例子。

1个回答

5
JSON序列化/反序列化器支持JSON规范中涵盖的所有基本值。如果要序列化自定义类型,则必须告诉序列化器如何操作。
Play 的JSON序列化器使用一种Scala(最初是Haskell)模式,叫做“type class”。简单来说,它允许在无需建立子类的情况下实现多态。通过使一个隐含值出现在范围内实现这一点,即要处理新类型,您需要定义一个隐含值/方法/对象。在您的具体示例中,您将为定义一个类型类实例。
虽然您可以在代码中手动转换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._

1
感谢您的解释。我不得不深入研究隐式和类型类,但完全觉得值得。 - smk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接