在Java UTF-8解码(utf-8 decoding in java)

2019-09-02 04:00发布

我试图从一个PHP中间层到理解J2EE一个Java后端传递参数。 我正在写在Groovy的控制器代码。 在那里,我试图解码一些参数可能会包含国际字符。

我真的被我调试的这个问题,到目前为止,所以我想与你分享,希望有人能够给我结果的正确解释的结果感到困惑。

对于我的小测试的缘故,我传递的参数为“DEJEUNER”。 只是可以肯定,的System.out.println(“DEJEUNER”)正确地给我:

déjeuner

在控制台

现在,以下是原始字符串的字符每一个的炭/ DEC和十六进制值:

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

注意用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

而stmt.getBytes( “ISO-8859-1”)给了我9个字节:

64 c3 a9 6a 65 75 6e 65 72

注意c3a9序列在这里!

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

new String(stmt.getBytes("UTF-8"), "UTF-8");

我得到:

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

注意c3a9序列

new String(stmt.getBytes("iso-8859-1"), "UTF-8")

结果是:

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

注意E9这在UTF-8(和ASCII)的,同样,“E”字,我很向往。

不幸的是,在两种情况下我是结束了,将显示一个类似的文本字符串“DEJEUNER”正确的字符串。 奇怪的是,字节序列似乎都正确,但。

Answer 1:

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

所以,问题是:你是怎么得到的字符串? 必须有在该代码不正确处理UTF-8编码的错误byte的序列。

为什么原因ISO-8859-1通常工作原理是,此编码不修改任何char与代码点<256(即0到255之间的任何东西),所以UTF-8编码的byte序列不会被修改。

你的最后一个例子也错了: char e9是在电子ISO-8859-1和Unicode。 在UTF-8,它,因为它不是一个不是有效byte ,并因为它是byte c3缺少前缀。 这就是说,它正确地代表你所寻求的Unicode字符串。



Answer 2:

如果你开始使用Java字符串,其中"d\u00C3\u00A9jeuner".equals(stmt)然后将数据在此阶段已损坏。

一个Java char是不是C char 。 一个char在Java是16位宽,暗含UTF-16编码数据。 尝试存储在一个Java任何其他编码数据char /字符串类型是自找麻烦。 在任何其他编码字符数据应该是作为byte数据。

如果您正在阅读的使用servlet API参数 ,那么很可能的是,HTTP请求包含不一致或不充分的编码信息。 检查调用代码和HTTP标头。 它是可能的客户端编码数据为UTF-8,但该servlet作为ISO-8859-1解码它。



Answer 3:

我有不同之处在于我的表单使用“GET”请求,而不是“POST”请求非常类似的问题。

所以,我的网址是这样的: HTTP://本地主机:4502 / form.jsp查询= d%C3%A9jeuner

request.getCharacterEncoding() = ISO-8859-1
response.getCharacterEncoding() = UTF-8
request.getParameter("query") = déjeuner

所以应该HttpServletRequest的使用UTF-8解码请求参数(这显然它不是),或者是这只是一个浏览器错误,因为该浏览器不设置任何字符编码标头(这又没有多大意义,因为它不是做POST请求)。 下面是完整的套头,并注意在URL中的%C3%A9。

http://localhost:4502/form.jsp?query=d%C3%A9juerne

GET /form.jsp?query=d%C3%A9juerne HTTP/1.1
Host: localhost:4502
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.0.17) Gecko/2010010604 Ubuntu/9.04 (jaunty) Firefox/3.0.17
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

我在此问题是,我居然复制并粘贴查询到浏览器的形式和它的编码不正确的。 无论是在Chrome和Firefox。



Answer 4:

经过一番深入调查,我发现这个答案

如何获得UTF-8在Java中的webapps工作? 。

这一切都在tomcat连接器设置的URIEncoding =“UTF-8”。

我们如何做到这一点,我们使用CMS搞清楚(CQ5 /日)。



文章来源: utf-8 decoding in java