Java 中文官方教程 2022 版(四十)(4)

简介: Java 中文官方教程 2022 版(四十)

Java 中文官方教程 2022 版(四十)(3)https://developer.aliyun.com/article/1488168

使用属性

译文:docs.oracle.com/javase/tutorial/jaxp/properties/usingProps.html

本节重点介绍了 JAXP 1.5 中引入的新属性。

何时使用属性

只有处理不受信任的 XML 内容的应用程序才需要限制获取外部资源。不处理不受信任内容的内部系统和应用程序不需要关注新的限制或进行任何更改。自 7u40 和 JDK8 默认没有对此类限制的要求,应用程序在升级到 7u40 和 JDK8 时不会出现行为变化。

对于处理不受信任的 XML 输入、Schema 或样式表的应用程序,如果已经存在安全措施,比如启用 Java 安全管理器仅授予受信任的外部连接,或者使用解析器解析实体,则不需要 JAXP 1.5 中添加的新功能。

然而,JAXP 1.5 确实为没有安全管理器运行的系统和应用程序提供了直接的保护。对于这类应用程序,可以考虑使用下面详细描述的新功能来进行限制。

通过 API 设置属性

当改变代码可行时,通过 JAXP 工厂或解析器设置新属性是启用限制的最佳方式。属性可以通过以下接口设置:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setAttribute(name, value);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
parser.setProperty(name, value);
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(name, value);
SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
schemaFactory.setProperty(name, value);
TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(name, value);

以下是一个将 DOM 解析器限制为仅本地连接的外部 DTD 的示例:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
    dbf.setAttribute({{XMLConstants.ACCESS_EXTERNAL_DTD}}, "file, jar:file");
} catch (IllegalArgumentException e) {
    //jaxp 1.5 feature not supported
}

当代码更改可行,并且对于新开发,建议设置新属性如上所示。通过这种方式设置属性,应用程序可以确保无论部署到较旧还是较新版本的 JDK,或者通过系统属性或jaxp.properties设置属性,都能保持所需的行为。

使用系统属性

如果改变代码不可行,系统属性可能会有用。

如果希望为整个 JDK/JRE 调用设置限制,可以在命令行上设置系统属性;如果仅需要部分应用程序,可以在该部分之前设置系统属性,然后在之后清除。例如,以下代码展示了如何使用系统属性:

//allow resolution of external schemas
System.setProperty("javax.xml.accessExternalSchema", "file, http");
//this setting will affect all processing after it's set
some processing here
//after it's done, clear the property
System.clearProperty("javax.xml.accessExternalSchema");

使用 jaxp.properties

jaxp.properties 是一个普通的配置文件。它位于${java.home}/lib/jaxp.properties,其中 java.home 是 JRE 安装目录,例如,[安装目录路径]/jdk7/jre

可通过将以下行添加到 jaxp.properties 文件来设置外部访问限制:

javax.xml.accessExternalStylesheet=file, http

设置此项后,所有 JDK/JRE 的调用将遵守加载外部样式表的限制。

对于不希望允许 XML 处理器进行任何外部连接的系统,此功能可能很有用,此时,所有三个属性可以设置为,例如,仅文件。

错误处理

原文:docs.oracle.com/javase/tutorial/jaxp/properties/error.html

由于这些属性是当前版本的新功能,建议应用程序捕获适合接口的异常,例如,在以下示例中捕获 SAXException。在旧版本上,应用程序可能正常工作,例如,示例代码包含以下方法,用于检测是否使用支持新属性的 JDK 版本或 JAXP 实现运行示例:

public boolean isNewPropertySupported() {
       try {
           SAXParserFactory spf = SAXParserFactory.newInstance();
           SAXParser parser = spf.newSAXParser();
           parser.setProperty("http://javax.xml.XMLConstants/property/accessExternalDTD", "file");
       } catch (ParserConfigurationException ex) {
           fail(ex.getMessage());
       } catch (SAXException ex) {
           String err = ex.getMessage();
           if (err.indexOf("Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.") > -1)
           {
             //expected, jaxp 1.5 not supported
             return false;
           }
       }
       return true;
  }

如果由于新属性设置的限制而拒绝访问外部资源,则将以以下格式抛出异常并带有错误信息:

[type of construct]: Failed to read [type of construct] "[name of the external resource]", because "[type of restriction]" access is not allowed due to restriction set by the [property name] property.

