我具有许多实现的特征。当为json格式时,您可以通过kind
属性轻松区分它们。有什么简单的方法让json4s根据该属性选择正确的实现?
我宁愿避免编写庞大的自定义序列化程序来分别处理每种情况。
我希望这样的事情可以工作:
class ExampleTest extends WordSpecLike with Matchers {
implicit val formats: Formats = DefaultFormats + new CarSerializer
val teslaJson =
"""
|{
| "name": "Tesla",
| "kind": "electric",
| "batteryCapacity": 250.0
|}
""".stripMargin
val bmwJson =
"""
|{
| "name": "BMW",
| "kind": "petrol",
| "tankCapacity": 70.0
|}
""".stripMargin
val tesla = ElectricCar(
"Tesla", "electric", 250.0
)
val bmw = PetrolCar(
"BMW", "petrol", 70.0
)
"JSON4s" should {
"extract electric car" in {
parse(teslaJson).extract[ElectricCar] should be(tesla)
}
"extract petrol car" in {
parse(bmwJson).extract[PetrolCar] should be(bmw)
}
"extract electric car with CarSerializer" in {
parse(teslaJson).extract[Car] should be(teslaJson)
}
}
}
class CarSerializer extends CustomSerializer[Car](_ => ( {
case car: JObject =>
car \ "kind" match {
case JString(v) if v == "electric" => car.extract[ElectricCar]
case JString(v) if v == "petrol" => car.extract[PetrolCar]
}
}, {
case car: Car => Extraction.decompose(car)
}))
sealed trait Car {
def name: String
def kind: String
}
case class ElectricCar(
name: String,
kind: String,
batteryCapacity: Double
) extends Car
case class PetrolCar(
name: String,
kind: String,
tankCapacity: Double
) extends Car
不幸的是,它不起作用,因为extract
和decompose
函数要求存在隐式格式,但是串行化器本身是格式的一部分。