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对象,这样就让反序列化更加安全、健壮。