xml中文乱码的根本原因是outputformat的setencoding与底层输出流编码不匹配,必须显式设置setencoding("utf-8")并确保outputstreamwriter等使用utf-8构造。

XML序列化时中文变问号或方块,OutputFormat没设对编码
根本原因不是XML本身有问题,而是OutputFormat默认用UTF-8但输出流(比如FileWriter或PrintWriter)没匹配上,或者压根没显式指定编码。DOM序列化走的是字节流路径,编码不一致就直接乱码。
实操建议:
- 永远显式调用
outputFormat.setEncoding("UTF-8"),别依赖默认值 - 如果最终写入
FileOutputStream,必须包装成OutputStreamWriter并传入"UTF-8",不能直接用FileWriter(它用系统默认编码) - 用
StringWriter做中间载体时,它内部是char[],不涉及编码问题,但后续转String.getBytes()再写文件时,仍要指定编码
OutputFormat的setEncoding和setIndenting谁影响乱码
setIndenting只控制缩进和换行,完全不影响字符编码;只有setEncoding管乱码。但容易混淆的是:即使setEncoding("UTF-8")写了,如果底层Writer不是UTF-8打开的,照样白搭。
常见错误现象:
立即学习“Java免费学习笔记(深入)”;
- XML头里写着
<?xml version="1.0" encoding="UTF-8"?>,但文件打开全是乱码 →Writer编码错了 - 控制台打印正常,写入文件乱码 → 控制台用UTF-8,文件用系统编码(如Windows-1252)
- 用
StringWriter拿到字符串再string.getBytes()写文件,没传编码 → 默认用系统编码
用Transformer替代XMLSerializer是否能避开这个问题
可以,而且更推荐。原生org.apache.xml.serialize.XMLSerializer早已废弃,Transformer是JDK标准API,编码控制更明确。
关键差异:
-
Transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8")必须设置,且要早于transform() - 目标
StreamResult必须用OutputStream+OutputStreamWriter("UTF-8")构造,不能用File或String直接构造 -
Transformer对DOCTYPE、CDATA等兼容性更好,XMLSerializer在某些老版本里会丢弃encoding声明
示例片段:
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(new FileOutputStream("out.xml"), "UTF-8")))
Spring Boot里用Jaxb2Marshaller导出XML还用管OutputFormat吗
不用——Jaxb2Marshaller底层走的是JAXB,不经过XMLSerializer或Transformer,它的编码由Marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8")控制。
但注意:
- 如果手动调用
marshaller.marshal(..., Writer),这个Writer仍需是UTF-8编码的OutputStreamWriter - Web接口返回
@ResponseBodyXML时,Spring会自动设Content-Type: application/xml;charset=UTF-8,但前提是你的HttpMessageConverter配置正确,否则可能漏掉charset - 测试时用
MockMvc验证响应体,记得用andReturn().getResponse().getContentAsString(StandardCharsets.UTF_8),否则默认按ISO-8859-1读
Writer或OutputStream是否真用了UTF-8。光设OutputFormat.setEncoding或Transformer.setOutputProperty,只是“告诉XML怎么编”,没管“字节怎么写”,这两层脱节,乱码就躲不掉。










