new String(request.getParameter("newdefrayItem").getBytes("iso-8859-1"),"GBK")

用了好幾種編碼 全是亂碼,request.setCharacterEncoding("UTF-8");嘗試了好幾種

String newdefrayItem = new String(request.getParameter("newdefrayItem").getBytes("iso-8859-1"),"GBK");也換了幾次編碼方式,最後是String newdefrayItem = new String(request.getParameter("newdefrayItem").getBytes("iso-8859-1"),"GBK");這樣可以。在網上查了下原理,轉了過來

 

tomcat默認全部都是用ISO-8859-1編碼,不管你頁面用什麼顯示,Tomcat最終還是會替你將所有字符轉做ISO-8859-1.那麼,當在另目標頁面再用GBK翻譯時就會將本來錯的編碼翻譯成GBK的編碼,這時的文字會亂碼. 

所以需要先將得到"字符"(不管是什麼)都先用字節數組表示,且使用ISO-8859-1進行翻譯,得到一個在ISO-8859-1編碼環境下的字節數組.例如:AB表示成[64,65].然後再用GBK編碼這個數組,並翻譯成一個字符串. 

那麼我們可以得到一個編碼轉換的過程 
假設:GBK碼("你")->URLencode後變成->(%3F%2F)->Tomcat自動替你轉一次ISO-8859-1->得到( 23 43 68 23 42 68 每一個符號表示爲ISO-8859-1中的一個編碼)->接收頁面--->再轉一次爲ISO-8859-1的Byte數組[23,43,68,23,42,68]--->用GBK再轉爲可讀的文字--->(%3F%2F"---->轉爲("你")

 

除了UTF-16,其它字符集定義時都重複。 

比如漢字“我”,假設它的值是22530(只是假設,具體多少我沒查) 
而日文的“マ”的值也可能是22530(也是假設)或韓文的“?” 

在網絡上傳輸是不能以高字節傳輸,因爲網絡底層最後只認無符號char,相當於Java中的byte,所以 
22530這個int要轉換爲字節數組, 

byte[0] = (22530 >> 8)&0xFF; 
byte[1] = 22530 &0xFF; 
具體多少我沒算,假設是byte[125,231] 

這樣的字節傳到服務端到是表示漢字“我”還是日文的“マ”還是其它狗屁? 
一般通訊協議中會告訴對字符集,比如HTTP在請求時告訴服務端: 
ContentType="xxxxxxxxxx";charset="GKB"; 
這時服務端就知道現在接收到的[125,231]是GKB的“我”而不是其它文字。 

上面是標準的通信過程。但如果有些水平很差的程序員在提交請求時沒有通知服務端字符集,那服務端就沒辦法了。 
只好按最常用的字符集來猜一個默認的。 

這還不錯,最要命的是寫服務器的程序員水平和見識很差時,就要命了。就象寫老版本的TOMCAT的程序員,他自己生在西方,以爲全世界所有人都用的是26個字母加一些符號,所以他不管客戶端提交什麼都按ISO-8859-1來算,結果可想而知。 

沒辦法,誰讓我們用GBK的人不會寫tomcat呢,只好先把讓那個差勁的程序員錯誤生成的String用ISO-8859-1還原成 
[125,231],再重新用GKB生成String.

用於得到服務器傳來的字符重新生成GBK編碼


下面的例子是做的模擬:

public class GetLuanMa {
   public static void main(String[] args) throws Exception {
       System.out.println("\t------JSP模擬------");
       System.out.println("客戶端,有一箇中文字符的請求(轉換成了字節序列發送),發送至服務器端");
       String request="請求";
       byte[] client=request.getBytes();//客戶端的請求的字節序列
       print(client);
       System.out.println();//分割用的
       System.out.println("有一中間件,將發送的字符序列以默認的編碼格式(iso-8859-1)進行解碼");
       String sever=new String(client,"iso-8859-1");
       System.out.println(sever);
       
       /*System.out.println("haha: "+new String(sever.getBytes("iso-8859-1")));
       print(new String(sever.getBytes("iso-8859-1")).getBytes());
       System.out.println();*/
       
       System.out.println("程序猿發現,這邊有問題,中文有亂碼,前來解決!");
       
String debug=new String(sever.getBytes("iso-8859-1"),"UTF-8");//還原字節序列,使用“UTF-8”重新進行解碼!
       System.out.println(debug);
       System.out.println("問題解決!");
   }
   public static void print(byte[] b){//用於顯示字節序列的
       for(byte b1:b){
           System.out.print(Integer.toHexString(b1 & 0xff)+" ");
       }
   }
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章