java中文亂碼解決之道(四)-----java編碼轉換過程,java-----java
前面三篇部落格側重介紹字元、編碼問題,通過這三篇部落格各位博友對各種字元編碼有了一個初步的瞭解,要瞭解java的中文問題這是必須要瞭解的。但是瞭解這些僅僅只是一個開始,以下部落格將側重介紹java亂碼是如何產生的、存在哪些亂碼的情況、該如何從根本上解決亂碼問題。各位隨博主一起征服令人厭煩的java亂碼問題吧!!!
java編碼轉換過程
我們總是用一個java類檔案和使用者進行最直接的互動(輸入、輸出),這些互動內容包含的文字可能會包含中文。無論這些java類是與資料庫互動,還是與前端頁面互動,他們的生命週期總是這樣的:
1、程式員在作業系統上通過編輯器編寫程式碼並且以.java的格式儲存作業系統中,這些檔案我們稱之為源檔案。
2、通過JDK中的javac.exe編譯這些源檔案形成.class類。
3、直接運行這些類或者部署在WEB容器中運行,得到輸出結果。
這些過程是從宏觀上面來觀察的,瞭解這個肯定是不行的,我們需要真正來瞭解java是如何來編碼和被解碼的:
第一步:當我們用編輯器編寫java源檔案,程式檔案在儲存時會採用作業系統預設的編碼格式(一般我們中文的作業系統採用的是GBK編碼格式)形成一個.java檔案。java源檔案是採用作業系統預設支援的file.encoding編碼格式儲存的。下面代碼可以查看系統的file.encoding參數值。
System.out.println(System.getProperty("file.encoding"));
第二步:當我們使用javac.exe編譯我們的java檔案時,JDK首先會確認它的編譯參數encoding來確定原始碼字元集,如果我們不指定該編譯參數,JDK首先會擷取作業系統預設的file.encoding參數,然後JDK就會把我們編寫的java來源程式從file.encoding編碼格式轉化為JAVA內部預設的UNICODE格式放入記憶體中。
第三步:JDK將上面編譯好的且儲存在記憶體中資訊寫入class檔案中,形成.class檔案。此時.class檔案是Unicode編碼的,也就是說我們常見的.class檔案中的內容無論是中文字元還是英文字元,他們都已經轉換為Unicode編碼格式了。
在這一步中對對JSP源檔案的處理方式有點兒不同:WEB容器調用JSP編譯器,JSP編譯器首先會查看JSP檔案是否設定了檔案編碼格式,如果沒有設定則JSP編譯器會調用調用JDK採用預設的編碼方式將JSP檔案轉化為臨時的servlet類,然後再編譯為.class檔案並保持到臨時檔案夾中。
第四步:運行編譯的類:在這裡會存在一下幾種情況
1、直接在console上運行。
2、JSP/Servlet類。
3、java類與資料庫之間。
這三種情況每種情況的方式都會不同,
1.Console上啟動並執行類
這種情況下,JVM首先會把儲存在作業系統中的class檔案讀入到記憶體中,這個時候記憶體中class檔案編碼格式為Unicode,然後JVM運行它。如果需要使用者輸入資訊,則會採用file.encoding編碼格式對使用者輸入的資訊進行編碼同時轉換為Unicode編碼格式儲存到記憶體中。程式運行後,將產生的結果再轉化為file.encoding格式返回給作業系統並輸出到介面去。整個流程如下:
在上面整個流程中,凡是涉及的編碼轉換都不能出現錯誤,否則將會產生亂碼。
2.Servlet類
由於JSP檔案最終也會轉換為servlet檔案(只不過儲存的位置不同而已),所以這裡我們也將JSP檔案納入其中。
當使用者請求Servlet時,WEB容器會調用它的JVM來運行Servlet。首先JVM會把servlet的class載入到記憶體中去,記憶體中的servlet代碼是Unicode編碼格式的。然後JVM在記憶體中運行該Servlet,在運行過程中如果需要接受從用戶端傳遞過來的資料(如表單和URL傳遞的資料),則WEB容器會接受傳入的資料,在接收過程中如果程式設定了傳入參數的的編碼則採用設定的編碼格式,如果沒有設定則採用預設的ISO-8859-1編碼格式,接收的資料後JVM會將這些資料進行編碼格式轉換為Unicode並且存入到記憶體中。運行Servlet後產生輸出結果,同時這些輸出結果的編碼格式仍然為Unicode。緊接著WEB容器會將產生的Unicode編碼格式的字串直接發送置用戶端,如果程式指定了輸出時的編碼格式,則按照指定的編碼格式輸出到瀏覽器,否則採用預設的ISO-8859-1編碼格式。整個過程流程圖如下:
3.資料庫部分
我們知道java程式與資料庫的串連都是通過JDBC驅動程式來串連的,而JDBC驅動程式預設的是ISO-8859-1編碼格式的,也就是說我們通過java程式向資料庫傳遞資料時,JDBC首先會將Unicode編碼格式的資料轉換為ISO-8859-1的編碼格式,然後在儲存在資料庫中,即在資料庫儲存資料時,預設格式為ISO-8859-1。
-----原文出自:http://cmsblogs.com/?p=1475,請尊重作者辛勤勞動成果,轉載說明出處.
-----個人網站:http://cmsblogs.com