前言
在现代软件开发中,数据的传输和存储是不可避免的需求。为了在不同的系统、语言和环境之间交换数据,开发者通常采用一些标准的格式,如 JSON 和 XML。然而,这些格式在处理复杂数据类型(如对象、集合等)时存在局限性。为了解决这个问题,许多语言和框架引入了序列化和反序列化机制,将对象转换为字节流,以便传输和存储。
序列化(Serialization):将对象的状态转换为字节流。
反序列化(Deserialization):将字节流恢复为对象的过程。
大多数处理方法中,JSON和XML支持的数据类型就是基本数据类型,整型、浮点型、字符串、布尔等,如果开发者希望在传输数据的时候直接传输一个对象,那么就不得不想办法扩展基础的JSON(XML)语法。
不管是Jackson、Fastjson还是编程语言内置的序列化方法,一旦涉及到序列化与反序列化数据,就可能会涉及到安全问题。
对象的创建和方法的自动调用:在反序列化过程中,Java 虚拟机会自动创建对象,并可能调用某些特殊的方法(如
readObject()
、readResolve()
)。这些方法可能包含自定义的逻辑,攻击者可以利用这些方法执行不安全的操作。类的加载和实例化:反序列化过程中,JVM 会根据序列化数据中的类名加载相应的类。如果类路径中存在恶意类,可能导致执行未预期的代码。
通过对比PHP的__wakeup和java的readobject的区别来深入理解java反序列化
readObject 倾向于解决“ 反序列化时如 何还原一个完整对象“这个问题,而PHP的 __wakeup 更倾向于解决“反序列化后如何初始化这个对象”的问题。
PHP反序列化
PHP的序列化是开发者不能参与的
,开发者调用 serialize 函数后,序列化的数据就已经完成了
,你得到的是一个完整的对象,你并不能在序列化数据流里新增某一个内容,你如果想插入新的内容,只有将其保存在一个属性中。也就是说PHP的序列化、反序列化是一个纯内部
的过程,而其 __sleep 、__wakeup 魔术方法的目的就是在序列化、反序列化的前后
执行一些操作。
总结:无法在序列化数据流中插入自定义内容,开发者不能直接干预序列化过程,只能通过对象的属性来影响序列化结果。
__sleep()
在序列化之前执行,返回一个数组,包含需要序列化的属性名。
清理对象中不需要序列化的资源(如关闭数据库连接)。
选择性地序列化对象的属性。
1 |
|
__wakeup()
在反序列化之后执行,用于恢复对象的状态。
重新建立数据库连接或其他资源。
初始化未序列化的属性。
1 |
|
资源类型的序列化问题
资源类型(Resource):表示外部资源的特殊变量,如数据库连接、文件句柄等。
不可序列化:资源类型无法被序列化,序列化后会变为
NULL
。
1 |
|
1 |
|
- 原因:
$link
是一个 PDO 对象,内部包含资源,无法序列化,结果为NULL
。
所以要sleep()返回三个参数,然后wakeup执行connect
java反序列化
Java反序列化的操作,很多是需要开发者深入参与的,所以你会发现大量的库会实现 readObject 、writeObject 方法,这和PHP中 __wakeup 、__sleep 很少使用是存在鲜明对比的。
其实很好理解
最大的区别就是java能够控制序列化的过程。
1 | private void writeObject(java.io.ObjectOutputStream s) throws IOException { |
3. objectAnnotation 的角色
在这段代码中,特别引人注意的是 objectAnnotation
。在 Java 的序列化过程中,除了对象的字段信息之外,开发者还可以将额外的数据放入 objectAnnotation
区域中。这使得 Java 的序列化变得更加灵活。通过 writeObject
写入的 "This is a object"
就被存放在 objectAnnotation
中。
序列化生成的数据流内容展示了这一点:
1 | objectAnnotation |
这里的 objectAnnotation
位置就是用于存储额外的序列化数据。在反序列化时,通过 readObject()
可以读取该区域的数据并进行相应的处理。
classAnnotation
主要用于描述类的额外信息,和类的元数据相关,开发者通常不会直接操作。
objectAnnotation
则用于存储对象级别的额外数据,开发者可以通过自定义 writeObject
和 readObject
方法来操作这个区域。
简单例子
1 |
About this Post
This post is written by void2eye, licensed under CC BY-NC 4.0.