JEP 290 在 JDK 9 中加入,但在 JDK 6,7,8 一些高版本中也添加了:
Java? SE Development Kit 8, Update 121 (JDK 8u121)
Java? SE Development Kit 7, Update 131 (JDK 7u131)
Java? SE Development Kit 6, Update 141 (JDK 6u141)
对于ObjectInputStream类来说,主要的过滤方法为filterCheck

根据注释,我们知道这个方法主要是当序列化过滤器不为空的时候触发该过滤器。
其中反序列化过滤器就为serialFilter属性值,跟进一下。

这是一个ObjectInputFilter接口,根据注释我们知道从流中读取类的类描述符和类的过滤器,可以不进行配置。
我们看看该类的构造方法:

默认会对serialFilter属性进行赋值操作,跟进ObjectInputFilter.Config.getSerialFilter()方法的调用。

获取的是ObjectInputFilter中的内部静态类Config的serialFilter属性
跟下来回到filterCheck方法的分析。

首先就会判断是否具有serialFilter这个过滤器,如果不为空,将会调用过滤器的checkInput方法进行过滤处理,传入了clazz / arrayLength / depth等信息。

这个方法返回的是一个ObjectInputFilter.Status,这是一个枚举类型。

接下来回到filterCheck方法。
如果返回的状态为null/REJECTED两个之一,将会抛出异常。
所以,对于过滤器的设置,我们可以通过创建一个ObjectInputFilter实例,并重写他的checkInput方法,在其中实现我们的过滤逻辑,之后通过调用ObjectInputStream#setInternalObjectInputFilter进行为stream添加过滤器。

在这个类中,存在有一个静态代码块。

在调用该类的时候就会为serialFilter属性赋值,跟进到configuredFilter属性的来源。

主要是获取jdk.serialFilter属性值,之后通过调用createFilter方法进行过滤器的创建。
跟进一下createFilter方法的调用。

这个方法将会调用ObjectInputFilter.Config.Global.createFilter方法进行创建。
接着上面的分析,我们跟进该类的createFilter方法

将传入的JEP规则字符串var0传入Global内部静态类的构造方法中,创建了一个Golbal对象,进行返回,所以前面在ObjectInputStream类的构造方法中主要是为serialFilter赋值的是一个Global类。
查看官方文档,我们知道JEP 290的编写规则为:
!", the class is rejected if the rest of the pattern matches, otherwise it is accepted
.**" it matches any class in the package and all subpackages
.*" it matches any class in the package
*", it matches any class with the pattern as a prefix
接下来看看Global构造方法中是如何进行解析的。

首先是通过传入的规则var1,将其根据;进行分割,并初始化filters属性为ArrayList数组。

首先判断是否以*结尾,进而判断是否是.*结尾,如果是以!开头的话成功匹配的话,将会通过lambada的格式调用this.filters.add将Status放置于filters属性中,这里举个例子就行了,后面就也就是同样的格式,进行filters属性的添加
我们看看filters属性是个什么东西。

这是一个函数列表。
这样成功设置了过滤器,当我们调用的时候将会调用
ObjectInputStream#filterCheck
ObjectInputFilter$Config$Global#checkInput
主要是根据遍历filters属性通过反序列化的类进行获取对应的Status状态
通过前面的分析,我们可以知道在ObjectInputFilter$Config类中属性configuredFilter中获取了jdk.serialFilter属性值,这里就是全局过滤器。
对于该属性值的设置有两种方式:
jdk.serialFilter;
%JAVA_HOME%\conf\security\java.security中的jdk.serialFilter字段。同样有着两种方法进行设置
ObjectInputStream对象之后通过调用其
setInternalObjectInputFilter方法进行设置;
Config#setObjectInputFilter方法进行设置。