将json对象数组解析为适当的case类

时间:2016-05-24 09:08:01

标签: json scala playframework

我有一个设置的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
  }
]

我想将其解析为SeqSetting个对象。我试图通过使用特征定义我的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 [设置]

有没有办法将每个设置映射到适当的案例类?

1 个答案:

答案 0 :(得分:4)

  1. 天真的方法是提供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)
    
  2. 但是,如果您使用相同类型的'默认'在不同的子类。在这种情况下,JSON反序列化器无法区分 在这两个案例类之间。

    1. 另一种方法是使用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格式'应该在声明所有可能的子类之后发生。

    2. 有关播放json变体库click here

      的更多信息