Java Properties类怎么加载XML文件

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

加载时的编码与异常处理要点

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,取出来就是字符串 "\\u4f60\\u597d",不是“你好”。要支持 Unicode,得手动调用 StringEscapeUtils.unescapeJava()(Apache Commons Lang)或自己实现反斜杠解析。

实际用 XML 存配置的场景不多,一旦格式写错或编码不匹配,错误信息非常模糊——重点盯住 XML 声明、根标签、实体转义这三处,基本就能绕过八成问题。