我在play scala中有一个等效的以下模型:
case class Foo(id:Int,value:String)
object Foo{
import play.api.libs.json.Json
implicit val fooFormats = Json.format[Foo]
}
Run Code Online (Sandbox Code Playgroud)
对于以下Foo实例
Foo(1, "foo")
Run Code Online (Sandbox Code Playgroud)
我会得到以下JSON文档:
{"id":1, "value": "foo"}
Run Code Online (Sandbox Code Playgroud)
此JSON是持久存储的,并从数据存储区读取.现在我的要求已经改变了,我需要为Foo添加一个属性.该属性具有默认值:
case class Foo(id:String,value:String, status:String="pending")
Run Code Online (Sandbox Code Playgroud)
写入JSON不是问题:
{"id":1, "value": "foo", "status":"pending"}
Run Code Online (Sandbox Code Playgroud)
但是从它读取会产生一个JsError,错过了"/ status"路径.
如何以最小的噪音提供默认值?
(ps:我有一个答案,我将在下面发布,但我对此并不满意,并且会赞成并接受任何更好的选择)
我有这个:
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]
}
Run Code Online (Sandbox Code Playgroud)
当我这样做:
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"}
Run Code Online (Sandbox Code Playgroud)
我如何隐瞒序列化混合val'ints'?喜欢:
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}]
Run Code Online (Sandbox Code Playgroud)
注意:如果我尝试:implicit val hasIntsWrites …
假设我有两个特征,我想混合到一个班级.每个特征都实现了类所需的抽象方法.
trait Writable {
def serialize(out: java.io.DataOutput)
}
trait T1 extends Writable
trait A extends T1 {
val aNum: Int
abstract override def serialize(out: java.io.DataOutput) = {
super.serialize(out)
println("A serialize")
out.writeInt(aNum)
}
def action = println("A action")
}
trait B extends T1 {
val bNum: Int
abstract override def serialize(out: java.io.DataOutput) = {
super.serialize(out)
println("B serialize")
out.writeInt(bNum)
}
def action = println("B action")
}
abstract class M[CT1 <: T1](val mNum: Int) extends Writable {
this: M[CT1] with T1 =>
def …
Run Code Online (Sandbox Code Playgroud)