Java 8 中使用 JAXB 的 UTF-8 字符

kir*_*sty 6 java encoding jaxb utf-8

我最近将 JBoss AS 5 的应用程序迁移到 Wildfly 8,因此必须从 Java 6 迁移到 Java 8。

\n\n

我现在在通过 Ant 运行我的单元测试之一时遇到问题:

\n\n
[javac] C:\\Users\\test\\JAXBClassTest.java:123: error: unmappable character for encoding UTF8\n
Run Code Online (Sandbox Code Playgroud)\n\n

测试类的第123行是:

\n\n
Assert.assertEquals("J\xc2\xb5hn", JAXBClass.getValue()); \n
Run Code Online (Sandbox Code Playgroud)\n\n

该测试专门用于确保 JAXB 编组器可以处理 UTF-8 字符,我相信这一点\xc2\xb5。我已在 JAXB 编组器上添加了一个属性,以确保允许使用这些字符:

\n\n
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");\n
Run Code Online (Sandbox Code Playgroud)\n\n

我见过多个问题(1 , 2 , 3),这些问题似乎很相似,但它们的答案解释了为什么以前以一种方式解码的无效字符现在以另一种方式解码,或者似乎实际上没有和我一样的问题。

\n\n

如果所有字符都有效,这会导致问题吗?我知道我一定错过了一些东西,但我看不到什么。

\n

Sub*_*mal 4

问题是在您的源代码中\xc2\xb5被编码为\\265. 这对于 UTF-8 无效。作为 UTF-8 编码,它是\\uC2B5

\n

在此源中,文件的字符编码是 ISO8859。

\n
class Latin1 {\n    public static void main(String[] args) {\n        String s = "\xc2\xb5"; // \\265\n        System.out.println(s);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

可以用...编译

\n
javac -encoding iso8859-1 Scratch.java\n
Run Code Online (Sandbox Code Playgroud)\n

...但是UTF-8编码失败

\n
javac -encoding UTF-8 Latin1.java\nLatin1.java:3: error: unmappable character for encoding UTF-8\n        String s = "?";\n                    ^\n
Run Code Online (Sandbox Code Playgroud)\n

在此源中,文件的字符编码为 UTF-8。

\n
class Utf8 {\n    public static void main(String[] args) {\n        String s = "\xc2\xb5"; // \\uC2B5\n        System.out.println(s);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

可以使用 ISO8859-1 进行编译,也可以使用 UTF-8 进行编译。

\n
javac -encoding UTF-8 Utf8.java\njavac -encoding iso8859-1 Utf8.java\n
Run Code Online (Sandbox Code Playgroud)\n

编辑以防从网页复制和过去会改变编码。两个源文件都可以按如下方式创建,这应该可以看出差异。

\n
String latin1 = "class Latin1 {\\n"\n        + " public static void main(String[] args) {\\n"\n        + "        String s = \\"\xc2\xb5\\";\\n"\n        + "        System.out.println(s);\\n"\n        + " }\\n"\n        + "}";\nFiles.write(Paths.get("Latin1.java"), \n        latin1.getBytes(StandardCharsets.ISO_8859_1));\n\nString utf8 = "class Utf8 {\\n"\n        + " public static void main(String[] args) {\\n"\n        + "        String s = \\"\xc2\xb5\\";\\n"\n        + "        System.out.println(s);\\n"\n        + " }\\n"\n        + "}";\nFiles.write(Paths.get("Utf8.java"), \n        utf8 .getBytes(StandardCharsets.UTF_8));\n}\n
Run Code Online (Sandbox Code Playgroud)\n