播放 2.1 Json 序列化的特征? [英] Play 2.1 Json serialization for traits?
问题描述
我有这个:
package models
import play.api.libs.json._
import play.api.libs.functional.syntax._
object ModelWrites {
implicit val tmoWrites= Json.writes[TestModelObject]
implicit val ihWrites = Json.writes[IntHolder]
}
case class TestModelObject(s1:String, s2:String)
case class IntHolder(i1:Int, i2:Int)
trait HasInts {
val ints: List[IntHolder]
}
当我这样做时:
scala> val tmo = new TestModelObject("hello", "world") with HasInts {
val ints = List(IntHolder(1,2), IntHolder(3,4))
}
scala> Json.toJson(tmo)
res0: play.api.libs.json.JsValue = {"s1":"hello","s2":"world"}
如何隐式序列化混合的 val 'ints'?喜欢:
how can I implicity serialize the mixed-in val 'ints'? Like:
scala> val someInts = List(IntHolder(8,9), IntHolder(10,11))
someInts: List[models.IntHolder] = List(IntHolder(8,9), IntHolder(10,11))
scala> Json.toJson(someInts)
res1: play.api.libs.json.JsValue = [{"i1":8,"i2":9},{"i1":10,"i2":11}]
注意:如果我尝试:implicit val hasIntsWrites = Json.writes[HasInts]
我(预期?)得到:
Note: if I try: implicit val hasIntsWrites = Json.writes[HasInts]
I (expectedly?) get:
[error] Models.scala:10: No unapply function found
[error] implicit val hasIntsWrites = Json.writes[HasInts]
[error] ^
推荐答案
您将无法使用 实验性的初始"功能(Json.writes[...]
)直接在这里,因为它只适用于案例类.但是,您可以在 Inception 可以 提供的 Writes
实例的基础上构建,只需很少的样板即可完成您想要的操作.
You're not going to be able to use the experimental "Inception" feature (Json.writes[...]
) directly here, since that only works on case classes. You can, however, build on the Writes
instances that Inception can provide to accomplish what you want with only a very little boilerplate.
请注意,我忽略了在实例化这样的案例类时混合特征是否是一个好主意的问题——它可能不是——但我在这里给出的方法也适用于更一般的情况.
Note that I'm ignoring the question of whether mixing in a trait when instantiating a case class like this is a good idea—it probably isn't—but the approach I give here will work in the more general case as well.
首先是类和导入(这里没有变化):
First for the classes and imports (no changes here):
case class TestModelObject(s1: String, s2: String)
case class IntHolder(i1: Int, i2: Int)
trait HasInts { val ints: List[IntHolder] }
import play.api.libs.json._
import play.api.libs.functional.syntax._
现在我们需要将所有较低优先级的实例放入一个 trait 以确保编译器会选择正确的实例,因为 TestModelObject with HasInts
是 TestModelObject
和 HasInts
:
Now we need to put all our lower-priority instances into a trait to make sure that the compiler will pick the right one, since TestModelObject with HasInts
is a subtype of both TestModelObject
and HasInts
:
trait LowPriorityWritesInstances {
implicit val tmoWrites = Json.writes[TestModelObject]
implicit val ihWrites = Json.writes[IntHolder]
implicit object hiWrites extends OWrites[HasInts] {
def writes(hi: HasInts) = Json.obj("ints" -> hi.ints)
}
}
现在是主要事件:
object WritesInstances extends LowPriorityWritesInstances {
implicit val tmowhiWrites = new Writes[TestModelObject with HasInts] {
def writes(o: TestModelObject with HasInts) =
tmoWrites.writes(o) ++ implicitly[OWrites[HasInts]].writes(o)
}
}
我们完成了:
scala> import WritesInstances._
import WritesInstances._
scala> val tmo = new TestModelObject("hello", "world") with HasInts {
| val ints = List(IntHolder(1, 2), IntHolder(3, 4))
| }
scala> println(Json.toJson(tmo))
{"s1":"hello","s2":"world","ints":[{"i1":1,"i2":2},{"i1":3,"i2":4}]}
根据需要.
这篇关于播放 2.1 Json 序列化的特征?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!