前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面向对象--序列化与反序列化

面向对象--序列化与反序列化

作者头像
田维常
发布2019-08-05 18:59:26
1.4K0
发布2019-08-05 18:59:26
举报

概述

内存中的数据对象只有转换成二进制才可以进行数据持久化和网络传输。将数据对象转换成二进制的流程称之为对象的序列化(Serialization)。

反之,将二进制流恢复为数据对象的过程称之为反序列化(Deserialization)。序列化需要保留充分的信息以恢复数据对象,但是为了节省存储空间和网络带宽,序列化后的二进制流又要尽可能的小。序列化常见的使用时RPC框架的数据传输。

常见三种序列化方式

Java原生序列化

Java类型通过实现Serializable接口来实现该类对象的序列化,这个接口非常特殊,没有任何方法,只是起到一个标识符的作用。Java序列化保留了对象的元数据(如类、成员变量、继承类信息等),以及对象数据等,兼容性最好,但是不支持跨语言,同时性能不是最好的。

实现Serializable接口的类建议设置serialVersionUID字段值,如果不设置,那么每次运行时,编译器会根据类的内部实现,包括类名、接口名、方法名和属性等来自动生成serialVersionUID。如果类的源代码有修改,那么重新编译后serialVersionUID的取值可能会变化。因此实现Serializable接口的类最好是显示低设置serialVersionUID值,修改类时候可以根据需要或者兼容性来决定是否需要修改serialVersionUID值。

SerialVersionUID是一个标识符,当它通常使用对象的哈希码序列化时会标记在对象上。我们可以通过Java中serialver工具找到该对象的serialVersionUID。

  • 如果是兼容升级,请不要修改serialVersionUID字段,避免反序列化失败 java.io.NotSerializableException。
  • 如果是不兼容升级,需要修改serialVersionUID值,避免反序列化失败java.io.NotSerializableException。

使用Java原生态序列化需要注意,Java反序列化时候不会调用类的无参构造方法,而是调用native方法将成员变量赋值为对应类型的初始值,基于性能以及兼容性的考虑,不推荐使用Java序列化。

Hessian序列化

Hessian序列化是一种支持动态类型、跨语言、即将于对象传输的网络协议。Java对象序列化的二进制流可以被其他语言(如:C++,python等语言)反序列化。

特性:

自描述序列化类型,不依赖外部描述文件或接口定义,用一个字节表示常用基础类型,极大的缩短了二进制流。

  • 语言无关性,支持脚本语言
  • 协议简单,比Java原生态序列化高效

相比Hessian 1.0、Hessian 2.0中增加了压缩编码,其序列化二进制流大小是Java原生态序列化的50%,序列化耗时是Java原生态大小的30%,反序列化耗时是Java原生态反序列化的20%。

Hessian 会把复杂对象所有属性存储在一个map中进行序列化。所以在父类、子类存在同名成员变量的情况下,Hessian 序列化时,先序列化子类,然后序列化父类,因此反序列化结果会导致子类同名成员变量被父类的值覆盖。

JSON序列化

JSON序列化这里的JSON=JavaScript Object Notation,是一种轻量级的数据交换格式,JSON 序列化就是将数据对象转换成JSON字符串。在序列化过程中跑起来类型信息,所以反序列化时候只有提供类型信息才能准确低反序列化。相比前面两种方式JSON可读性笔记好,方便调试。

序列化通常会通过网络协议传输对象,而对象中往往有敏感数据,所以序列化常常是黑客们的攻击点,攻击者穷秒地利用反序列化过程构造恶意代码,是得程序在反序列化过程中执行任意代码。

Java工程中广泛使用的Apache Commons Collections、Jackson、fastjson等都出现过反序列化漏洞。

如果防范这种黑客攻击呢?

将一些对象的敏感信息不进行序列化传输,可以加关键字transient修饰,避免把该属性信息转化为序列化的二进制流。如果一定要传递对象的敏感信息,也可以使用对称加密和非对称加密方式独立传输,再使用某个方法把属性还原丹对象中。transient 修饰符仅适用于变量,不适用于方法和类。在序列化时,如果我们不想序列化特定变量以满足安全约束,那么我们应该将该变量声明为transient。执行序列化时,JVM会忽略transient变量的原始值并将默认值保存到文件中。因此,transient意味着不要序列化。

应用开发者对序列化要有一定的安全意识防范,对传入数据的内容进行校验或者权限控制,及时更新安全漏洞,避免遭到黑客攻击。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端技术栈 微信公众号,前往查看

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

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

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