- 封装接口:
-
ObjectInputFilter
ObjectInputFilter
。
JVM范围的反序列化过滤器工厂和静态JVM范围的过滤器可以在ObjectInputFilter.Config
类初始化期间从系统属性进行配置。
如果Java虚拟机启动时使用系统属性jdk.serialFilter
,则其值用于配置过滤器。如果未定义系统属性,并且定义了Security
属性jdk.serialFilter
,则用于配置过滤器。如果过滤器字符串无效,则初始化失败,随后尝试获取过滤器、设置过滤器或创建ObjectInputStream都会抛出IllegalStateException
。使用无效的序列化过滤器无法进行反序列化。如果未设置系统属性jdk.serialFilter
或Security
属性jdk.serialFilter
,则可以使用Config.setSerialFilter
来设置过滤器。使用System.setProperty
设置jdk.serialFilter
不会设置过滤器。属性值的语法与createFilter
方法相同。
如果Java虚拟机启动时使用系统属性jdk.serialFilterFactory
或同名的Security
属性,则其值命名要配置JVM范围的反序列化过滤器工厂的类。如果未定义系统属性,并且定义了Security
属性jdk.serialFilterFactory
,则用于配置过滤器工厂。如果保持未设置,则过滤器工厂是与先前版本兼容的内置过滤器工厂。
该类必须是public,必须具有public零参数构造函数,实现BinaryOperator<ObjectInputFilter>
接口,提供其实现并可通过应用程序类加载器访问。如果无法成功调用过滤器工厂构造函数,则随后尝试获取工厂、设置工厂或创建ObjectInputStream
都会抛出IllegalStateException
。使用无效的序列化过滤器工厂无法进行反序列化。在初始化期间使用系统或安全属性配置的过滤器工厂无法用Config.setSerialFilterFactory
替换。这确保了在命令行上设置的过滤器工厂不会被应用程序意外或故意覆盖。
使用System.setProperty
设置jdk.serialFilterFactory
不会设置过滤器工厂。系统属性值和安全属性值的语法是反序列化过滤器工厂的完全限定类名。
- 自JDK版本:
- 9
-
Method Summary
Modifier and TypeMethodDescriptionstatic ObjectInputFilter
createFilter
(String pattern) 返回一个由模式字符串生成的ObjectInputFilter。static ObjectInputFilter
返回静态JVM范围的反序列化过滤器,如果未配置则返回null
。static BinaryOperator
<ObjectInputFilter> 返回JVM范围的反序列化过滤器工厂。static void
setSerialFilter
(ObjectInputFilter filter) 如果尚未配置或设置静态JVM范围的过滤器,则设置它。static void
setSerialFilterFactory
(BinaryOperator<ObjectInputFilter> filterFactory)
-
Method Details
-
getSerialFilter
返回静态JVM范围的反序列化过滤器,如果未配置则返回null
。- 返回:
-
静态JVM范围的反序列化过滤器,如果未配置则返回
null
- 抛出:
-
IllegalStateException
- 如果从系统属性jdk.serialFilter
或安全属性jdk.serialFilter
初始化过滤器失败。
-
setSerialFilter
如果尚未配置或设置静态JVM范围的过滤器,则设置它。- 参数:
-
filter
- 要设置为JVM范围过滤器的反序列化过滤器;不能为空 - 抛出:
-
SecurityException
- 如果存在安全管理器且未授予SerializablePermission("serialFilter")
-
IllegalStateException
- 如果过滤器已经设置或从系统属性jdk.serialFilter
或安全属性jdk.serialFilter
初始化过滤器失败。
-
getSerialFilterFactory
返回JVM范围的反序列化过滤器工厂。如果已经设置过滤器工厂,则返回该工厂,否则返回内置的反序列化过滤器工厂。该过滤器工厂在从ObjectInputStream构造函数调用时为每个ObjectInputStream提供过滤器,并在使用setObjectInputFilter
设置流特定过滤器时提供过滤器。- 实现要求:
-
内置的反序列化过滤器工厂在从ObjectInputStream构造函数调用时提供静态JVM范围的过滤器。当调用
设置流特定过滤器
时,请求的过滤器将替换静态JVM范围的过滤器,除非已经设置。内置的反序列化过滤器工厂实现了在ObjectInputStream
构造函数和ObjectInputStream.setObjectInputFilter(java.io.ObjectInputFilter)
中设置初始过滤器的行为。 - 返回:
- JVM范围的反序列化过滤器工厂;非空
- 抛出:
-
IllegalStateException
- 如果过滤器工厂初始化不完整 - 自JDK版本:
- 17
-
setSerialFilterFactory
设置JVM范围的反序列化过滤器工厂。过滤器工厂只能通过以下方式之一进行配置:在命令行上设置jdk.serialFilterFactory
属性,在Security
文件中设置jdk.serialFilterFactory
属性,或使用此setSerialFilterFactory
方法。只能在创建任何ObjectInputStream
之前设置过滤器工厂,以避免使用哪个过滤器工厂的任何不一致性。当构造ObjectInputStream时会调用JVM范围的过滤器工厂,并在设置流特定过滤器时调用。参数是当前过滤器和请求的过滤器,它返回要用于流的过滤器。如果当前过滤器为
non-null
,则过滤器工厂必须返回一个non-null
过滤器;这是为了防止启用过滤后无意中禁用过滤。工厂根据其输入、任何其他过滤器、上下文或可用状态确定用于ObjectInputStream
流的过滤器。工厂可能会抛出运行时异常来表示不正确的使用或无效的参数。请参阅过滤器模型以获取组合和委托的示例。- 参数:
-
filterFactory
- 要设置为JVM范围过滤器工厂的反序列化过滤器工厂;不能为空 - 抛出:
-
IllegalStateException
- 如果内置的反序列化过滤器工厂已被替换或已创建任何ObjectInputStream
实例。 -
SecurityException
- 如果存在安全管理器且未授予SerializablePermission("serialFilter")
- 自JDK版本:
- 17
-
createFilter
从模式字符串返回一个ObjectInputFilter。模式之间用 ";"(分号)分隔。空格是有意义的,并被视为模式的一部分。如果模式包含等号赋值 "
=
",则设置一个限制。如果一个限制出现多次,则使用最后一个值。- maxdepth=
value
- 图的最大深度 - maxrefs=
value
- 内部引用的最大数量 - maxbytes=
value
- 输入流中的最大字节数 - maxarray=
value
- 允许的最大数组长度
其他模式匹配或拒绝从
Class.getName()
返回的类或包名称,如果存在可选模块名称,则匹配class.getModule().getName()
。请注意,对于数组,模式使用元素类型,而不是数组类型。- 如果模式以 "!" 开头,则如果匹配剩余模式,则拒绝该类;否则,如果模式匹配,则允许该类。
- 如果模式包含 "/", 则非空前缀直到 "/" 是模块名称;如果模块名称与类的模块名称匹配,则使用剩余模式与类名匹配。如果没有 "/", 则不比较模块名称。
- 如果模式以 ".**" 结尾,则匹配包中的任何类和所有子包中的类。
- 如果模式以 ".*" 结尾,则匹配包中的任何类。
- 如果模式以 "*" 结尾,则匹配任何以该模式为前缀的类。
- 如果模式等于类名,则匹配。
- 否则,不匹配该模式。
生成的过滤器执行限制检查,然后尝试匹配类(如果有)。如果超出任何限制,则过滤器返回
Status.REJECTED
。如果类是数组类型,则要匹配的类是元素类型。任意维度的数组与元素类型相同对待。例如,模式 "!example.Foo
" 拒绝创建任何example.Foo
的实例或数组。从左到右工作的第一个匹配的模式确定Status.ALLOWED
或Status.REJECTED
结果。如果未超出限制且没有模式与类匹配,则结果为Status.UNDECIDED
。- 参数:
-
pattern
- 要解析的模式字符串;不能为空 - 返回:
-
用于检查正在反序列化的类的过滤器;如果没有模式,则返回
null
- 抛出:
-
IllegalArgumentException
- 如果模式字符串非法或格式错误且无法解析。特别是,如果以下任一情况为真:- 如果缺少限制的名称或名称不是 "maxdepth"、"maxrefs"、"maxbytes" 或 "maxarray" 之一
- 如果限制的值无法被
Long.parseLong
解析或为负数 - 如果模式包含 "/" 且缺少模块名称或剩余模式为空
- 如果对于 ".*" 和 ".**" 缺少包
- maxdepth=
-