Java UTF-8写入xml成功

Java UTF-8写入xml成功,java,utf-8,character-encoding,jdom,jdom-2,Java,Utf 8,Character Encoding,Jdom,Jdom 2,今天我遇到了一个非常有趣的问题。当我试图重写xml文件时 我有三种方法可以做到这一点。我想知道解决问题的最好方法和原因 一, 在这种情况下,我的应用程序有一个大问题。在用我自己的语言写了文件后,我什么都看不懂。ANSI javax.servlet.ServletException上的编码文件已更改:javax.servlet.jsp.jspeException:查找属性的参数无效:document.rootElement.children[0]。children 二, 在这种情况下,我没有问题。

今天我遇到了一个非常有趣的问题。当我试图重写xml文件时

我有三种方法可以做到这一点。我想知道解决问题的最好方法和原因

一,

在这种情况下,我的应用程序有一个大问题。在用我自己的语言写了文件后,我什么都看不懂。ANSI javax.servlet.ServletException上的编码文件已更改:javax.servlet.jsp.jspeException:查找属性的参数无效:document.rootElement.children[0]。children

二,

在这种情况下,我没有问题。编码没有改变。阅读和写作没有问题

这篇文章呢


我想知道解决问题的最好方法和原因

这看起来像是个问题:

FileWriter fileWriter = new FileWriter(file); 
这将始终使用平台默认编码,这很少是您想要的。假设您的默认编码是ISO-8859-1。如果您的文档声明自己是用UTF-8编码的,但实际上所有内容都是用ISO-8859-1编写的,那么如果您有任何非ASCII字符,那么您的文件将无效-您最终将使用ISO-8859-1单字节表示法来编写它们,而ISO-8859-1单字节表示法是无效的UTF-8

实际上,我会向XMLOutputter而不是编写器提供流。这样,文件声明的编码和编写器使用的编码之间就没有冲突的余地。因此,只需将代码更改为:

FileOutputStream fileOutput = new FileOutputStream(file);
...
xmlOutput.output(document, fileOutput);
。。。正如我现在看到的,您在第二段代码中所做的。因此,是的,这是首选方法。在这里,流对要使用的编码不做任何假设,因为它只处理二进制数据。XML编写代码决定二进制数据将是什么,它可以确保它真正使用的字符编码与文件开头的声明匹配


您还应该清理异常处理—不要只打印堆栈跟踪并在失败时继续,在finally块中而不是在try块的末尾调用close。如果您不能真正地处理异常,可以让它直接向堆栈上传播,可能会向您的方法中添加throws子句,或者捕获它,记录它,然后重新显示异常,或者使用更合适的异常包装原因。

好吧,这看起来像是问题:

FileWriter fileWriter = new FileWriter(file); 
这将始终使用平台默认编码,这很少是您想要的。假设您的默认编码是ISO-8859-1。如果您的文档声明自己是用UTF-8编码的,但实际上所有内容都是用ISO-8859-1编写的,那么如果您有任何非ASCII字符,那么您的文件将无效-您最终将使用ISO-8859-1单字节表示法来编写它们,而ISO-8859-1单字节表示法是无效的UTF-8

实际上,我会向XMLOutputter而不是编写器提供流。这样,文件声明的编码和编写器使用的编码之间就没有冲突的余地。因此,只需将代码更改为:

FileOutputStream fileOutput = new FileOutputStream(file);
...
xmlOutput.output(document, fileOutput);
。。。正如我现在看到的,您在第二段代码中所做的。因此,是的,这是首选方法。在这里,流对要使用的编码不做任何假设,因为它只处理二进制数据。XML编写代码决定二进制数据将是什么,它可以确保它真正使用的字符编码与文件开头的声明匹配


您还应该清理异常处理—不要只打印堆栈跟踪并在失败时继续,在finally块中而不是在try块的末尾调用close。如果您不能真正地处理异常,可以让它直接向堆栈上传播,可能会向您的方法添加throws子句,或者捕获它,记录它,然后重新显示异常,或者使用更合适的异常包装原因。

如果我没记错的话,您可以强制xmlOutputter使用漂亮的格式,包括: 新的XMLOutputterFormat.getPrettyFormat,因此它也应该与I一起工作

美丽是:

返回执行空白美化的新格式对象 对于2空间缩进,使用UTF-8编码,不会展开为空 元素,包括声明和编码,并使用默认值 实体逃逸策略。可以对返回的格式进行调整 实例而不影响其他实例


如果我没记错的话,您可以强制XMLOutputer使用以下格式: 新的XMLOutputterFormat.getPrettyFormat,因此它也应该与I一起工作

美丽是:

返回执行空白美化的新格式对象 对于2空间缩进,使用UTF-8编码,不会展开为空 元素,包括声明和编码,并使用默认值 实体逃逸策略。可以对返回的格式进行调整 实例而不影响其他实例


感谢您的帮助,最后,我将写入程序更改为FileOutputStream,解决UTF-8问题~感谢您的帮助,最后,我将写入程序更改为FileOutputStream,解决UTF-8问题~