天天看點

java中文亂碼解決之道(四)—–java編碼轉換過程

java編碼轉換過程

我們總是用一個java類檔案和使用者進行最直接的互動(輸入、輸出),這些互動内容包含的文字可能會包含中文。無論這些java類是與資料庫互動,還是與前端頁面互動,他們的生命周期總是這樣的:

1、程式員在作業系統上通過編輯器編寫程式代碼并且以.java的格式儲存作業系統中,這些檔案我們稱之為源檔案。

2、通過jdk中的javac.exe編譯這些源檔案形成.class類。

3、直接運作這些類或者部署在web容器中運作,得到輸出結果。

這些過程是從宏觀上面來觀察的,了解這個肯定是不行的,我們需要真正來了解java是如何來編碼和被解碼的:

第一步:當我們用編輯器編寫java源檔案,程式檔案在儲存時會采用作業系統預設的編碼格式(一般我們中文的作業系統采用的是gbk編碼格式)形成一個.java檔案。java源檔案是采用作業系統預設支援的file.encoding編碼格式儲存的。下面代碼可以檢視系統的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格式傳回給作業系統并輸出到界面去。整個流程如下:

java中文亂碼解決之道(四)—–java編碼轉換過程

在上面整個流程中,凡是涉及的編碼轉換都不能出現錯誤,否則将會産生亂碼。

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編碼格式。整個過程流程圖如下:

java中文亂碼解決之道(四)—–java編碼轉換過程

3.資料庫部分

我們知道java程式與資料庫的連接配接都是通過jdbc驅動程式來連接配接的,而jdbc驅動程式預設的是iso-8859-1編碼格式的,也就是說我們通過java程式向資料庫傳遞資料時,jdbc首先會将unicode編碼格式的資料轉換為iso-8859-1的編碼格式,然後在存儲在資料庫中,即在資料庫儲存資料時,預設格式為iso-8859-1。

java中文亂碼解決之道(四)—–java編碼轉換過程

<a href="http://cmsblogs.com/?p=1475">原文連結</a>