深入分析Java Web中的中文编码问题

深入JAVA WEB 内幕学习系列 三、 深入分析Java Web中的中文编码问题

一、为什么要编码

  1. 在计算机中存储信息的最小单元是一个字节,即8bit,所以最多能表达的字符范围是0-255个
  2. 人类使用的符号太多,无法用一个字节完全表示
  3. 因此需要一个新的数据结构char ,从char到byte必须编码

二、 常见编码

  1. ASCII 码
    总共128个,用1个字节的低7位表示,0-31是控制字符,如回车、换行,32-126是打印字符,可以通过键盘输入并且能够表示出来。
  2. ISO-8859-1
    单字节8位编码,可以表示256个字符。
  3. GB2313
    双字节编码,包含6763个字符。
  4. GBK
    为了扩展GB2312,同时兼容GB2312。用GB2312编码的汉字可以用GBK解码。
  5. GB18032
    国标,与GB2312兼容,但实际应用并不广泛。
  6. UTF-16
    统一码,使用两个定长字节表示。
  7. UTF-8
    采用变长两个字节表示。

编码之间的比较:
GBK比BG2312能够处理更多的汉字,两者之间选择GBK.UTF-8与UTF-16相比,UTF-16编码效率更高,从字符到字节的转换更简单,进行字符操作也更好,适合本地磁盘合内存之间的编码,但不适合在网络间传输,因为网络传输中容易损坏字节流,一旦字节流损坏将很难回复,所以相比较UTF-8更适合网络传输,因为UTF-8对ASCII字符采用单字节存储,单个字符损坏不会影响后面的,编码效率介于GBK与UTF-16,因此UTF-8是比较理想的中文编码。

三、 Java Web中涉及的编码

用户从浏览器端发起一个HTTP请求,需要存在编码的地方是URL、Cookie、Paramiter。服务器端可能还需要读取数据中的数据,本地或网络中其它地方的文本文件,都有可能存在编码问题。

3.1 URL的编解码

URL和URI 分别对应的是Servlet中的request.getRequestURL()和request.getRequestURI(),Port对应在Tomcat的中配置,而ContextPath 在

3.2 POST表单的编解码

提交表单时,浏览器首先会根据ContentType的编码格式进行编码,然后提交到服务端,服务端根据ContentType的编码字符集进行解码,所以一把不会出现乱码,而且我们自己可以设置整个字符集request.setCharacterEncoding(charset)来设置;
注意该方法必须在第一次调用request.getParameter()之前,调用,因为request.getParameter()会进行解码,这时我们设置的字符集还没生效,默认使用ISO8859-1解码,导致出现乱码。
为什么request.setCharacterEncoding(charset)对GET请求的参数不生效,因为get请求的编码是根据浏览器的设置进行编码,一般为UTF-8.而解码默认不使用ContentType的字符集,而是使用ISO8859-1,所以即便通过request.setCharacterEncoding(charset)设置了字符集,对GET请求的参数一样不生效,我们可以通过将connector中的中的useBodyEncodingForURI设置为true,来使用ContentType的字符集进行解码。对get请求的参数,我们需要对其使用ISO8859-1重新编码,然后使用UTF-8进行解码,即可解决乱码问题。

3.3响应乱码问题

我们可以使用response.setCharacterEncoding(charset)来设置,如果没有进行设置ContentType的字符集,默认使用HTML页面的字符集。
如果是数据库,我们可以通过设施JDBC URL来指定例如在后面加上characteEncoding=utf-8。

3.4 JS的URL编码

JS中处理URL编码的函数有三个,掌握了这三个函数就能基本处理JS中的URL乱码问题。
1、escape();
这个函数是将ASCII字母、数字、标点符号之外的其它字符进行Unicode编码并在编码值前加%u。
在最新的ECMAScript v3标准中已经将该方法删除,使用下面的两个方法进行替代。
2、encodeURI()
编码字符范围更多,使用UTF-8编码。
3、encodeURIComponent()和decodeURIComponent()
这两个函数对应的分辨是编码和解码,比encodeURI()编码更加彻底,这个函数通常是为了将一个URL当作参数放在另一个URL中,如果不进行编码,后面URL中的&附后会影响前面URL的完整性,而encodeURI()方法做不到。

3.5 JAVA与JS的编解码问题

JAVA中对应的URL编解码有两个类URLEncoder和URLDecoder ,这两个类使用的是服务器的字符集进行编解码。如果使用encodeURIComponet()进行编码,到服务端使用URLDecoder解码有可能出现乱码,因为前端使用的是UTF-8编码,而服务端有可能是GBK或者GB2313。解决办法是使用encodeURIComponet()两次编码即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值