我有一个设置的json数组,如下所示:
[
{
"name": "Company Name",
"key": "company_name",
"default": "Foo"
}, {
"name": "Deposit Weeks",
"key": "deposit_weeks",
"default": 6
}, {
"name": "Is VAT registered",
"key": "vat_registered",
"default": false
}
]
我想将其解析为Seq
个Setting
个对象。我试图通过使用特征定义我的json格式,并根据json对象中的数据类型定义不同的case类:
sealed trait Setting
case class StringSetting(name: String, key: String, default: String) extends Setting
case class IntSetting(name: String, key: String, default: Int) extends Setting
case class BoolSetting(name: String, key: String, default: Boolean) extends Setting
现在我尝试解析json:
val json = Json.parse(jsonStr)
implicit val jsonFormat: Format[Setting] = Json.format[Setting]
val result = Try(json.as[Seq[Setting]])
这里我收到编译错误:
错误:(19,61)未找到unapply或unapplySeq函数 隐式val jsonFormat:格式[设置] = Json.format [设置]
有没有办法将每个设置映射到适当的案例类?
答案 0 :(得分:4)
天真的方法是提供Reads [Setting](如果您的目的只是将json转换为object),以便JSON解串器能够构建正确的Setting变体。
import play.api.libs.json._
import play.api.libs.functional.syntax._
implicit val settingReads: Reads[Setting] = (__ \ "default").read[String].map[Setting](StringSetting) |
(__ \ "default").read[Int].map[Setting](IntSetting) |
(__ \ "default").read[Boolean].map[Setting](BoolSetting)
但是,如果您使用相同类型的'默认'在不同的子类。在这种情况下,JSON反序列化器无法区分 在这两个案例类之间。
另一种方法是使用play json变体库。
import julienrf.variants.Variants
sealed trait Setting
case class StringSetting(name: String, key: String, default: String) extends Setting
case class IntSetting(name: String, key: String, default: Int) extends Setting
case class BoolSetting(name: String, key: String, default: Boolean) extends Setting
object Setting {
implicit val format: Format[Setting] = Variants.format[Setting]
}
Variant.format为Setting提供读写操作。确保分配隐式val格式'应该在声明所有可能的子类之后发生。
有关播放json变体库click here
的更多信息