JAVA中文编码问题总结
2015-04-11 19:53
218 查看
中文编码常用的是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");
其中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");
相关文章推荐
- JAVA编码(中文转码)问题总结
- Java-MySQL中文乱码编码问题总结
- 收藏:jsp中java中文编码问题的个人经验
- java里的中文乱码问题总结。
- 转载:Java中文问题详解,底层编码解剖
- Java中文问题详解,底层编码解剖
- (转)MySQL5.0中文问题及JDBC数据库连接和JSP汉字编码问题解决方法总结
- JAVA与C++::关于JNI中文字符串操作问题总结
- Java中文&编码问题小结(转载)
- Java中文&编码问题小结
- MySQL5.0中文问题及JDBC数据库连接和JSP汉字编码问题解决方法总结
- MySQL5.0中文问题及JDBC数据库连接和JSP汉字编码问题解决方法总结
- MySQL5.0中文问题及JDBC数据库连接和JSP汉字编码问题解决方法总结
- 关于中文编码问题及Java中的处理
- Java中文问题详解,底层编码解剖
- JAVA中文问题解决总结
- JAVA中文问题解决总结
- JAVA/J2ME中文编码问题完全解决方案
- jsp中中文编码问题的总结
- JAVA中文编码问题的小体会