java中的utf-8解码

use*_*346 7 java groovy encoding utf-8

我正在尝试将参数从PHP中间层传递到了解J2EE的java后端.我正在用Groovy编写控制器代码.在那里,我正在尝试解码一些可能包含国际字符的参数.

到目前为止,我对调试此问题的结果感到非常困惑,因此我希望与您分享,希望有人能够对我的结果给出正确的解释.

为了我的小测试,我传递的参数是"déjeuner".只是为了确定,System.out.println("déjeuner")正确地给了我:

déjeuner
Run Code Online (Sandbox Code Playgroud)

在控制台中

以下是原始字符串的每个字符的char/dec和hex值:

next char: d 100 64
next char: ? -61 c3
next char: ? -87 a9
next char: j 106 6a
next char: e 101 65
next char: u 117 75
next char: n 110 6e
next char: e 101 65
next char: r 114 72
Run Code Online (Sandbox Code Playgroud)

请注意,UTF-8中的c3a9序列是所希望的字符:http://www.fileformat.info/info/unicode/char/00e9/index.htm

现在,如果我尝试将此字符串作为UTF-8字符串读取,就像在stmt.getBytes("UTF-8")中一样,我突然得到一个11字节的序列,如下所示:

64 c3 83 c2 a9 6a 65 75 6e 65 72
Run Code Online (Sandbox Code Playgroud)

而stmt.getBytes("iso-8859-1")给了我9个字节:

64 c3 a9 6a 65 75 6e 65 72
Run Code Online (Sandbox Code Playgroud)

请注意c3a9序列!

现在如果我尝试将UTF-8序列转换为UTF-8,就像在

new String(stmt.getBytes("UTF-8"), "UTF-8");
Run Code Online (Sandbox Code Playgroud)

我明白了:

next char: d 100 64
next char: ? -61 c3
next char: ? -87 a9
next char: j 106 6a
next char: e 101 65
next char: u 117 75
next char: n 110 6e
next char: e 101 65
next char: r 114 72
Run Code Online (Sandbox Code Playgroud)

注意c3a9序列

new String(stmt.getBytes("iso-8859-1"), "UTF-8")
Run Code Online (Sandbox Code Playgroud)

结果是:

next char: d 100 64
next char: ? -23 e9
next char: j 106 6a
next char: e 101 65
next char: u 117 75
next char: n 110 6e
next char: e 101 65
next char: r 114 72
Run Code Online (Sandbox Code Playgroud)

请注意e9中的utf-8(和ascii)再次是我渴望的'é'字符.

不幸的是,在任何一种情况下,我最终都会得到一个正确的字符串,就像文字字符串"déjeuner"一样.奇怪的是,字节序列似乎都是正确的.

Aar*_*lla 9

在处理字符串时,请记住:byte!= char.所以在你的第一个例子中,你有char c3,而不是byte c3一个巨大的区别:byte它将是UTF-8序列的一部分,但char 已经是Unicode.因此,当您将其转换为UTF-8时,Unicode字符c3必须成为byte序列c3 83.

所以问题是:你是如何获得String的?该代码中必定存在一个错误,该错误无法正确处理UTF-8编码byte序列.

ISO-8859-1通常工作的原因是该编码不会修改任何char代码点<256(即0到255之间的任何值),因此byte不会修改UTF-8编码的序列.

你的上一个例子也是错误的:char e9是éin ISO-8859-1和Unicode.在UTF-8中,它不是有效的,因为它不是a byte,因为byte c3缺少前缀.也就是说,它正确表示您寻求的Unicode字符串.