java字符编码

     近来在看java的字符编码,有过Java web编程经验的人应该都知道,Java国际化的编码问题对菜鸟一直是个噩梦,经常一不小心又一堆乱码跑出来,而你还一头雾水,甚至统一用某种编码格式了(比如UTF-8),还是会乱码,而且是一个页面内有些乱码有些正常,让人痛不欲生。网上相关文章也不少了,这里主要说一下自己对字符编码(不仅仅是Java)的理解,如有错误,恳请高手指正
     下面的内容参考张孝祥的《深入体验Java web开发内幕——核心基础》,这里顺便宣传一下,的确是一本好书,内容很详细,不是随便拼凑而是作者的经验之谈,适合有空的初学者,对打好扎实的web编程基础很有好处。
     首先,一句简单的 String s = "中国",对Java来说,就是以UNICODE格式存放在内存中(Java的内置编码格式统一为Unicode),用十六进制就是 4e2d 56fd,因为每个中文在unicode下是两个字节。再来一句:byte[] gb = s.getBytes("gb2312"),那么这个gb数组的内容就是 d6d0 b9fa 。我们平时所说的“编码转换”,例如把gb2312的字符转成utf8,其实是根据这两种编码之间的映射关系,改变底层的那些0和1。当你把内存中的字符串输出到本地文件保存时,系统自动把unicode编码转换成你本地的编码格式(中文系统通常是gb2312);而当你的操作系统要把文件中的这些本质上是0和1的数据,以文字的形式显示在屏幕上时,它首先要知道这一串0和1是什么编码的,然后利用系统中的相应字体文件,把0和1映射成屏幕相应的文字图形,交给显示设备显示。
     所以,如果你把一个原本是以gb2312格式保存在文件中的字符,以其他不兼容的格式显示时,理所当然就会乱码了,就好像把中文的发音硬是按照英文来理解。例如,给你一个byte数组,里面是“中国”的gb2312编码,然后你以“ISO8859-1”的格式(用于拉丁字符,一个字符对应一个字节,不支持中文)读取,就会把“d6”当成一个拉丁字符,再把“d0”当成一个字符,如此类推,最后总共得到四个字符,而且显示出来全部乱码。而且,在Java中,“把一个gb2312的字符串以ISO格式读取”,意思是把该字符串当作是iso格式的,然后一个个字符转换成unicode编码,保存回内存中,所以,上面的“中国”,最后以iso格式读入时,保存在内存中的十六进制实际上是:“00d6 00d0 00b9 00fa”。这是因为系统把“d6”这个字节,当成一个iso字符,而iso转换成unicode只要在前面加上一个“00”的字节就可以了,其他的也是同样道理。
     对于转换错误的字符,要改回正确的,应该如何处理呢?因为字符编码直接的转换是可逆的,所以我们把上面的“00d6 00d0 00b9 00fa”,从unicode转回iso去,得到d6d0 b9fa,再把它按照gb2312进行读取,重新保存成“4e2d 56fd”这个正确的“中国”的unicode编码
     以上只是说了字符编码的一些基本内容,在实际使用中,还有很多地方会影响编码,比如servlet中request和response都可以设置编码类型,这将影响输入和输出的字符格式;而如果用到forward或者redirect时,对于字符编码的设置又有很多细节方面的不同;而在客户端这边,浏览器的编码设置既可以影响浏览网页的效果,也可以影响提交的数据的编码格式(比如以get模式提交的内容格式就和浏览器的编码设置有关);同时,html文件中contentType属性,还有meta标签的内容,均会对浏览效果有影响 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值