objectinputvalidation是用于反序列化后校验对象完整性的接口,需实现validateobject()方法并显式调用registervalidation注册,校验失败抛出invalidobjectexception。

ObjectInputValidation 是 Java 序列化机制中用于在反序列化完成后、对象被返回给调用方之前执行自定义校验的接口。它不参与反序列化过程本身,而是在 ObjectInputStream 完成所有字段还原、调用完所有 readObject 方法后,统一触发校验逻辑,适合做完整性、一致性或业务规则检查。
实现 ObjectInputValidation 接口
让需要校验的类(或其内部类)实现 ObjectInputValidation,并重写 validateObject() 方法:
- 该方法无参数、无返回值,校验失败时抛出
InvalidObjectException - 类本身必须可序列化(实现
Serializable) - 需在
readObject(ObjectInputStream)中注册自身为校验器(关键!否则不会被调用)
在 readObject 中注册校验器
仅实现接口不够,必须显式调用 ois.registerValidation(this, priority)。优先级(priority)是整数,数值越小越先执行(如 0 最先,100 较晚):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
// 注册当前对象为校验器,优先级设为 0
ois.registerValidation(this, 0);
}
注意:registerValidation 必须在 defaultReadObject() 或手动读取字段之后调用,确保字段已初始化完毕。
在 validateObject 中执行校验逻辑
validateObject() 在反序列化全部完成、所有对象图构建好后被调用。此时可安全访问字段、调用其他对象方法、检查约束:
- 检查必填字段是否为 null(如
if (name == null) throw new InvalidObjectException("name cannot be null");) - 验证数值范围(如
if (age 150) throw new InvalidObjectException("invalid age");) - 校验关联对象状态(如
if (address != null && address.isIncomplete()) ...) - 避免在该方法中修改对象状态——它只应做只读校验
注意事项与限制
ObjectInputValidation 不是安全防护手段,它无法防止恶意字节流构造、反序列化 gadget 链等攻击。它的定位是“数据质量守门员”,不是“反序列化防火墙”:
- 仅对实现了该接口且正确注册的对象生效;父类/组合对象需各自注册
- 若校验失败,整个反序列化操作会以
InvalidObjectException终止,对象不会返回 - JDK 9+ 中该机制仍可用,但现代应用更推荐禁用反序列化(如使用
ObjectInputFilter)或改用 JSON/YAML 等更可控格式
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










