什么是序列化?
两个服务之间要传输一个数据对象,就需要将对象转换成二进制流,通过网络传输到对方服务,再转换成对象,供服务方法调用。这个编码和解码的过程称之为序列化和反序列化。
序列化就是把 Java 对象变成二进制形式,本质上就是一个byte[]
数组。将对象序列化之后,就可以写入磁盘进行保存或者通过网络中输出给远程服务了。
反之,反序列化可以从网络或者磁盘中读取的字节数组,反序列化成对象,在程序中使用。
序列化类型
- Java 序列化:默认通过
Serializable
接口实现序列化,只要实现了该接口,该类就会自动实现序列化与反序列化,该接口没有任何方法,只起标识作用。 - Hessian序列化:Hessian 序列化是一种支持动态类型、跨语言、基于对象传输的网络协议。需要注意的是,Hessian序列化会把复杂对象所有属性存储在一个
Map
中进行序列化。所以在父类、子类存在同名成员变量的情况下, Hessian 序列化时,先序列化子类,然后序列化父类,因此反序列化结果会导致子类同名成员变量被父类的值覆盖。 - JSON序列化:把对象转化为JSON字符串形式,JSON 可读性比较好,方便调试。
一般不建议使用Java序列化
目前主流框架很少使用到 Java 序列化,比如 SpringCloud 使用的 Json 序列化,Dubbo
虽然兼容 Java
序列化,但默认使用的是 Hessian
序列化。
- 限制Java,无法跨语言
- 易被攻击,对象是通过在 ObjectInputStream 上调用 readObject() 方法进行反序列化的,它可以将类路径上几乎所有实现了 Serializable 接口的对象都实例化。这意味着,在反序列化字节流的过程中,该方法可以执行任意类型的代码,这是非常危险的。
- 序列化后的流太大
- 序列化性能太差