必须正确设置HttpServletResponse响应头:Content-Type需为application/xml;charset=UTF-8,Content-Disposition设为attachment并引号包裹filename,CharacterEncoding设为UTF-8;优先用PrintWriter输出XML,且须在getWriter前完成所有头设置。

用 HttpServletResponse 输出 XML 文件并触发浏览器下载
Java 后端生成 XML 并让浏览器直接下载,核心不是“生成 XML”,而是正确设置 HttpServletResponse 的响应头与输出流。只要响应头不对,即使 XML 内容完全正确,浏览器也可能解析渲染、报错或保存为乱码文件。
关键响应头必须设全:Content-Type、Content-Disposition、Character-Encoding
缺一不可,且顺序和值有严格要求:
-
response.setContentType("application/xml;charset=UTF-8")—— 必须带charset=UTF-8,否则中文会乱码;不能写成text/xml(部分旧浏览器可能不识别下载行为) -
response.setHeader("Content-Disposition", "attachment; filename=\"data.xml\"")——attachment触发下载;filename值必须用英文引号包裹,且不能含路径或非法字符(如/、\、:) -
response.setCharacterEncoding("UTF-8")—— 与setContentType中的 charset 一致,确保 Writer 写入时编码统一
用 PrintWriter 还是 ServletOutputStream?选 PrintWriter + setCharacterEncoding
XML 是文本内容,优先用 PrintWriter,更易控制换行、缩进和编码。但必须在调用 getWriter() 前完成所有响应头设置,否则会抛 IllegalStateException。
错误写法:
response.getWriter(); // 此时 headers 已被提交,再 setHeader 无效
response.setHeader("Content-Disposition", "...");
正确顺序:
立即学习“Java免费学习笔记(深入)”;
response.setContentType("application/xml;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=\"report.xml\"");
PrintWriter writer = response.getWriter();
writer.write("\n");
writer.write("- 测试
");
writer.flush();
生成 XML 的常见陷阱:手动拼接 vs 使用 DOM/SAX/JAXB
手动字符串拼接 XML 看似简单,但极易出错:
- 未转义特殊字符(
、&、")→ XML 解析失败 - 中文字符未声明 encoding → 浏览器用默认编码(如 ISO-8859-1)解析,显示方块
- 无
声明 → 某些校验工具报 warning
生产环境建议用 javax.xml.parsers.DocumentBuilder 或 org.dom4j.DocumentHelper 构建节点,自动处理转义和编码。若只是简单结构,至少封装一个转义方法:
private String escapeXml(String s) {
if (s == null) return "";
return s.replace("&", "&")
.replace("<", "zuojiankuohaophpcn")
.replace(">", "youjiankuohaophpcn")
.replace("\"", """)
.replace("'", "'");
}
真正容易被忽略的是:即使你用了 DOM 生成 XML,如果没显式调用 Transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"),输出流仍可能按平台默认编码写入,导致下载后打开乱码。这个细节比选什么 XML 库更重要。










