前面三篇博客側重介紹字符、編碼問題,經過這三篇博客各位博友對各類字符編碼有了一個初步的瞭解,要了解java的中文問題這是必需要了解的。可是瞭解這些僅僅只是一個開始,如下博客將側重介紹java亂碼是如何產生的、存在哪些亂碼的狀況、該如何從根本上解決亂碼問題。各位隨博主一塊兒征服使人厭煩的java亂碼問題吧!!!前端
咱們老是用一個java類文件和用戶進行最直接的交互(輸入、輸出),這些交互內容包含的文字可能會包含中文。不管這些java類是與數據庫交互,仍是與前端頁面交互,他們的生命週期老是這樣的:java
一、程序員在操做系統上經過編輯器編寫程序代碼而且以.java的格式保存操做系統中,這些文件咱們稱之爲源文件。程序員
二、經過JDK中的javac.exe編譯這些源文件造成.class類。數據庫
三、直接運行這些類或者部署在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編碼格式了。3d
在這一步中對對JSP源文件的處理方式有點兒不一樣:WEB容器調用JSP編譯器,JSP編譯器首先會查看JSP文件是否設置了文件編碼格式,若是沒有設置則JSP編譯器會調用調用JDK採用默認的編碼方式將JSP文件轉化爲臨時的servlet類,而後再編譯爲.class文件並保持到臨時文件夾中。code
第四步:運行編譯的類:在這裏會存在一下幾種狀況
一、直接在console上運行。
二、JSP/Servlet類。
三、java類與數據庫之間。
這三種狀況每種狀況的方式都會不一樣,
這種狀況下,JVM首先會把保存在操做系統中的class文件讀入到內存中,這個時候內存中class文件編碼格式爲Unicode,而後JVM運行它。若是須要用戶輸入信息,則會採用file.encoding編碼格式對用戶輸入的信息進行編碼同時轉換爲Unicode編碼格式保存到內存中。程序運行後,將產生的結果再轉化爲file.encoding格式返回給操做系統並輸出到界面去。整個流程以下:
在上面整個流程中,凡是涉及的編碼轉換都不能出現錯誤,不然將會產生亂碼。
因爲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程序與數據庫的鏈接都是經過JDBC驅動程序來鏈接的,而JDBC驅動程序默認的是ISO-8859-1編碼格式的,也就是說咱們經過java程序向數據庫傳遞數據時,JDBC首先會將Unicode編碼格式的數據轉換爲ISO-8859-1的編碼格式,而後在存儲在數據庫中,即在數據庫保存數據時,默認格式爲ISO-8859-1。
-----原文出自:http://cmsblogs.com/?p=1475,請尊重做者辛勤勞動成果,轉載說明出處.
-----我的站點:http://cmsblogs.com