Properties.loadFromXML()是Java中唯一支持XML格式配置加载的方法,要求XML以声明开头、根元素为、键值对用...表示,并严格遵循编码与实体转义规范。

Properties.loadFromXML() 是唯一支持 XML 的加载方法
Java 的 Properties 类本身不支持直接用 load() 读取 XML 文件——那个方法只认 ISO-8859-1 或 UTF-8 编码的键值对文本。真正能加载 XML 格式的,只有 loadFromXML(InputStream) 这一个方法。
它要求输入流必须指向符合 Java XML 属性文件规范的文档,不是任意 XML。常见错误是拿 Spring 的 application.xml 或自定义格式 XML 去试,结果抛出 InvalidPropertiesFormatException。
- XML 必须以
开头(编码可为 ISO-8859-1,但推荐 UTF-8) - 根元素必须是
,且仅含一个(可选)和若干yyy - key 值不能含等号、空格或控制字符;value 中的特殊字符(如
&、)需实体转义
正确的 XML 格式长什么样
下面是一个能被 loadFromXML() 成功解析的最小合法示例:
Generated by Java jdbc:h2:mem:test sa Hello, & welcome!
注意:& 是必须的——XML 解析器先解码成 &,再由 Properties 当作普通值处理。如果写成原始 &,会报 org.xml.sax.SAXParseException: The entity "amp" was referenced, but not declared。
立即学习“Java免费学习笔记(深入)”;
加载时的编码与异常处理要点
loadFromXML() 内部强制使用 UTF-8 或 ISO-8859-1 解析 XML 声明中的 encoding 属性。如果你的文件声明为 encoding="GBK",它会直接失败,不会 fallback。
- 务必确保 XML 文件保存编码与声明一致(推荐统一用 UTF-8)
- 捕获
IOException(如文件不存在、无读权限)和InvalidPropertiesFormatException(格式非法) - 不要用
FileInputStream包裹FileReader——XML 解析需要原始字节流,字符流会导致编码错乱
正确写法:
Properties props = new Properties();
try (InputStream is = getClass().getResourceAsStream("/config.xml")) {
props.loadFromXML(is);
} catch (InvalidPropertiesFormatException e) {
// XML 结构不对,比如少了 标签
} catch (IOException e) {
// 文件没找到或不可读
} 和 load() 的行为差异:注释、空行、Unicode 处理
loadFromXML() 和 load() 在语义上并不等价:
-
load()允许 # 或 ! 开头的注释行,loadFromXML()只认元素,且只保留第一个 -
load()把连续空格/制表符压缩为单个空格,loadFromXML()完全保留 value 中的空白(包括换行) -
load()对 Unicode 转义(\uXXXX)自动解码,loadFromXML()不做任何转义处理——value 就是 XML 文本内容原样
这意味着,如果你在 XML 里写 ,取出来就是字符串 "\\u4f60\\u597d",不是“你好”。要支持 Unicode,得手动调用 StringEscapeUtils.unescapeJava()(Apache Commons Lang)或自己实现反斜杠解析。
实际用 XML 存配置的场景不多,一旦格式写错或编码不匹配,错误信息非常模糊——重点盯住 XML 声明、根标签、实体转义这三处,基本就能绕过八成问题。










