专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java序列化和反序列化(java序列化和反序列化漏洞)

temp10 2024-11-04 14:05:30 java教程 11 ℃ 0 评论

序列化与反序列化概念

序列化是将状态信息转换为存储或传输的形式的过程。在传输的过程中,它的形式可以是字节或是XML等。通过字节的或XML编码格式,还可以转换还原,此过程叫做反序列化。

Java对象的序列化与反序列化

Java序列化和反序列化(java序列化和反序列化漏洞)

在Java中,创建对象的方法很多,而且可以重复使用没有被回收的对象。这些对象的存储位置是在JVM的堆内存。

在应用时,我们必须将这些对象持久化保存,并且能够及时读取。这时候我们就可以使用Java的对象序列化。

我们通过对象序列化的方法,将对象状态转化为字节数组并储存,而且我们可以将这个字节数组通过反序列化的方式再转换回来。

相关接口及类

为了方便使用,有一套简易好用的API,它可以使我们很轻松的进行序列化及反序列化。其中包括以下接口和类:

类通过实现 java.io.Serializable 接口以启用其序列化功能。

而某些对象并不支持 Serializable 接口。所以我们要使用到NotSerializableException。

如果序列化的类中有父类,要使它定义过的变量持久化保存,那么父类也要集成java.io.Serializable接口。

下面是一个实现了java.io.Serializable接口的类

Externalizable接口

java中还有另一个序列化接口Externalizable

为了展示他们的区别,把上面的代码改成使用Externalizable接口。

之前的对象状态并没有被持久化保存。这就是两个接口的区别:

Externalizable继承Serializable,该接口中定义两个抽象方法:writeExternal()与readExternal()。

使用Externalizable进行序列化时,在读取对象时,会调用被序列化类去创建一个新的对象,然后再将它们的值分别填充到新对象中。

序列化ID

我们假设:两个客户端,A和B试图通过网络传递对象数据,A 将C序列化,转化为二进制数据再传给B,B再反序列化得到C。

C对象的全类路径假设为 com.inout.Test,在A和B端的类文件,功能代码完全一致,但反序列化时总是失败。

解决:虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致。如果两个类的功能代码完全一致,但是序列化ID不同,那也无法相互转化。

静态变量不参与序列化

main 方法,将对象序列化后,修改静态变量值,再读取出序列化对象,然后打印出来。

最后的输出是 10,序列化并不保存静态变量。

探究ArrayList的序列化

ArrayList实现了java.io.Serializable接口,那么我们就可以对它进行序列化及反序列化。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表