jsp教程:深入分析 JSP/Serverlet中的編碼問題

時間:2012-12-02 10:25來源:我愛IT技術網 作者:52ij 點擊: 158 次
(1) jsp頁面中的pageEncoding: 指定jsp編寫時所用的編碼(源文件編碼) 如果你用的是win98或winme的記事本來編寫的jsp, 則一定是常用的big5或gb2312; 如果用的是win2000或winXP的記事本時, 保存時就可以選擇不同的編碼,包括ANSI(BIG5/GB2312)、UTF-8或Unic

 (1)  jsp頁面中的pageEncoding:   指定jsp編寫時所用的編碼(源文件編碼)

JSP/Serverlet中的編碼問題

        如果你用的是win98或winme的記事本來編寫的jsp, 則一定是常用的big5或gb2312;  如果用的是win2000或winXP的記事本時, 保存時就可以選擇不同的編碼,包括ANSI(BIG5/GB2312)、UTF-8或Unicode(utf-16)
(2) jsp頁面中的contentType:   它指定的是jsp頁面最終在客戶端瀏覽器呈現時所見到的內容的編碼。就是mozilla的charactrer encoding或是IE6的encoding等。

Jsp從源文件到最終用戶看到的html文件,會大致經歷如下階段:
①  所編寫的源文件的保存, 由于計算機只能保存二進制形式的內容,而我們所寫的都是字符串形式的內容,所以這里進行的第一個階段即是由字符串到字節的編碼過程,這個階段所采用的就是PageEnco
ding所指定的編碼, 如這時指定的是GBK, 則會將一個漢字拆分成二個字節來保存,如果用的是utf-8則會用三個字節來保存。[jsp頁面的pageEncoding的默認值是iso8859-1]
② 本階段是從.jsp文件中讀取二進制信息并翻譯成.java文件的過程(這一過程由服務器如tomcat在運行
時時完成), 服務器讀取出二進制信息(字節), 然后用其保存時所使用的字符編碼來重新進行解碼,將其還原成原始字串.   這時系統再使用UTF-8對字符串重新進行編碼,并將其得到的字節信息寫入到x.java文件中(這與src中的.java文件不同,src中的.java文件采用的是平臺使用的字符集,而這里統一都用UTF-8)。
③  這一階段是完成從.java文件到源文件.class文件的編譯過程,這時系統會從.java文件中讀出字節數
據,然后直接將其寫入.class文件中,所用編碼方式仍為UTF-8。
④  本階段是由tomcat從class文件中讀取二進制信息,然后通過網絡發送出去, 具體用來實施這個工作的對象是response對象。而這個對象在發送數據前先要將數據根據UTF-8還原成原始字串,然后再按
contentType 所指定的編碼(如果沒設則與pageEncoding一樣)將字串編碼為字節流,然后再通過網
絡發送出去。
⑤  這階段的主要工作將由瀏覽器來完成.  此階段瀏覽器接收到字節流后,要負責將其解碼為字符串,而解碼所使用的字符碼式仍為contentType所指定的編碼方式。
 
      至此用戶就可以看到我們原先寫的字符串了。 其實上面幾步中前面幾步都沒可以省略不看,我們關
鍵要看的是最后兩步(即網絡發送前的編碼和到達瀏覽器后的解碼過程)來看下面幾種情況:
(1) <%@ page pageEncoding="GBK" contentType="text/html; charset=iso8859-1"%>
     假設頁面中有:  <h1>中</h1>
            當走到第4步時,服務器會讀取出字節并正確還原成字符串”<h1>中</h1>”, 這時response在發送前需要先將其變為字節序列,所使用的編碼標準就是iso8859-1(由charset指定), 它會將一個英文解析為一個字節,將一個中文也解析為一個字節,這樣數據在發送前就已經丟失了,所以到達瀏覽器時也必然為少了一個字節了。故我們會看到?輸出.
(2) <%@ page pageEncoding="GBK" contentType="text/html; charset=utf-8"%>
     假設頁面中有:  <h1>中</h1>
     發送前會將所有中文字符編碼為三個字節、英文字母和數字仍為1個字節,然后送出,到瀏覽器后,再用同樣的字符編碼將字節解碼為字符串(中文三個一組),所以數據不會丟失,不會出現亂碼。編碼本身提供了一套標準來識別某個字節是否是中文字符的開始部分.
(3) <%@ page pageEncoding="utf-8" contentType="text/html; charset= GBK"%>
     假設頁面中有:  <h1>中</h1>
     發送前會將所有中文字符編碼為二個字節、英文字母和數字仍為1個字節,然后送出,到瀏覽器后,再用同樣的字符編碼將字節解碼為字符串(中文二個一組),所以數據不會丟失,不會出現亂碼。
 
Jsp向servlet提交數據時的編碼問題:
      前面部分都一致,關鍵問題是字節流到達服務器后的解碼(字節->字符)過程, 與頁面不同的是它不采用contentType指定的字符編碼方式來解碼字節,而是采用服務器(tomcat默認值為iso8859-1)來解析,這樣一個字節就被還原成了一個字符, 這時如果我們的jsp指定的contentType是UTF-8, 就會出現本來是一個字符的三個字節被分別解析成了三個字符,所以亂碼也就產生了。
      我們可以通過手工的方式來設置字節的解碼方式,具體做法是在用request的getParameter方法前調用request的 setCharacterEncoding(“解碼方式”); 將編碼和解碼的碼式設為一致,如前面contentType設置為utf-8, 此處也就設置為utf-8, 這樣信息就能順利還原了。
      注:在tomcat中對于get方式提交的數據不論request的setCharacterEncoding設置的是何種字符編碼方式,服務器均采用ISO8859-1方式對其進行解碼,所以我們要想得到正確數據,就可以通過:
           String str =  request.getParameter(“xxx”);
           str =  new  String (str.getBytes(“ISO8859-1”,”contentType指定的編碼”);
這樣先將數據還原,然后再用發送時的字符集來進行解碼,這樣就可將數據還原了.

(責任編輯:admin)