例如,如果由于限制只允许使用 http 协议而拒绝获取外部 DTD,如下所示:parser.setProperty("http://javax.xml.XMLConstants/property/accessExternalDTD", "file");,并且解析器解析包含对"http://java.sun.com/dtd/properties.dtd"的外部引用的 XML 文件,则错误消息将如下所示:

External DTD: Failed to read external DTD ''http://java.sun.com/dtd/properties.dtd'', because ''http'' access is not allowed due to restriction set by the accessExternalDTD property.

StAX

原文:docs.oracle.com/javase/tutorial/jaxp/properties/stax.html

StAX、JSR 173 的规范尚不支持新属性。然而,在 JAXP 的上下文中,StAX 确实包括对这些属性的支持。设置新属性类似于 SAX 或 DOM,但通过 XMLInputFactory,如下所示:

XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty("http://javax.xml.XMLConstants/property/accessExternalDTD", "file");

存在于 StAX、JSR 173 规范中指定的属性和特性将优先于新的 JAXP 属性。例如,当 SupportDTD 属性设置为 false 时,将导致程序在输入文件包含 DTD 之前无法解析时抛出异常。对于使用 SupportDTD 属性禁用 DTD 的应用程序,新属性的添加不会产生影响。

结论

原文:docs.oracle.com/javase/tutorial/jaxp/properties/conclusion.html

JAXP 1.5 提供了新的属性,让用户可以控制获取外部资源。使用新属性与其他现有属性相同,只是这些属性与相应的系统属性和jaxp.properties一起提供,以便它们可以用于系统范围的限制或权限。

参考资料

原文:docs.oracle.com/javase/tutorial/jaxp/properties/references.html

欲了解更多信息,请参阅以下资源:

Lesson: 处理限制

原文:docs.oracle.com/javase/tutorial/jaxp/limits/index.html

XML 处理有时可能是一个消耗大量内存的操作。应用程序,特别是那些接受来自不受信任来源的 XML、XSD 和 XSL 的应用程序,应该通过使用 JDK 提供的 JAXP 处理限制来防范过度的内存消耗。

开发人员应该评估他们应用程序的需求和运行环境,以确定系统配置的可接受限制,并相应地设置这些限制。与大小相关的限制可用于防止处理畸形的 XML 源时消耗大量内存,而EntityExpansionLimit将允许应用程序在可接受水平下控制内存消耗。

在本教程中,您将了解这些限制,并学习如何正确使用它们。

处理限制定义

原文:docs.oracle.com/javase/tutorial/jaxp/limits/limits.html

以下列表描述了 JDK 支持的 JAXP XML 处理限制。这些限制可以通过工厂 API、系统属性和jaxp.properties文件指定。

entityExpansionLimit

属性 描述
名称 http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit
定义 限制实体扩展的数量。
一个正整数。小于或等于 0 的值表示没有限制。如果值不是整数,则会抛出NumericFormatException异常。
默认值 64000
系统属性 jdk.xml.entityExpansionLimit
自从 7u45, 8

elementAttributeLimit

属性 描述
名称 http://www.oracle.com/xml/jaxp/properties/elementAttributeLimit
定义 限制元素可以拥有的属性数量。
一个正整数。小于或等于 0 的值表示没有限制。如果值不是整数,则会抛出NumericFormatException异常。
默认值 10000
系统属性 jdk.xml.elementAttributeLimit
自从 7u45, 8

maxOccurLimit

属性 描述
名称 http://www.oracle.com/xml/jaxp/properties/maxOccurLimit
定义 限制在构建包含值不是"unbounded"的maxOccurs属性的 W3C XML Schema 的语法时可以创建的内容模型节点的数量。
一个正整数。小于或等于 0 的值表示没有限制。如果值不是整数,则会抛出NumericFormatException异常。
默认值 5000
系统属性 jdk.xml.maxOccurLimit
自从 7u45, 8

totalEntitySizeLimit

属性 描述
名称 http://www.oracle.com/xml/jaxp/properties/totalEntitySizeLimit
定义 限制包含通用实体和参数实体的所有实体的总大小。大小是所有实体的聚合计算。
一个正整数。小于或等于 0 的值表示没有限制。如果值不是整数,则会抛出NumericFormatException异常。
默认值 5x10⁷
系统属性 jdk.xml.totalEntitySizeLimit
自从 7u45, 8

