应使用createxmlstreamwriter(writer)并配合outputstreamwriter指定编码,避免直接传outputstream;xml声明与实际字节编码需一致,否则导致乱码;命名空间修复属性对writer无效,需手动管理。

createXMLStreamWriter 报错“Unsupported encoding”怎么办
常见于指定非 UTF-8 编码(如 GBK、ISO-8859-1)时,XMLOutputFactory 默认实现(如 JDK 自带的 com.sun.xml.internal.stream.XMLOutputFactoryImpl)不支持编码参数传递到 createXMLStreamWriter 的 OutputStream 版本。
- 必须用
Writer版本:调用createXMLStreamWriter(Writer),自己先套一层OutputStreamWriter指定编码 - 别传
OutputStream+ 编码字符串——这个重载方法压根不接受编码参数,JDK 文档里也没这签名 - 如果硬要 OutputStream,得手动写 XML 声明(如
<?xml version="1.0" encoding="GBK"?>),再交给createXMLStreamWriter(OutputStream),否则生成的文件头仍是 UTF-8 声明,实际字节却是 GBK,解析器会乱码
StAX 写入时中文乱码,但文件头显示 encoding="UTF-8"
说明 XML 声明写对了,但底层流没按 UTF-8 编码写入字节。根本原因不是 StAX 本身,而是你传进去的 OutputStream 没经过 OutputStreamWriter 转换。
- 错误写法:
factory.createXMLStreamWriter(new FileOutputStream("a.xml"))—— 这会用平台默认编码(Windows 是 GBK)写入 - 正确写法:
new OutputStreamWriter(new FileOutputStream("a.xml"), "UTF-8"),再传给createXMLStreamWriter(Writer) - 注意:JDK 8+ 的
Files.newBufferedWriter默认用 UTF-8,可直接用:createXMLStreamWriter(Files.newBufferedWriter(Paths.get("a.xml")))
为什么 setProperty("javax.xml.stream.isRepairingNamespaces", true) 没生效
这个属性只影响 XMLStreamReader(读取端),对 XMLStreamWriter 完全无效。StAX 规范里,命名空间修复(自动补 xmlns)是 reader 的责任,writer 只负责按你写的写。
- 写入时想自动管理命名空间,得手动调用
writeStartElement(String prefix, String localName, String namespaceURI) - 或者用
setPrefix(String prefix, String namespaceURI)+writeNamespace(String prefix, String namespaceURI)显式声明 - 别指望 writer 自动推导或补全——它连元素是否在默认命名空间里都懒得判断
性能对比:StAX vs DOM vs Jackson XML 写小文件
StAX XMLStreamWriter 在内存占用和速度上,对中小 XML(
立即学习“Java免费学习笔记(深入)”;
- 纯流式写入(无 POJO 绑定):StAX 最快,内存恒定 O(1)
- 需要从 Java 对象生成 XML:Jackson XML 更简洁,但字段多时反射开销明显,且不支持部分 StAX 级别的控制(如自定义 CDATA 包裹)
- 注意 factory 实例可复用,但
XMLStreamWriter不可重用——每次写新文档必须 new 一个










