JAVA中文编码问题总结

来源:互联网 发布:戒烟软件 编辑:程序博客网 时间:2024/05/30 07:13

中文编码常用的是GBK(兼容GB2312)和Unicode(Universal Code 统一码),Unicode是Java和XML的基础。

 

其中UTF-16是采用一种定长的方式,每两个字节表示一个字符;这种方式比较简单,大大简化了字符串操作,所以Java以UTF-16作为内存中字符的存储格式。

 

UTF-8则是一种变长技术,不同类型的字符可以由1~6个字节组成,有如下的编码规则:

1、一个字节,最高位为0,则表示这是一个ASCII字符(00~7F);

2、一个字节,以11开头,则连续的1的个数暗示这个字符的字节数,例如:110xxxxx代表它是双字节字符的首字节;

3、一个字节,以10开头,表示它不是首字节,需要向前查找首字节。

 

UTF-8编码适合网络传输,在编码效率上介于GBK和UTF-16之间,总体来说是最理想的中文编码方式。

 

Tomcat编码配置 

<Connector URIEncoding="UTF-8" useBodyEncodingForURI="true"/>,其中URIEncoding是针对URI解码,useBodyEncodingForURI是针对QueryString使用BodyEncoding解码。

 

JS中的编码问题

JavaScript中的编解码函数为encodeURIComponent和decodeURIComponent,分别对应Java端的java.net.URLEncoder和java.net.URIDecoder。

在某些情况下,前端使用encodeURIComponent编码,后台解码也会出现乱码,出现这种情况是因为JS一般采用UTF-8编码(与浏览器相关),服务端解码采用GBK或GB2312解码;一种简单粗暴的解决办法是前端使用encodeURIComponent进行两次编码,如encodeURIComponent(encodeURIComponent(str))。

这样做的原因参考了另一篇博文:

两次encodeURIComponent是因为第一次encodeURIComponent的时候出现了"%",这个符号在解析参数的时候是无法解析的,必须把"%"也进行编码,"%"编码后就是"%25",这样就不会出现问题了。

一般情况下, 发送 encodeURIComponent(parmeName)+"="+encodeURIComponent(parmeValue);
接收时, 直接 String paramValue = request.getParameter(paramName); // 容器自动解码.

我们知道 encodeURIComponent 使用的是 UTF-8 编码规则来编的.
如果 request.getParameter(paramName) 时,容器也按 UTF-8 解的话,是正确的. 根本无须在客户端
进行二次的 encodeURIComponent(...)

如果 request.getParameter(paramName)没有按 UTF-8 解的话, 结果就是乱码;
如果你在jsp程序中,能够 request.setCharacterEncoding("UTF-8"),并且修改服务器配置,让容器在解 GET 提交的参数时使用 UTF-8,则客户端提交前不用二次编码, 接收时也只直接使用 request.getParameter(paramName) 即可。

客户端对参数进行二次编码,可以有效避开“提交多字节字符”这个棘手问题。
因为第一次编码,你的参数内容便不带有多字节字符了,成了纯粹的 ASCII字符串(这里用[STR_ENC1]代表这个字符串);
再编一次后,提交,接收时容器自动解一次(容器自动解的这一次,不管是按 GBK 还是 UTF-8 还是 ISO-8859-1 都好,都能够正确得到 [STR_ENC1])
然后,再在程序中实现一次 decodeURIComponent (Java中通常使用 java.net.URLDecoder(***, "UTF-8")) 就可以得到想提交的参数的原值。

示例代码如下:

String content = (String)request.getParameter("content");

content = URLDecoder.decode(content, "UTF-8");

0 0