关于Tomcat中乱码的产生原因详解

来源:互联网 发布:淘宝助理手机版最新 编辑:程序博客网 时间:2024/05/23 01:22
getBytes() 与 getBytes(String charset)
无参表示当前平台默认字符集
该方法的作用即,拿着你给的字符串,去指定的码表中查找其对应的字节数组

对于在码表中查找不到的,统一给你个?
这个?对应字节63,你会经常看到的

System.out.println(Arrays.toString(s.getBytes("iso-8859-1")));//[63, 63]
西欧码表中根本没有中文,你拿这两个字去找,肯定给你两个问号啊
----------------------------------------------------------------------------

数据存储的过程:
比如将“中国”存入Tomcat服务器中
第一步,对中国调用getBytes()方法,假如是utf-8格式对应
[-28, -72, -83, -27, -101, -67],假如是gbk格式,对应的是[-42, -48, -71, -6]
第二步,拿着这个字节数组去西欧码表ISO8859-1中按它的规则查找对应的字符
分别对应 ä¸­å½ 和 Öйú
第三步,将查到的字符存起来(前后过程对应的字节数组是没有变化)
上述过程的代码表现形式即:
String s1 ="中国";
String s2 = new String(s1.getBytes(),"iso8859-1");
数据取出的过程:
不做任何处理,必出乱码,其代码表现形式
String s3 =new String(s2.getBytes("iso8859-1"),"iso8859-1");
正确处理方式
String s3 = new String(s2.getBytes("iso8859-1"),"utf-8")
再次得到“中国”
---------------------------------------------------------------------------
以上述原理解释,为什么gbk转不回utf8
String s1 ="中国";
String s2 = new String(s1.getBytes(),"utf-8");
System.out.println(s2); // ?й?
它在这一步就出了问题,也就是说拿着[-28, -72, -83, -27, -101, -67]去GBK码表中找对应字符的时候,它连这个对应的字符都找不到,比如说-28,-72这两个字节不对应任何一个字符,这时候,它就扔了个问号?过来。这个过程中,对字节数组的内容产生了改变,再想通过这个机制转回来是不可能实现的了
----------------------------------------------------------------------------
编码:将看得懂的变成看不懂的
解码:将看不懂的变成看得懂的
乱码出现的原因:编码方式与解码方式不一致
我们当前系统默认编码方式为gbk


String 类支持在创建时 按照指定编码方式创建String对象,
如public byte[]getBytes()
public byte[]getBytes(String charsetname)
使用平台的默认字符集或指定字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中


也可以将其他基本类型以指定的编码格式进行解码
如String(byte[] bytes,Charset charset)
通过使用指定的charset 解码指定的 byte 数组,构造一个新的 String
------------------------------------------------------------------------------------------
getBytes()方法不存在正确错误的概念,重新编码而已,与被编码对象是什么原编码方式无关。只要保证解码过程对应正确就不会乱码
------------------------------------------------------------------------------------------

错误的编解码方式
String s1 = "你好"; //当前的eclipse平台默认编码方式为gbk时
String s2 = new String(s1.getBytes("utf8"),"gbk");
System.out.println(s2); //浣犲ソ
System.out.println(Arrays.toString(s2.getBytes("gbk")));//[-28, -67, -96, -27, -91, -67]
String correctS2 = new String(s2.getBytes("gbk"),"utf8");
System.out.println(correctS2); //你好
String s3 = new String(s1.getBytes("gbk"),"utf-8");
System.out.println(s3);//???
System.out.println(Arrays.toString(s3.getBytes("gbk"))); //[63, 63, 63]
System.out.println(Arrays.toString(s3.getBytes("utf8")));//[-17, -65, -67, -17, -65, -67, -17, -65, -67]
String correctS3 = new String(s3.getBytes("utf8"),"gbk");
System.out.println(correctS3); //锟斤拷锟?
//s2能正确转换是因为转换过程中,字节数组对应的值没有变化,2个汉字6个字节的utf8编码能找到对应的3个汉字6字节gbk编码
//s3在转换过程中,字节数组发生了变化,2个汉字4个字节的gbk编码无法找到对应的utf-8对应的汉字,找来了不对应的一些奇怪的东西,此时无论怎么转都转不回去了
-------------------------------------------------------------------------------------------------------