15.8.4 Java9增加的过滤功能
15.8.4 Java9增加的过滤功能
Java9
为ObjectInputStream
增加了setObjectInputFilter()
、getObjectInputFilter()
两个方法:
方法 | 描述 |
---|---|
void setObjectInputFilter(ObjectInputFilter filter) |
Set the serialization filter for the stream. |
ObjectInputFilter getObjectInputFilter() |
Returns the serialization filter for this stream. |
其中setObjectInputFilter
方法用于为对象输入流设置过滤器。
反序列化时 过滤器ObjectInputFilter的checkInput方法会自动触发
当程序通过ObjectInputStream
反序列化对象时,过滤器的checkInput()
方法会被自动激发,用于检查序列化数据是否有效。
ObjectInputFilter是函数式接口
方法 | 描述 |
---|---|
ObjectInputFilter.Status checkInput(ObjectInputFilter.FilterInfo filterInfo) |
Check the class, array length, number of object references, depth, stream size, and other available filtering information. |
checkInput方法返回值
使用checkInput()
方法检查序列化数据时有3种返回值。
checkInput() 方法返回值 |
描述 |
---|---|
ObjectInputFilter.Status.REJECTED |
拒绝恢复 |
ObjectInputFilter.Status.ALLOWED |
允许恢复 |
ObjectInputFilter.Status.UNDECIDED |
未决定状态,程序继续执行检查 |
ObjectInputStream
将会根据ObjectInputFilter
的检查结果来决定是否执行反序列化:
- 如果
checkInput
方法返回Status.REJECtED
,反序列化将会被阻止; - 如果
checkInput
方法返回Status.ALLOWED
,程序将可执行反序列化;
程序 反序列化之前先检查数据
下面程序对前的ReadObject.java
程序进行改进,该程序将会在反序列化之前对数据执行检查。
1 | import java.io.*; |
上面程序中的粗体字代码为ObjectInputStream
设置了ObjectInputFilter
过滤器(程序使用Lambda
表达式创建过滤器),程序重写了checkInput
方法。
重写checkInput
方法时先使用默认的ObjectInputFilter
执行检查,
- 如果检查结果不是
Status.UNDECIDED
,程序直接返回检查结果。 - 接下来程序通过
FilterInfo
检验序列化数据,- 如果序列化数据中的对象不唯一(数据已被污染),程序拒绝执行反序列化;
- 如果序列化数据中的对象不是
Person
对象(数据被污染),程序拒绝执行反序列化。
通过这种检查,程序可以保证反序列化出来的是唯一的Person
对象,这样就让反序列化更加安全、健壮。