maxGeneralEntitySizeLimit

属性 描述
名称 http://www.oracle.com/xml/jaxp/properties/maxGeneralEntitySizeLimit
定义 限制任何通用实体的最大大小。
一个正整数。小于或等于 0 的值表示没有限制。如果值不是整数,则会抛出NumericFormatException异常。
默认值 0
系统属性 jdk.xml.maxGeneralEntitySizeLimit
自从 7u45, 8

maxParameterEntitySizeLimit

属性 描述
名称 http://www.oracle.com/xml/jaxp/properties/maxParameterEntitySizeLimit
定义 限制任何参数实体的最大大小,包括嵌套多个参数实体的结果。
一个正整数。小于或等于 0 的值表示没有限制。如果值不是整数,则会抛出NumericFormatException异常。
默认值 1000000
系统属性 jdk.xml.maxParameterEntitySizeLimit
自 JDK 7u45, 8 起

entityReplacementLimit

属性 描述
名称 http://www.oracle.com/xml/jaxp/properties/entityReplacementLimit
定义 限制所有实体引用中节点的总数。
一个正整数。小于或等于 0 的值表示没有限制。如果值不是整数,则会抛出NumericFormatException异常。
默认值 3000000
系统属性 jdk.xml.entityReplacementLimit
自 JDK 7u111, 8u101 起

maxElementDepth

属性 描述
名称 http://www.oracle.com/xml/jaxp/properties/maxElementDepth
定义 限制最大元素深度。
一个正整数。小于或等于 0 的值表示没有限制。如果值不是整数,则会抛出NumericFormatException异常。
默认值 0
系统属性 jdk.xml.maxElementDepth
自 JDK 7u65, 8u11 起

maxXMLNameLimit

属性 描述
名称 http://www.oracle.com/xml/jaxp/properties/maxXMLNameLimit
定义 限制 XML 名称的最大大小,包括元素名称、属性名称和命名空间前缀和 URI。
一个正整数。小于或等于 0 的值表示没有限制。如果值不是整数,则会抛出NumericFormatException异常。
默认值 1000
系统属性 jdk.xml.maxXMLNameLimit
自 JDK 7u91, 8u65 起

旧版系统属性

这些属性自 JDK 5.0 和 6 起被引入,并继续为向后兼容性而受支持。

系统属性 自 JDK 5.0 和 6 起 新系统属性
entityExpansionLimit 1.5 jdk.xml.entityExpansionLimit
elementAttributeLimit 1.5 jdk.xml.elementAttributeLimit
maxOccurLimit 1.6 jdk.xml.maxOccur

{java.home}/lib/jaxp.properties

可以在jaxp.properties文件中指定系统属性,以定义 JDK 或 JRE 的所有调用的行为。格式为system-property-name=value。例如:

jdk.xml.maxGeneralEntitySizeLimit=1024

范围和顺序

原文:docs.oracle.com/javase/tutorial/jaxp/limits/scope.html

javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING(FSP)功能对包括 DOM、SAX、模式验证、XSLT 和 XPath 在内的 XML 处理器是必需的。当 FSP 设置为true时,建议的默认限制将被强制执行。将 FSP 设置为false不会改变这些限制。

当 Java 安全管理器存在时,FSP 被设置为 true 且无法关闭。因此,建议的默认限制将被强制执行。

jaxp.properties文件中指定的属性会影响 JDK 和 JRE 的所有调用,并将覆盖它们的默认值,或者可能已被 FSP 设置的值。

系统属性在设置时会影响 JDK 和 JRE 的调用,并覆盖默认设置或者在jaxp.properties中设置的值,或者可能已被 FSP 设置的值。

通过 JAXP 工厂或SAXParser指定的 JAXP 属性优先于系统属性,jaxp.properties文件以及FEATURE_SECURE_PROCESSING

使用限制

原文:docs.oracle.com/javase/tutorial/jaxp/limits/using.html

环境评估

评估包括在系统级别考虑应用程序可用的内存量,是否接受和处理来自不受信任来源的 XML、XSD 或 XSL 源,以及在应用程序级别考虑是否使用某些构造(如 DTD)。

内存设置和限制

