java new String getBytes 到底怎麼轉換字符集的問題

我們常常遇到字符集轉換的問題。

我要說的當然不是網站中遇到的ISO8859-1的那個傻BUG。

實例:

目標,把一個UTF-8的中文字符串轉化成GBK的字符串。

新建一個GBK的java項目。

也就是說*.java文件中的字符是用GBK字符集保存的。

在main中,建一箇中文字符串,那麼這個靜態串就是GBK字符。

再把它的屬性,字符集改成UTF-8後,變成這樣了。

 

然後,我們再建一個UTF-8的java項目。

在main中寫入以下:

String str = "新建文本文檔.txt";
  System.out.println(str);
  byte[] bs = null;
  try {
   bs = str.getBytes("UTF-8");
  } catch (UnsupportedEncodingException e1) {
   e1.printStackTrace();
  }
  System.out.print( "UTF-8: \n");
  for(int i=0;i<bs.length;i++){
   System.out.print( bs[i] + " ");
  }
  System.out.println();
  try {
   String tempStr ="";

   bs = str.getBytes("GBK");
   System.out.print( "GBK: \n");
   for(int i=0;i<bs.length;i++){
    System.out.print( bs[i] + " ");
   }
   System.out.println();
   System.out.println();

   tempStr = new String(bs,"GBK");
   System.out.println( "用UTF-8打印,這個GBK串(通過GBK重組後的): "+ tempStr );

   tempStr = new String(bs,"UTF-8");
   System.out.println( "用UTF-8打印,這個GBK串(通過UTF-8重組後的): "+ tempStr );

   System.out.print( "再把這個串"+tempStr+"轉成UTF-8數組打印: \n");
   bs = tempStr.getBytes("UTF-8");
   for(int i=0;i<bs.length;i++){
    System.out.print( bs[i] + " ");
   }
   System.out.println();


  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  }

 

得到的輸入:

很明顯,通過GBK重組後的字符串,打印出來的是明文,與我們原選做的測試完全不一樣。

也就是說他根本沒有被轉碼。

而通過UTF-8重組後的字符串,打印出來的才與我們原先看到的測試是一樣的。

這纔是真正的轉碼成功了。

 

這是爲什麼呢?

JDK幫助的描述是這樣的。

getBytes(Charset charset) 
使用給定的 charset 將此 String 編碼到 byte 序列,並將結果存儲到新的 byte 數組。

String(byte[] bytes, Charset charset) 
通過使用指定的 charset 解碼指定的 byte 數組,構造一個新的 String。

 

應該這樣理解:

getBytes是真正的在轉碼。

而new String是把它用某種碼來顯示。

像上面的那串亂碼,它正在已經是GBK碼了,用GBK顯示正常,用UTF-8顯示是亂碼。

但,現在我們是在UTF-8環境下,所以要用UTF-8存字符串,最後把這個串輸出給讀它的平臺。

你可以用,Xshell 的兩種字符集環境來打印以上的輸出。

在GBK連接的方式中,那串亂碼被正常顯示出來。

 

你感興趣,還可以把這個例子反過來做一下,看是不是你想要的結果。

 

同時,我們再來理解一下tomcat中爲什麼要做這樣一件事:

new String(str.getBytes("ISO-8859-1"),"gb2312"); 

這是因爲,默認情況下,tomcat使用的是iso8859-1的編碼方式傳遞。

而網頁中設定的比如是gb2312或utf-8。這樣得到的就是錯的。

所以用ISO-8859-1得到字節流,再用gb2312來重組字節流得到gb2312的字符串流。

 

解決辦法:

修改tomcat下的conf/server.xml文件
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
修改爲: 
<Connector port="8080" useBodyEncodingForURI="true" URIEncoding="UTF-8" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

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