一、图像?文字?
当我门在电脑屏幕上看到“中国”时,毫无疑问我们看到是两个字,就像你在纸上写的一样,但是对计算机而言,这是计算机显示的图像,是由像素组成的。和你看到的普通图片一样,计算机需要你告送它怎样绘制“中国”图片。屏幕可以看做是二维坐标系,只要你告送计算“中国”的所有坐标就可以在屏幕上看到“中国”两个字。想象一下“中国”可能由上百个坐标点组成,要是手动输入计算机,会是多么痛苦的事。文字编码就是为了解决这个问题而开发出来的。
二、文字编码
文字编码其实就是计算机文字坐标数据和数字(二进制)建立起映射,只要告送计算机数字,通过文字编码程序,找到对应的文字坐标数据,将数据传给计算机,便能在屏幕上显示出文字。举个例子,在windows写入和读取文本文件过程
- 写入:中国windows默认gbk编码,所以你在写入的时候,实际上是往内存里写入gbk编码值(二进制),然后文字编码程序会展示给你编码后文字。
- 保存:把内存中gbk值写到硬盘
- 读取:从硬盘读取gbk值,通过文字编码程序显示出文字
三、常见的编码
编码 | 字节数 | 字符数 | 说明 |
---|---|---|---|
ASCII | 1 | 128 | 一个字节,只用了后7位,最高位0 |
ISO-8859-1/Latin1 | 1 | 256 | 用满8位 |
GB2312 | 2 | 6763 | 中国发布了第一个汉字编码标准 |
GBK | 2 | 23940 | 在 GB2312基础上 拓展 |
GB18030 | 2 | 70,244 | 在 gbk基础上 拓展 |
UTF8 | 1-4 | 汉字三字节表示,英文一字节表示 | |
UTF-16 | 2 | 2字节表示,java用次编码存储字符 |
还有一个特殊编码Unicode,只定义了映射关系。简单的说unicode码不会直接存储在内存和硬盘上,也不会直接用于传输。他有一个很大的用处,unicode和上述编码值存在映射关系,可以实现上述编码间的相互转换。Unicode的存储和传输会用UTF-8、UTF-16等来完成。
四、编码问题
-
ISO-8859-1的特性
public class Test3 { public static void test() { } public static void main(String[] args) throws Exception { System.out.println("utf-8->gbk->utf-8 字符失真"); String k = "一个"; String gbk = new String(k.getBytes("utf-8"), "gbk"); System.out.println(gbk); System.out.println(new String(gbk.getBytes("gbk"), "utf-8")); System.out.println("utf-8->ISO-8859-1->utf-8 字符不失真"); String iso = new String(k.getBytes("utf-8"), "ISO-8859-1"); System.out.println(iso); System.out.println(new String(iso.getBytes("ISO-8859-1"), "utf-8")); } }
运行结果
utf-8->gbk->utf-8 字符失真 涓�涓� �?�? utf-8->ISO-8859-1->utf-8 字符不失真 一个 一个
非utf-8字节流在转换为utf-8时丢失字节的某些位,造成最终无法还原,ISO-8859-1编码的结果是乱码,但是没丢字节位,所以能够被还原。因为ISO-8859-1可以使用字节的所有位,所以才有这个特性,其他编码都没有使用所有位,所以没有这个特性。
-
浏览器编码和tomcat配置URIEncoding=“”
String r=req.getParameter("test");//使用的是tomcat URIEncoding设置的值 byte[] bs=r.getBytes( tomcat uriecoding); System. out.println(r); //1 System. out.println( new String(bs, 浏览器get请求编码));//2
运行结果:
浏览器get请求编码 | tomcat uriecoding | servlet代码结果 |
---|---|---|
utf-8 | iso-8859-1 | 1错误2正确 |
gbk | utf-8 | 1错误2错误 |
utf-8 | utf-8 | 1正确2正确 |
总结:第三次测试毫无疑问,第一、第二次测试结果,可以用第一个例子来理解
-
servlet 编码说明
- tomcat配置URIEncoding=“”:只是uri的编码方式即get请求编码方式。不能决定请求体的编码方式。
- request.setCharacterEncoding(“utf-8”); 设置的是获取请求“数据体(body)”使用的编码方式
- response.setContentType(“text/plain;chartset=UTF-8”):告送浏览器用utf-8来解析收到的内容。浏览器只能通过响应头的编码信息来解析内容。如果没有则用默认的浏览器编码解析。
-
urL 编码
url 编码和该文章所说编码不是一个东西,其类似对特殊字符的转义。