XML 处理可能非常消耗内存。允许消耗的内存量取决于特定环境中应用程序的要求。必须防止处理格式不正确的 XML 数据消耗过多内存。

默认限制通常设置为允许大多数应用程序的合法 XML 输入,并允许小型硬件系统(如 PC)的内存使用。建议将限制设置为可能的最小值,以便在消耗大量内存之前捕获任何格式不正确的输入。

这些限制是相关的,但并非完全冗余。您应为所有限制设置适当的值:通常限制应设置为比默认值小得多的值。

例如,可以设置ENTITY_EXPANSION_LIMITGENERAL_ENTITY_SIZE_LIMIT来防止过多的实体引用。但是当扩展和实体大小的确切组合未知时,TOTAL_ENTITY_SIZE_LIMIT可以作为整体控制。同样,虽然TOTAL_ENTITY_SIZE_LIMIT控制替换文本的总大小,但如果文本是一个非常大的 XML 块,ENTITY_REPLACEMENT_LIMIT会限制文本中可以出现的节点总数,并防止系统过载。

通过使用getEntityCountInfo属性估计限制

为帮助您分析应设置的限制值,提供了一个名为http://www.oracle.com/xml/jaxp/properties/getEntityCountInfo的特殊属性。以下代码片段显示了使用该属性的示例:

parser.setProperty("http://www.oracle.com/xml/jaxp/properties/getEntityCountInfo", "yes");

查看示例以获取有关下载示例代码的更多信息。

当程序在 W3C MathML 3.0 中运行时,将打印出以下表格:

属性 限制 总大小 大小 实体名称
ENTITY_EXPANSION_LIMIT 64000 1417 0 null
MAX_OCCUR_NODE_LIMIT 5000 0 0 null
ELEMENT_ATTRIBUTE_LIMIT 10000 0 0 null
TOTAL_ENTITY_SIZE_LIMIT 50000000 55425 0 null
GENERAL_ENTITY_SIZE_LIMIT 0 0 0 null
PARAMETER_ENTITY_SIZE_LIMIT 1000000 0 7303 %MultiScriptExpression
MAX_ELEMENT_DEPTH_LIMIT 0 2 0 null
MAX_NAME_LIMIT 1000 13 13 null
ENTITY_REPLACEMENT_LIMIT 3000000 0 0 null

在此示例中,实体引用的总数,或实体扩展,为 1417;默认限制为 64000。所有实体的总大小为 55425;默认限制为 50000000。在解析所有引用后,最大的参数实体是 %MultiScriptExpression,长度为 7303;默认限制为 1000000。

如果这是应用程序预计要处理的最大文件,请建议将限制设置为较小的数字。例如,ENTITY_EXPANSION_LIMIT 设置为 2000,TOTAL_ENTITY_SIZE_LIMIT 设置为 100000,PARAMETER_ENTITY_SIZE_LIMIT 设置为 10000。

设置限制

限制可以像其他 JAXP 属性一样设置。它们可以通过工厂方法或解析器设置:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setAttribute(name, value);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
parser.setProperty(name, value);
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(name, value);
SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
schemaFactory.setProperty(name, value);
TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(name, value);

以下示例显示了如何使用 DocumentBuilderFactory 设置限制:

dbf.setAttribute(JDK_ENTITY_EXPANSION_LIMIT, "2000");
dbf.setAttribute(TOTAL_ENTITY_SIZE_LIMIT, "100000");
dbf.setAttribute(PARAMETER_ENTITY_SIZE_LIMIT, "10000"); 
dbf.setAttribute(JDK_MAX_ELEMENT_DEPTH, "100"); 

使用系统属性

如果更改代码不可行,系统属性可能很有用。

要为整个 JDK 或 JRE 的调用设置限制,请在命令行上设置系统属性。要仅为应用程序的一部分设置限制,可以在该部分之前设置系统属性,并在之后清除。以下代码显示了如何使用系统属性:

public static final String SP_GENERAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit";
//set limits using system property
System.setProperty(SP_GENERAL_ENTITY_SIZE_LIMIT, "2000");
//this setting will affect all processing after it's set
...
//after it is done, clear the property
System.clearProperty(SP_GENERAL_ENTITY_SIZE_LIMIT);

请注意,属性的值应为整数。如果输入的值不包含可解析的整数,将抛出 NumberFormatException;请参阅方法 parseInt(String)

