1. 程式人生 > >關於Tomcat中亂碼的產生原因詳解

關於Tomcat中亂碼的產生原因詳解

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對應的漢字,找來了不對應的一些奇怪的東西,此時無論怎麼轉都轉不回去了 -------------------------------------------------------------------------------------------------------