2013-03-12 45 views
3

首先,我对Play 2 Scala很新。我试图写一个转换我的模型对象到/从JSON。Anorm的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)) 

然后,它给了我一个错误说没有JSON解串器发现PK [INT]

所以我用尽这样的事情(经过一些谷歌搜索)

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) 
} 

我不明白究竟发生了什么,并coudlnt找到一个例子o n如何序列化/反序列化anorm。

回答

5

JSON串行器/解串器支持JSON规范涵盖的所有基本值。如果你想序列化一个自定义类型,你必须告诉序列化程序如何做到这一点。

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

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

至于你的代码,它应该只是正常工作,只是确保你有范围的必要进口:

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

感谢您的解释..只好深挖implicits和类型类,但完全感觉值得。 – smk 2013-03-12 23:57:07