XmlUtil.serialize未返回UTF-8编码问题及相关代码咨询
这个UTF-8编码问题我之前也碰到过,看你的代码片段,问题出在XmlUtil.serialize的默认行为上,而不是StreamingMarkupBuilder的设置,我来给你拆解下并解决:
问题分析
你已经给StreamingMarkupBuilder设置了UTF-8编码,但XmlUtil.serialize的无参(或仅传入XML节点)重载方法,默认会使用系统平台的默认编码来生成字符串——这就导致立陶宛语、俄语这类非ASCII字符被错误转码,最终输出的XML并不是真正的UTF-8编码。
解决方案
核心是显式指定XmlUtil.serialize使用UTF-8编码输出,有两种常用方式:
方式1:生成UTF-8编码的XML字符串
通过ByteArrayOutputStream和UTF-8编码的OutputStreamWriter捕获序列化内容,确保编码全程正确:
def dataMap = [ [No: '1', CustomerID: '777', Name: 'Lithuania: Ąęįėčęįasdad5645'], [No: '2', CustomerID: '888', Name: 'Latin: abcdefghij5646'], [No: '3', CustomerID: '999', Name: 'Russian: ааАСДАСЩХдсадсасд546'] ] def date = new Date() def sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") def builder = new StreamingMarkupBuilder() builder.setEncoding("UTF-8") // 补全并绑定XML结构 def xmlNode = builder.bind { mkp.xmlDeclaration() mkp.declareNamespace('xsi': 'http://www.w3.org/2001/XMLSchema-instance') iFile { Header { FileDate(sdf.format(date)) // 补充你的其他Header字段 } Records { dataMap.each { record -> Record { No(record.No) CustomerID(record.CustomerID) Name(record.Name) } } } } } // 显式用UTF-8编码序列化 def baos = new ByteArrayOutputStream() def utf8Writer = new OutputStreamWriter(baos, StandardCharsets.UTF_8) XmlUtil.serialize(xmlNode, utf8Writer) utf8Writer.flush() // 得到正确的UTF-8编码XML字符串 def utf8Xml = new String(baos.toByteArray(), StandardCharsets.UTF_8)
方式2:直接写入UTF-8编码的文件
如果你的目标是输出到文件,直接用指定UTF-8的文件写入器更高效:
// 承接上面的xmlNode变量 new File("your-output.xml").withWriter(StandardCharsets.UTF_8) { writer -> XmlUtil.serialize(xmlNode, writer) }
关键说明
builder.setEncoding("UTF-8")只是设置XML声明中的encoding="UTF-8"属性,并不控制序列化过程中的实际编码。- 一定要避免直接使用
XmlUtil.serialize(xmlNode)返回字符串,因为它会用系统默认编码(比如Windows下的GBK),导致特殊字符乱码。 - 使用
StandardCharsets.UTF_8比硬编码字符串"UTF-8"更安全,避免拼写错误。
内容的提问来源于stack exchange,提问作者evigis
相关产品推荐
相关产品推荐

