将对象的json数组解析为相应的case类 [英] Parse a json array of object to their appropriate case class

查看:145
本文介绍了将对象的json数组解析为相应的case类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 settings 的json数组,如下所示:

I have a json array of settings like so:

[
  {
    "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
  }
]

我想将其解析为Setting对象的Seq.我试图通过使用特征来定义我的json格式,并根据json对象中的数据类型定义不同的case类:

I want to parse this into a Seq of Setting objects. I have tried to define my json format by using a trait and defining the different case classes according to the data type in the json object:

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:

Now I try to parse the json:

val json = Json.parse(jsonStr)
implicit val jsonFormat: Format[Setting] = Json.format[Setting]

val result = Try(json.as[Seq[Setting]])

在这里我得到一个编译错误:

Here I get a compile error:

错误:(19,61)找不到unapply或unapplySeq函数 隐式val jsonFormat:Format [Setting] = Json.format [Setting]

Error:(19, 61) No unapply or unapplySeq function found implicit val jsonFormat: Format[Setting] = Json.format[Setting]

是否有一种方法可以将每个设置映射到相应的案例类?

Is there a way to map each setting to its appropriate case class?

推荐答案

  1. 天真的方法是提供Reads [Setting](如果您的目的只是将json转换为对象),以便JSON解串器能够构建Setting的正确变体.

  1. The naive approach would be to provide Reads[Setting](if your aim just to convert json to object) so that JSON deserializer able to build the right variant of 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反序列化器无法区分 在这两个案例类之间.

However, this would not work if you have same type for 'default' in different sub classes. In this case JSON deserializer unable to distinguish between those two case classes.

  1. 另一种方法是使用play json变体库.

  1. Another approach is to use play json variant library.

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提供对设置的读取和写入.确保在声明所有可能的子类之后才进行隐式val格式"的分配.

Variant.format provides both read and writes for Setting. Make sure that assignment of 'implicit val format' should happen after all possible subclass has been declared.

有关播放json变体库的更多信息,单击此处

For more information regarding play json variant library click here

这篇关于将对象的json数组解析为相应的case类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