我试图从一个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”正确的字符串。 奇怪的是,字节序列似乎都正确,但。
当处理字符串时,永远记住: 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字符串。
如果你开始使用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解码它。
我有不同之处在于我的表单使用“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。
经过一番深入调查,我发现这个答案
如何获得UTF-8在Java中的webapps工作? 。
这一切都在tomcat连接器设置的URIEncoding =“UTF-8”。
我们如何做到这一点,我们使用CMS搞清楚(CQ5 /日)。