JAVA與編碼

壹頁書發表於2013-12-12
JAVA很容易出現亂碼...具體分析以下幾個環節的編碼。

1.編譯
    JAVA原始檔可能是GBK編碼也可能是UTF8編碼,使用javac命令編譯的時候,會使用作業系統預設的編碼編譯檔案。
    如果平臺是windows,而原始檔是UTF8編碼,則遇到了第一個亂碼問題。
    這時候可以使用javac命令的encoding選項,標明原始檔的編碼格式。
    經過編譯之後,JAVA位元組碼檔案以UTF8編碼儲存在class檔案中。    
    
    -encoding             指定原始檔使用的字元編碼

2.執行
    JAVA在執行時,採用unicode編碼,JAVA系統內部不存在亂碼問題。
    但是輸入輸出還是依賴外部編碼。預設使用作業系統的預設編碼。
    也可以指定file.encoding引數。
    如果設定了file.encoding引數,System.in、System.out、string.getBytes()等都會使用這個設定的編碼解析資料,否則使用平臺的預設編碼。
    
  1. public class Test {
  2.     public static void main(String[] args) {
  3.         String data="中文";
  4.         System.out.println(Charset.defaultCharset());
  5.         System.out.println(data);
  6.     }
  7. }
    平臺是windows系統,預設編碼為GBK,可以看到不同的file.encoding引數導致執行結果的不一樣。


3.JDBC編碼
    因為JAVA系統執行時採用unicode編碼,如果資料庫採用GBK或者utf8編碼,則可能出現亂碼問題。
    Oracle資料庫採用唯一編碼,oracle的jdbc會自動將unicode轉換為目標Oracle資料庫的編碼。
    而Mysql可以同時使用多種編碼,所以需要在Mysql JDBC的url中指定目標資料庫的編碼。

4.URL編碼
    如果需要在URL中傳輸中文引數,除了JS兩次編碼的方式,也可以使用如下方式。

  1. public class Test {
  2.     public static void main(String[] args) throws UnsupportedEncodingException {
  3.         // 模擬瀏覽器將中文引數編碼
  4.         String data = "%E4%B8%AD%E6%96%87%E8%AF%B7%E6%B1%82";

  5.         // 模擬Tomcat使用預設URIEncoding解碼[ISO-8859-1]
  6.         data = URLDecoder.decode(data, "ISO-8859-1");
  7.         System.out.println(data);
  8.         
  9.         //模擬在doGet中獲取引數
  10.         data=new String(data.getBytes("ISO-8859-1"),"utf8");
  11.         System.out.println(data);
  12.     }
  13. }
執行結果如下:
    ??????è?·?±?
    中文請求
    
    兩次JS編碼方式參見:http://blog.itpub.net/29254281/viewspace-775925/
    詳細資料:http://blog.csdn.net/feihong247/article/details/7841237

5.關於指定編碼
    無論是Spring的CharacterEncodingFilter還是request的setCharacterEncoding,都是為byte[]指定解碼的規則,而不是轉換。

  1. public class Test {
  2.     public static void main(String[] args) throws UnsupportedEncodingException {
  3.         byte[] data = "中".getBytes("utf8");
  4.         System.out.println(new String(data, "utf8"));
  5.         System.out.println(new String(data, "gbk"));
  6.         //執行結果:
  7.         //
  8.         //涓?
  9.     }
  10. }


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1063133/,如需轉載,請註明出處,否則將追究法律責任。

相關文章