【发布时间】:2025-12-06 18:40:01
【问题描述】:
我有以下类层次结构
case class A(id: String,name:String)
object A {
implicit val reads:Reads[A] = Json.reads[A]
implicit val writes:Writes[A] = Json.writes[A]
}
class B(id:String,name:String, val other:Int,val another:Vector[String]) extends A(id,name)
object B {
implicit val reads:Reads[B] = Json.reads[B]
implicit val writes:Writes[B] = Json.writes[B]
def apply(id: String,name:String, other:Int, another:Vector[String]) = new B(id,name,other,another)
def unapply(b: B):Option[(String,String)] = Some {(b.id,b.name,b.other,b.another)}
}
序列化B时的结果只包含其父类A的状态,如下:
{
id:"some value",
name: "some other value"
}
Reads 和 Writes 的配置应该是什么,以便尊重子类中的配置,并适当地序列化所有包含的键值对。我期望的结果如下:
{
id:"some value",
name: "some other value",
other: 4,
another: ["a","b"]
}
我不想对键值对进行花哨的自定义序列化。如果编译器没有抱怨父类缺少读写隐式,我只会在子类 B 中包含读写操作。
【问题讨论】:
-
通常不鼓励扩展案例类,因为它会导致一些奇怪的行为。尝试为您的基类使用特征或抽象类。
-
我不能使用特征,因为我需要参数。如果我使用抽象类,我需要根据 Play 的约定创建一个 apply 和 unapply 方法。为了创建一个应用方法,我需要某种构造函数。我应该在抽象类中使用什么样的构造函数?它是抽象的。
-
来自 Play 的文档:宏适用于满足以下要求的类和特征。 * 它必须有一个具有 apply 和 unapply 方法的伴生对象。 * unapply 的返回类型必须与 apply 方法的参数类型匹配。 * apply 方法的参数名称必须与 JSON 中所需的属性名称相同。
-
您的代码无法为我编译,因为
Json.reads[B]already 抱怨没有应用方法。此外,如果您只调用Json.toJson(new B(...)),则隐式解析将是模棱两可的。抱歉,我可能不明白你希望你的代码最终是什么样子。 -
你是对的。在尝试调整原始代码时,我删除了 apply 和 unapply 方法。
标签: scala playframework play-json