【问题标题】:serialize Map with key and value as case class using circe使用 circe 将带有键和值的 Map 序列化为案例类
【发布时间】:2021-05-28 17:42:16
【问题描述】:

下面是简化的代码,其中包含一个带有键和值作为案例类的 Map。 使用 circe 成功序列化键和值对象。 但是面临用circe序列化Map[CaseClassKey, CaseClassValue]的挑战。

//////case classes and common vals starts here//////

case class Person(personId : Int, phoneNumber : Int)

case class Item(name : String)
case class Basket(items : List[Item], bills : Map[Int, Int])

def createBasketInstance() : Basket = {
    val milk = Item("milk")
    val coffee = Item("coffee")

    val bills = Map(1 -> 20, 2 -> 75)
    Basket( List(milk, coffee), bills )
}

val basket = createBasketInstance()
val person = Person(1, 987654)

//////case classes and common vals ends here//////



import io.circe._
import io.circe.generic.semiauto._
import io.circe.syntax._
import io.circe.parser._

//Serializing Person instance that is used as Key in Map
{
    implicit val personCodec :Codec[Person] = deriveCodec[Person]
    val jsonString = person.asJson.spaces2
    println(jsonString)
    
}

println("-" * 50)

//Serializing Basket instance that is used as Value in Map
{
    implicit val itemCodec :Codec[Item] = deriveCodec[Item]
    implicit val basketCodec :Codec[Basket] = deriveCodec[Basket]
    val jsonString = basket.asJson.spaces2
    println(jsonString)
}

println("-" * 50)

//Serializing Map[Person, Basket]
//TODO : not able to make it work
{
    implicit val itemCodec :Codec[Item] = deriveCodec[Item]
    implicit val basketCodec :Codec[Basket] = deriveCodec[Basket]
    
    val map = Map(person -> basket)

    //TODO : How to make below lines work
    
    //val jsonString = map.asJson.spaces2
    //println(jsonString)
}

scalafiddle 链接:https://scalafiddle.io/sf/SkZNa1L/2

注意:希望正确地序列化和反序列化数据(Map[Person, Basket])。在这种特殊情况下,json 的外观并不重要。

【问题讨论】:

  • 您希望该 JSON 的外观如何? JSON 中的字段名称必须是字符串。
  • @Thilo :希望正确地序列化和反序列化数据(Map[Person, Basket])。在这种特殊情况下,json 的外观并不重要。
  • @mogli 它的外观非常重要,因为您需要了解您的序列化格式是如何工作的,才能设计出最佳的序列化方式。就像认为数据库的工作方式无关紧要,因为我只想将数据保存在那里,而不用担心如何将数据转换为表格/文档/图表或您正在使用的任何东西。

标签: json scala dictionary case-class circe


【解决方案1】:

严格来说,您正在尝试创建一个无效的 json。 Json 映射结构不是任意映射,它是一个对象结构,其中键是属性名称。 https://www.json.org/json-en.html

另见Can we make object as key in map when using JSON?

更新:

我建议对您的模型稍作改动以完成工作。 而不是 Map 使用对象数组,每个对象都有两个属性:键和值

类似这样的:

case class Entry(key: Person, value: Basket)

因此您可以将 Map[Person, Basket] 替换为 Seq[Entry],并在需要时将其转换回 Map。

【讨论】:

    猜你喜欢
    • 2019-03-06
    • 2019-03-28
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 2019-03-15
    • 2011-06-29
    相关资源
    最近更新 更多