Java中DOM Document转ByteArrayOutputStream的字符编码问题
解决Java中DOM Document转ByteArrayOutputStream的拉丁字符乱码问题
这问题我之前踩过坑!你看到的Ú变成Ú的现象,本质是UTF-8编码的多字节字符被当成单字节编码(比如ISO-8859-1)解析了——Ú的UTF-8是0xC3 0xBA两个字节,用ISO-8859-1读就会拆成Ã和š,完全乱套。核心原因就是你在转换过程中没明确指定UTF-8编码,默认用了平台编码处理输出流。
先看最容易出错的写法(就是你现在可能在用的)
// 错误示例:没有指定编码,默认使用系统平台编码(Windows可能是GBK,Linux可能是ISO-8859-1) Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.transform(new DOMSource(document), new StreamResult(byteArrayOutputStream));
正确的解决方式:全程强制UTF-8编码
有两种可靠的实现方式,选哪种都可以:
方式1:通过Transformer指定输出编码
ByteArrayOutputStream baos = new ByteArrayOutputStream(); Transformer transformer = TransformerFactory.newInstance().newTransformer(); // 关键步骤1:明确设置输出编码为UTF-8 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 可选:如果需要保留XML声明(比如<?xml version="1.0" encoding="UTF-8"?>),设置为"no"则会省略 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); transformer.transform(new DOMSource(document), new StreamResult(baos)); // 关键步骤2:转字符串时也要用UTF-8解码,别用默认的toString() String xmlContent = baos.toString(StandardCharsets.UTF_8.name());
方式2:用OutputStreamWriter包装输出流指定编码
ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 直接用OutputStreamWriter强制UTF-8编码包装输出流 Writer writer = new OutputStreamWriter(baos, StandardCharsets.UTF_8); Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.transform(new DOMSource(document), new StreamResult(writer)); writer.flush(); // 确保所有内容写入输出流 // 同样,转字符串时用UTF-8解码 String xmlContent = baos.toString(StandardCharsets.UTF_8.name());
额外注意点
如果你的Document是从外部XML文件/字符串加载的,也要确保加载时就用UTF-8解析,不然源头就可能有问题:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); // 加载XML时指定UTF-8编码 InputSource inputSource = new InputSource(new StringReader(rawXml)); inputSource.setEncoding("UTF-8"); Document document = builder.parse(inputSource);
本质就是一句话:全程编码统一为UTF-8,不管是解析生成Document,还是把Document转成输出流,都明确指定编码,别依赖系统默认的编码规则,这样拉丁字符(甚至其他非ASCII字符)都能正常保留。
内容的提问来源于stack exchange,提问作者Anderson Bestteti
相关产品推荐
相关产品推荐