查看 示例 以获取有关下载示例代码的更多信息。

使用 jaxp.properties 文件

jaxp.properties 文件是一个配置文件。通常位于 ${*java.home*}/lib/jaxp.properties,其中 *java.home* 是 JRE 安装目录,例如,[安装目录路径]/jdk8/jre。

可通过向 jaxp.properties 文件添加以下行来设置限制:

jdk.xml.maxGeneralEntitySizeLimit=2000

请注意,属性名称与系统属性相同,并具有前缀 jdk.xml。属性的值应为整数。如果输入的值不包含可解析的整数,将抛出 NumberFormatException;请参阅方法 parseInt(String)

当在文件中设置属性时,所有 JDK 和 JRE 的调用都将遵守限制。

相关文章
|
7月前
|
JavaScript NoSQL Java
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
367 96
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
|
3月前
|
Oracle Java 关系型数据库
java 编程基础入门级超级完整版教程详解
这份文档是针对Java编程入门学习者的超级完整版教程,涵盖了从环境搭建到实际项目应用的全方位内容。首先介绍了Java的基本概念与开发环境配置方法,随后深入讲解了基础语法、控制流程、面向对象编程的核心思想,并配以具体代码示例。接着探讨了常用类库与API的应用,如字符串操作、集合框架及文件处理等。最后通过一个学生成绩管理系统的实例,帮助读者将理论知识应用于实践。此外,还提供了进阶学习建议,引导学员逐步掌握更复杂的Java技术。适合初学者系统性学习Java编程。资源地址:[点击访问](https://pan.quark.cn/s/14fcf913bae6)。
307 2
|
8月前
|
消息中间件 Java 数据库
自研Java框架 Sunrays-Framework使用教程「博客之星」
### Sunrays-Framework:助力高效开发的Java微服务框架 **Sunrays-Framework** 是一款基于 Spring Boot 构建的高效微服务开发框架,深度融合了 Spring Cloud 生态中的核心技术组件。它旨在简化数据访问、缓存管理、消息队列、文件存储等常见开发任务,帮助开发者快速构建高质量的企业级应用。 #### 核心功能 - **MyBatis-Plus**:简化数据访问层开发,提供强大的 CRUD 操作和分页功能。 - **Redis**:实现高性能缓存和分布式锁,提升系统响应速度。 - **RabbitMQ**:可靠的消息队列支持,适用于异步
自研Java框架 Sunrays-Framework使用教程「博客之星」
|
9月前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
8584 5
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
8月前
|
Java 数据库连接 数据处理
探究Java异常处理【保姆级教程】
Java 异常处理是确保程序稳健运行的关键机制。它通过捕获和处理运行时错误,避免程序崩溃。Java 的异常体系以 `Throwable` 为基础,分为 `Error` 和 `Exception`。前者表示严重错误,后者可细分为受检和非受检异常。常见的异常处理方式包括 `try-catch-finally`、`throws` 和 `throw` 关键字。此外,还可以自定义异常类以满足特定需求。最佳实践包括捕获具体异常、合理使用 `finally` 块和谨慎抛出异常。掌握这些技巧能显著提升程序的健壮性和可靠性。
138 4
|
8月前
|
存储 移动开发 算法
【潜意识Java】Java基础教程:从零开始的学习之旅
本文介绍了 Java 编程语言的基础知识,涵盖从简介、程序结构到面向对象编程的核心概念。首先,Java 是一种高级、跨平台的面向对象语言,支持“一次编写,到处运行”。接着,文章详细讲解了 Java 程序的基本结构,包括包声明、导入语句、类声明和 main 方法。随后,深入探讨了基础语法,如数据类型、变量、控制结构、方法和数组。此外,还介绍了面向对象编程的关键概念,例如类与对象、继承和多态。最后,针对常见的编程错误提供了调试技巧,并总结了学习 Java 的重要性和方法。适合初学者逐步掌握 Java 编程。
149 1
|
9月前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
565 26
|
8月前
|
前端开发 Java 开发工具
Git使用教程-将idea本地Java等文件配置到gitte上【保姆级教程】
本内容详细介绍了使用Git进行版本控制的全过程,涵盖从本地仓库创建到远程仓库配置,以及最终推送代码至远程仓库的步骤。
426 0
|
9月前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
9月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)