前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >多个不同类型对象如何统一JSon序列化小技巧

多个不同类型对象如何统一JSon序列化小技巧

作者头像
用户2936994
发布2019-06-13 16:22:04
1.5K0
发布2019-06-13 16:22:04
举报
文章被收录于专栏:祝威廉祝威廉

标题其实没说明白,就是假设我有四个不同类型的对象:A,B,C,D 但是呢,我序列化的时候不知道这对象会是哪个,反序列化的时候也不知道应该用哪个进行反序列化。

因为我们知道一般Json 序列化反序列化是这样的:

object JsonUtils {
  /** Used to convert between classes and JSON. */
  val mapper = new ObjectMapper with ScalaObjectMapper
  mapper.setSerializationInclusion(Include.NON_ABSENT)
  mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
  mapper.registerModule(DefaultScalaModule)

  def toJson[T: Manifest](obj: T): String = {
    mapper.writeValueAsString(obj)
  }

  def toPrettyJson[T: Manifest](obj: T): String = {
    mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj)
  }

  def fromJson[T: Manifest](json: String): T = {
    mapper.readValue[T](json)
  }
}

也就是把json转化为对象或者对象转化为json都需要指定类型。但是有时候我们拿到一个json的时候,我并不知道是A,B,C,D的哪个一类型。

然后昨天在做Delta Compaction功能的时候,看到delta用了一个小技巧解决这个问题。 Delta有AddFile,RemoveFile,Metadata等对象。首先这些对象都继承一个父类:

sealed trait Action {
  def wrap: SingleAction
  def json: String = JsonUtils.toJson(wrap)
}

该父类做了一个序列化功能,首先会将自己wrap成一个SingleAction对象,然后在用json序列化SingleAction对象而不是直接序列化自己。

子类实现wrap也很简单:

override def wrap: SingleAction = SingleAction(add = this)

就是把自己传递给SingleAction. 那这样json序列化SingleAction的时候,同时也序列化了自己。

那SingleAction是啥样的呢?只是不同类型数据的枚举:

/** A serialization helper to create a common action envelope. */
case class SingleAction(
    txn: SetTransaction = null,
    add: AddFile = null,
    remove: RemoveFile = null,
    metaData: Metadata = null,
    protocol: Protocol = null,
    commitInfo: CommitInfo = null) {

  def unwrap: Action = {
    if (add != null) {
      add
    } else if (remove != null) {
      remove
    } else if (metaData != null) {
      metaData
    } else if (txn != null) {
      txn
    } else if (protocol != null) {
      protocol
    } else if (commitInfo != null) {
      commitInfo
    } else {
      null
    }
  }
}

当我们反序列化的时候,得到的对象是确认的,就是SinlgeAction,因为SingleAction只会有一个值不为null,所以通过uwrap就得到具体的对象了。当然,唯一的缺憾是你需要通过isInstanceOf等判定下最后得到的对象是啥。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.06.07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档