繁体   English   中英

如何在Scala中使用Json4s序列化密封的抽象类?

[英]How to serialize sealed abstract class with Json4s in Scala?

如何在Scala中使用Json4s序列化密封的抽象类?

定义了以下类:

sealed abstract class Person extends Product with Serializable
case class Spouse(name: String, age: Int) extends Person
case class Customer(name: String, age: Int, spouse: Spouse) extends Person

我创建了一个客户类型的对象:

val customer: Customer = Customer("Joe", 35, Spouse("Marilyn", 33))

然后我序列化为JSON:

implicit val formats = DefaultFormats
val serialized = write(customer)

很好 但是然后我尝试反序列化:

val parsedObj = Serialization.read[Person](serialized)

在这里,我不断出错:

org.json4s.package $ MappingException:解析的JSON值与类构造函数不匹配

我花了很多时间试图使这项工作...

经过大量的搜索并仔细阅读了Json4s文档之后,我发现我需要一个自定义的Serializer才能使其工作。

但是,我花了一段时间才弄清楚我需要设置格式以实际使用自定义序列化程序。

这是对我有用的代码。

简单的例子:

import org.json4s._
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization.{read, write}
import org.json4s.native.Serialization

sealed abstract class Person extends Product with Serializable
case class Spouse(name: String, age: Int) extends Person
case class Customer(name: String, age: Int, spouse: Spouse) extends Person

val customer: Customer = Customer("Joe", 35, Spouse("Marilyn", 33))

implicit val formats = Serialization.formats(NoTypeHints) + PersonSerializer
val serialized = write(customer)    
val parsedObj = Serialization.read[Person](serialized)

自定义序列化器:

object PersonSerializer extends Serializer[Person] {
    private val PersonClass = classOf[Person]

    def deserialize(implicit format: Formats)
    : PartialFunction[(TypeInfo, JValue), Person] = {
        case (TypeInfo(PersonClass, _), json) =>
            json match {
                case JObject(List(
                    JField("name", JString(d)),
                    JField("age", JInt(f)),
                    ("spouse", JObject(List(JField("name", JString(g)), JField("age", JInt(h)))))
                    )) => Customer(d, f.toInt, Spouse(g, h.toInt))
                case JObject(List(
                    JField("name", JString(d)),
                    JField("age", JInt(f))
                    )) => Spouse(d, f.toInt)
            }
    }

    def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
        case x: Customer =>
            JObject(List(
                JField("name", JString(x.name)),
                JField("age", JInt(x.age)),
                ("spouse", JObject(List(JField("name", JString(x.spouse.name)), JField("age", JInt(x.spouse.age)))))
            ))
        case x: Spouse =>
            JObject(List(
                JField("name", JString(x.name)),
                JField("age", JInt(x.age))
            ))
    }
}

输出量

scala> val序列化=写入(客户)

序列化:字符串= {“名称”:“乔”,“年龄”:35,“配偶”:{“名称”:“玛丽莲”,“年龄”:33}}

scala> val parsedObj = Serialization.readPerson

parsedObj:人员=客户(Joe,35,Spouse(Marilyn,33))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM