999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

Tom cat環境下JSP中文亂碼問題的解決

2011-08-15 00:53:01
湖南第一師范學院學報 2011年4期
關鍵詞:方法

彭 立

(湖南第一師范學院信息科學與工程系,湖南 長沙 410205)

Tom cat環境下JSP中文亂碼問題的解決

彭 立

(湖南第一師范學院信息科學與工程系,湖南 長沙 410205)

Web服務器Tom cat的中文亂碼問題給軟件開發人員帶來了很大的困惑。為解決這一問題,可通過分析各種編碼方式之間的相互轉換,發現中文亂碼問題的根源,并對各種出錯情況進行分析,找出解決問題的辦法。

Tomcat;JSP;中文亂碼;編碼;轉換

一、引言

Tomcat作為SUN公司官方推薦的JSP和Servlet容器,因其開源、免費、跨平臺、配置簡單等特點,得到了廣大軟件開發人員的喜愛。然而,在中文操作系統上用Tomcat作為Web服務器來開發網站時,會出現中文亂碼問題,從而給軟件開發人員帶來了很大的困惑。有人對這些問題進行過分析,但提出的解決辦法并不全面也不完全正確。Tomcat環境下的中文亂碼問題涉及范圍很廣,本文旨在解決其中的一類問題:JSP中文亂碼問題。現將Tomcat環境下常見的JSP中文亂碼問題列舉如下:

問題一:JSP(以下都將JSP文件簡稱為JSP)本身包含的中文內容在IE(以下都將IE瀏覽器簡稱為IE)中顯示為亂碼。

問題二:表單通過POST方式提交給JSP的中文信息在IE中顯示為亂碼。

問題三:表單通過GET方式提交給JSP的中文信息在IE中顯示為亂碼。

為了解決Tomcat環境下JSP中文亂碼問題,有必要先了解該環境下使用的編碼方式。

二、Tom cat的編碼方式

解決其他系統軟件的中文亂碼問題所獲得的經驗告訴我們,中文亂碼問題往往跟字符的編碼方式有關。編碼方式是指字符在計算機內的表現形式,也就是機內碼。在Tomcat環境下使用的編碼方式(即字符集)主要有四種:UNICODE、UFT-8、GB2312-80/GBK和ISO-8859-1。

(一)UN ICODE

UNICODE是Java內部采用的編碼方式,也就是說,當Java程序運行時,數據都會轉換為UNICODE編碼保存在內存中。UNICODE是DBCS(雙字節字符集),它和任意國家/區域使用的本地字符集之間存在相互映射的關系,通過這樣一種映射關系,它和本地字符集可相互轉換。Java虛擬機通過操作系統的Codepage得知系統采用的字符集后,就可以使Java程序中的數據在UNICODE編碼和本地字符編碼之間相互轉換。

(二)UTF-8

UTF-8以8個二進制位為單元對UNICODE進行編碼,它是網絡數據傳輸以及Java類文件所采用的編碼方式。Tomcat環境下的JSP編譯成的Servlet類文件就是以UTF-8編碼方式保存的。UTF-8編碼的長度不一,通常西文字符為一個字節,而漢字需三個字節。

(三)GB2312-80/GBK

GB2312-80/GBK是漢字的國際碼。中文操作系統中漢字的編碼方式都為GB2312-80/GBK,而西文字符的編碼方式為ISO-8859-1。GB2312-80/GBK是DBCS,其中GB2312-80只能表示簡體字,它包含了大部分常用的一、二級漢字和9區的符號;GBK是GB2312-80 的擴展,既可表示簡體字也可表示繁體字,它包含了20902個漢字,其編碼范圍是0X8140~0XFEFE,剔除高字節為0X80的字位,其所有字符都可以一對一映射到UNICODE 2.0。

(四)ISO-8859-1

ISO-8859-1是SBCS(單字節字符集),屬于西歐字符集,它是Tomcat默認的編碼方式。如無特殊說明,在編譯JSP時,Tomcat會把JSP的編碼方式默認看成ISO-8859-1;接收表單輸入數據時,Tomcat會將數據的編碼方式默認看成ISO-8859-1;輸出數據到IE時,Tomcat會默認將數據從UNICODE編碼轉換為ISO-8859-1編碼。

三、編碼方式的轉換

在Java程序運行時,數據以UNICODE編碼的形式保存在內存中,Tomcat根據需要,可將其轉換為UFT-8編碼、GB2312-80編碼或ISO-8859-1編碼,也可轉換回來。Tomcat環境下的JSP從編譯到輸出,中間要經過多次編碼轉換;JSP接收表單數據后輸出到IE,期間也涉及到多次編碼轉換。

(一)UN ICODE和UFT-8之間的轉換

UNICODE和UFT-8之間的轉換通常是網絡傳輸和保存文件的需要。因為UNICODE和UFT-8是一一對應的,這兩者之間的轉換通常不會造成中文亂碼問題。

(二)UN ICODE和GB2312-80之間的轉換

GB2312-80中所有的字符編碼都可轉換為對應的UNICODE編碼,例如,漢字“你”的GB2312-80編碼為0XC4E3,對應的UNICODE編碼為U4F60。但是,一個不在GB2312-80中的字符編碼被當作GB2312-80轉換為UNICODE時,會被轉換為一個特殊編碼UFFFD。反過來,并不是所有的UNICODE編碼都能轉換為GB2312-80編碼,只有漢字字符的UNICODE編碼才能被轉換為對應的GB2312-80編碼,例如,漢字“好”的 UNICODE編碼為U597D,對應的GB2312-80編碼為0XBAC3。不能映射到GB2312-80的UNICODE編碼轉換為GB2312-80編碼時,結果為0X3F,顯示出來是“?”。又如,U00D6轉換為GB2312-80編碼為0X3F。UNICODE編碼U00A0~U00FF之間有20個編碼在轉換為GB2312-80編碼后,顯示出來都是亂碼字符。再如,U00EC轉換為GB2312-80編碼為0XA8AC,顯示出來為亂碼字符“ì”。

(三)UN ICODE和ISO-8859-1之間的轉換

ISO-8859-1中所有的字符編碼都可轉換為對應的UNICODE編碼,轉換方法為:在ISO-8859-1編碼的前面加上0X00。例如字符“A”的ISO-8859-1編碼為0X41,對應的UNICODE編碼為0X0041。一個不在ISO-8859-1中的字符編碼被轉換為UNICODE編碼時,系統并不效驗被轉換的是否為ISO-8859-1編碼,而是直接按轉換方法在編碼的前面加上0X00。反過來,并不是所有的UNICODE編碼都能轉換為ISO-8859-1編碼。如果UNICODE中某個字符編碼能被轉換為ISO-8859-1編碼,那么它的高字節必為0X00,去掉高字節0X00,保留低字節,便形成了對應的ISO-8859-1編碼,例如,字符“B”的UNICODE編碼為 U0042,對應的ISO-8859-1編碼為0X42。不能映射到ISO-8859-1的UNICODE編碼被轉換為ISO-8859-1編碼時,結果為0X3F,顯示出來是“?”,又如漢字“好”的UNICODE編碼為U597D,轉換為ISO-8859-1編碼為0X3F[1]。

四、Tom cat中文亂碼問題的原因

在Tomcat環境下,字符通常要經過“編碼方式A→UNICODE→編碼方式B”這樣一個過程,才能最終輸出。

現以漢字“的”為例,看看在GB2312-80→UNICODE→ISO-8859-1和 ISO-8859-1→UNICODE→GB2312-80這兩種情況下分別會出現什么問題。“的”字的GB2312-80編碼為0XB5C4。在第一種情況下,“的”字的編碼方式被看作是GB2312-80,轉換成的UNICODE編碼為U7684,再由UNICODE編碼轉換成ISO-8859-1編碼后,結果是0X3F,顯示出來是一個“?”號。在第二種情況下,“的”字的編碼方式被看作ISO-8859-1,轉換成的UNICODE編碼為U00B5U00C4,再由UNICODE編碼轉化為GB2312-80編碼后,結果是0XA6CC0X3F,顯示出來是“μ?”這樣兩個亂碼字符。

可以看出以上兩種情況都會造成中文亂碼問題,錯誤的編碼轉換過程是Tomcat中文亂碼問題的根源。

五、JSP中文亂碼問題的分析和解決

(一)問題一的分析和解決

Tomcat環境下的JSP被IE訪問時要經過“編譯成Servlet→載入運行→輸出到IE”這樣三個階段。現分析一下在每個階段中編碼方式是如何轉換的。

1.編譯成Servlet

當JSP被IE訪問時,Tomcat會采取以下方式來判斷JSP采用了哪種編碼方式:首先,它會檢查JSP中是否有 <%@page pageEncoding=”xx”%> 這行語句(只有JSP2.0才支持這種的語句),如果有,它會把JSP的編碼方式看成是xx;否則,它會檢查JSP 中 是 否 有 <%@page contentType=”text/html;charset=yy”%>這行語句,如果有,它會把JSP的編碼方式看成是yy;如果兩者都無,它會把JSP的編碼方式默認看成ISO-8859-1。確定了JSP的編碼方式后(盡管不一定與實際相符),Tomcat會將JSP從該編碼方式轉換為UNICODE編碼[2],并將UNICODE編碼的JSP編譯為Servlet類文件,然后將Servlet類文件從UNICODE編碼轉換為UFT-8編碼,并保存在磁盤上。

2.載入運行

JSP編譯成的Servlet類文件被載入內存運行時,Tomcat會將Servlet類文件由UFT-8編碼轉換回UNICODE編碼。因為UFT-8編碼和UNICODE編碼是一一對應的,UFT-8和UNICODE間的相互轉換不會導致亂碼問題。

3.輸出到IE

Servlet將信息輸出到IE之前,Tomcat會檢查其對應的 JSP中是否有 <%@page contentType=”text/html;charset=xx”%>這行語句。如果有,Tomcat會將輸出信息由UNICODE編碼轉換為xx編碼,然后輸出到IE,IE的編碼方式也會自動被設置為xx;如果JSP中沒有以上語句,但有<%@page pageEncoding=”yy”%> 這行語句,Tomcat會將輸出信息由UNICODE編碼轉換為yy編碼,然后輸出到IE,IE的編碼方式也會自動被設置為yy;如果JSP中以上兩種語句都沒有,Tomcat會將輸出信息由UNICODE編碼默認轉換為ISO-8859-1編碼,然后輸出到IE,IE的編碼方式會被自動設置為ISO-8859-1。

通過以上分析可以看出,Tomcat環境下的JSP被IE訪問時要經過“編碼方式A→UNICODE→編碼方式B”這樣一個過程,這一過程中的錯誤編碼轉換會導致問題一的出現。問題一通常由以下兩種情況造成:

情況一:JSP中沒有包含語句 <%@page pageEncoding=”xx”%> 和 <%@page contentType=”text/html;charset=yy”%>。假設JSP中有一漢字“的”(以下都以“的”字為例),現分析為什么“的”字在IE中顯示時會變成亂碼。在中文操作系統中,JSP以GB2312-80編碼保存,因此,JSP文件中“的”字的編碼為0XB5C4。因為JSP中沒有以上兩種語句,在對JSP進行編譯時,Tomcat會把JSP的編碼方式默認當作ISO-8859-1,從而將0XB5C4轉換為UNICODE編碼U00B5U00C4。Servlet輸出信息到IE時,因JSP源文件中沒有以上兩種語句,Tomcat會將UNICODE編碼U00B5U00C4轉換為ISO-8859-1編碼0XB5C4,然后輸出到IE。因為IE的編碼方式會被自動設置為ISO-8859-1,它將編碼0XB5C4顯示為亂碼“μ?”。

情況二:JSP中同時包含有語句 <%@page pageEncoding=”xx”% > 和 <%@page contentType=”text/htm l;charset=yy”%>,但xx和yy之中只有一個為GB2312-80,另一個為ISO-8859-1。如果xx為GB2312-80,yy 為 ISO-8859-1,“的”字在輸出時,它的編碼會經歷0XB5C4→U7684→0X3F這樣一個轉換過程,最終在IE中顯示為一個“?”號。如果xx 為 ISO-8859-1,yy 為 GB2312-80,“的”字在輸出時,它的編碼會經歷0X B5C4→U00b5U00c4→0XA6CC0X3F這樣一個轉換過程,最終在IE中顯示為“μ?”這樣兩個亂碼字符。

解決問題一的方法很簡單,只要在JSP中包含語 句 <%@page pageEncoding=”GB2312-80”%> 或<%@page contentType=”text/htm l;charset=GB2312-80”%>即可,這樣就可以保證JSP中的中文內容在編譯時由GB2312-80編碼轉換為UNICODE編碼,在輸出時由UNICODE編碼轉換回GB2312-80編碼。如果要在JSP中同時使用這兩種語句,要確保兩種語句中的編碼方式都為GB2312-80。

(二)問題二、問題三的分析和解決

除了被IE直接訪問,JSP還可以被表單調用,從而實現表單輸入信息由JSP接收后再輸出到IE顯示。表單調用JSP時,實質上是調用其編譯而成的Servlet。表單輸入信息由IE傳給Tomcat,再由Tomcat傳給運行中的Servlet,最后由Servlet輸出到IE進行顯示。之前已對Servlet輸出信息到IE時出現的編碼轉換進行過分析,這里不再贅述,接下來只對表單輸入信息經Tomcat傳遞給Servlet時出現的編碼轉換進行分析。表單調用JSP時,通常采取兩種方式:POST方式和GET方式。

1.POST方式

在POST方式下,表單輸入數據放在IE請求消息的實體部分傳給Tomcat。Servlet中的Request對象通過getParameter方法向Tomcat請求表單輸入數據時,Tomcat會檢查Request對象的編碼方式屬性。如果在Request對象調用getParameter方法之前,其編碼方式屬性已通過request.setCharacterEncoding(“xx”)語句被設置成xx,Tomcat會把輸入數據的編碼方式看成是xx。如果Servlet中沒有這行語句,Tomcat會將輸入數據的編碼方式默認看成是ISO-8859-1。確定了表單輸入數據的編碼方式后(盡管不一定與實際相符),Tomcat會將輸入數據從該編碼方式轉換為UNICODE編碼,然后傳遞給Servlet[3]。

可以發現在POST方式下,表單輸入數據通過JSP輸出到IE時,同樣要經歷“編碼方式A→UNICODE→編碼方式B”這樣一個過程,這一過程中的錯誤編碼轉換會導致問題二的出現。問題二通常由以下兩種情況造成(假定在這兩種情況中,表單所在的HTML頁面的編碼方式都為GB2312-80,那么表單中的漢字信息在傳給Tomcat時,編碼方式都為GB2312-80):

情況一:JSP中既沒有語句<%@page pageEncoding=”xx”%> 和 <%@page contentType=”textml;charset=yy”%>,也沒有語句request.setCharacterEncoding(“zz”)。因為JSP中沒有語句request.setCharacterEncoding(“zz”),Tomcat會將表單輸入數據的編碼方式看成是ISO-8859-1,并轉換成UNICODE編碼,因此“的”字的編碼會從0XB5C4轉換為U00B5U00C4。Servlet輸出信息到IE時,因為JSP中沒有語句 <%@page pageEncoding=”xx”%> 和<%@page contentType=”textml;charset=yy”%>,Tomcat會將編碼U00B5U00C4轉換為ISO-8859-1編碼0XB5C4,并輸出到IE。因為IE的編碼方式會被自動設置為ISO-8859-1,編碼0XB5C4顯示為亂碼“μ?”。

情況二:JSP中包含有語句<%@page pageEncoding=”GB2312-80”%> 或 <%@page contentType=”textml;charset=GB2312-80”%>,但沒有語句request.setCharacterEncoding(“zz”)。情況二和情況一的不同之處在于:情況二的JSP中包含了語句<%@page pageEncoding=”GB2312-80”%> 或 <%@page content-Type=”textml;charset=GB2312-80”%>,因此”的“字被Servlet輸出到IE時,它的編碼會從U00B5U00B4轉換為GB2312-80編碼0XA6CC0X3F,輸出到IE顯示為“μ?”這樣兩個亂碼字符。

解決問題二有兩種方法。

方法一:確保JSP中包含有語句<%@page pageEncoding=”GB2312-80”%> 或 <%@page content-Type=”textm l;charset=GB2312-80”%>,此外,在 Request對象調用getParameter方法之前加上語句request.setCharacterEncoding(“GB2312-80”)。這種方法可確保表單中輸入的中文信息通過JSP輸出到IE時會經過GB2312-80→UNICODE→GB2312-80這樣一個正確的編碼轉換過程。

方法二:確保JSP中包含有語句<%@page pageEncoding=”GB2312-80”%> 和 <%@page content-Type=”textml;charset=GB2312-80”%>,此外,將 Request對象調用getParameter方法的語句改為String Output=new(request.getParameter(“Input”).getBytes(“ISO8859_1”)),然后輸出字符串Output即可。現說明一下這種方法為什么可行。在request.getParameter(“Input”)執行之前,并沒有設置Request對象的編碼方式,因此表單中漢字的編碼方式被當成是ISO-8859-1,然后轉換成UNICODE傳給Servlet,因而,“的”字的編碼從0XB5C4轉換為U00B5U00C4。調用了getBytes(“ISO8859_1”)方法后,“的”字的編碼又變回了0XB5C4,相當于又變成了GB2312-80編碼。通過new方法生成字符串 Output時,該GB2312-80編碼會轉換成對應的UNICODE編碼。在字符串Output被輸出時,字符串的內容從UNICODE編碼轉換成GB2312-80編碼輸出。通過以上分析發現,該方法可確保表單中輸入的中文信息通過JSP輸出時會經過ISO-8859-1→UNICODE→ISO-8859-1(GB2312-80)→UNICODE→GB2312-80這樣一個正確的編碼轉換過程。

2.GET方式

在GET方式下,表單輸入數據放在IE請求消息的請求行之中傳給Tomcat。通過查看Tomcat的源代碼可以發現,Tomcat對GET方式下表單輸入數據的處理采用了和POST方式不同的方法。當Request對象通過getParameter方法向Tomcat請求表單輸入數據時,Tomcat不會檢查Request對象的編碼方式屬性,而是檢查配置文件server.xml中port值為 8080的 connector元素的 URIEncoding屬性,并將表單輸入數據的編碼方式看成URIEncoding屬性所設置的編碼方式。如果server.xml中port值為8080的connector元素沒有對URIEncoding屬性進行設置,Tomcat會將輸入數據的編碼方式默認當作ISO-8859-1[4]。

知道了Tomcat在GET方式下對表單輸入數據所采用的處理方法,不難為問題三找到解決辦法,主要有兩種:

方法一:確保JSP中包含有語句<%@page pageEncoding=”GB2312-80”%> 或 <%@page content-Type=”textml;charset=GB2312-80”%>,此外,將配置文件server.xml中port值為8080的connector元素的URIEncoding屬性設置為GB2312-80。這種方法可確保表單中輸入的中文信息通過JSP輸出到IE時會經過GB2312-80→UNICODE→GB2312-80這樣一個正確的編碼轉換過程。

方法二:確保JSP中包含有語句<%@page pageEncoding=”GB2312-80”%> 和 <%@page content-Type=”textml;charset=GB2312-80”%>,此外,將 JSP中Request對象調用getParameter方法的語句改為String Output=new(request.getParameter(“Input”).get-Bytes(“ISO8859_1”)),然后輸出字符串Output即可。此方法可行的原因和問題二的方法二相同,此處不再累述。這種方法可確保表單中輸入的中文信息通過 JSP輸出到 IE時會經過 ISO-8859-1→UNICODE→ISO-8859-1(GB2312-80)→UNICODE→GB2312-80這樣一個正確的編碼轉換過程。

六、結語

Tomcat環境下JSP中文亂碼問題的根源是錯誤的編碼轉換過程,對各種出錯情況進行分析后,不難找出這些問題的解決辦法。以上分析對解決Tomcat環境下其他類型的中文亂碼問題也具有指導作用。文中的測試都是在Tomcat5.0.28下進行的,所有的解決方法都在該版本下驗證通過。

[1]JrneforsO.AshortoverviewofISO/IEC10646andUni code[DB/OL].http://www.nada.kth.se/i18n/ucs/unicodeiso10646-oview.htm l

[2]LindenbergN.DevelopingMultilingualWebApplications UsingJavaServerPagesTechnology[DB/OL].http://java.sun.com/developer/technicalArticles/Intl/MultilingualJSP/index.htm l

[3]孫衛琴,李洪成.Tomcat與JavaWeb開發技術詳解[M].北京:電子工業出版社,2004.

[4]Apache Software Foundation.ApacheTomcatConfiguration ReferenceTheHTTPConnector[DB/OL].http://tom cat.apache.org/tomcat-5.5-doc/config/http.htm l

The Solution to Chinese Lousy Code Problemsof JSPon Tom cat

PENG Li

(Departmentof Information Science and Engineering,Hunan FirstNormalUniversity,Changsha,Hunan 410205)

Chinese lousy code problems on Web server Tomcat have been puzzling software developers.To solve thisproblem,one should analyze the conversion between every encoding and find the reason that Chinese lousy code problemsare caused by false encoding-conversion processes.Then a solution to the problem may be found after a furtheranalysisofeach w rong case.

Tomcat;JSP;Chinese lousy code;encoding;conversion

TP311.1

A

1674-831X(2011)04-0128-05

2011-01-09

湖南第一師范學院院級課題(XYS10N09)

彭立(1974—),男,湖南汨羅人,湖南第一師范學院信息科學與工程系講師。

[責任編輯:胡 偉]

猜你喜歡
方法
中醫特有的急救方法
中老年保健(2021年9期)2021-08-24 03:52:04
高中數學教學改革的方法
河北畫報(2021年2期)2021-05-25 02:07:46
化學反應多變幻 “虛擬”方法幫大忙
變快的方法
兒童繪本(2020年5期)2020-04-07 17:46:30
學習方法
用對方法才能瘦
Coco薇(2016年2期)2016-03-22 02:42:52
最有效的簡單方法
山東青年(2016年1期)2016-02-28 14:25:23
四大方法 教你不再“坐以待病”!
Coco薇(2015年1期)2015-08-13 02:47:34
賺錢方法
捕魚
主站蜘蛛池模板: 久久国产精品电影| 亚洲av成人无码网站在线观看| 特级毛片免费视频| 99热这里只有精品5| 久久黄色一级视频| 亚洲国内精品自在自线官| 日韩一级二级三级| 免费在线a视频| 久久精品丝袜高跟鞋| 亚洲欧美日本国产综合在线| 在线精品亚洲国产| 久久伊人操| 久久青草热| 99热国产这里只有精品无卡顿"| 久久成人18免费| 全部免费毛片免费播放| 国产91视频观看| 亚洲Va中文字幕久久一区| 国产一在线观看| 久久99国产精品成人欧美| 91精品国产综合久久不国产大片| 国模极品一区二区三区| 亚洲无线国产观看| 国产精品永久不卡免费视频| 免费AV在线播放观看18禁强制| 国产主播在线一区| 亚洲人成人无码www| 美女被操91视频| 国产精品香蕉在线观看不卡| 久久香蕉国产线看精品| 国产成人一区在线播放| 一本大道无码高清| 她的性爱视频| 亚洲中文精品人人永久免费| 国产精品999在线| 欧美不卡在线视频| 免费在线国产一区二区三区精品| 亚洲综合二区| 国产免费一级精品视频| 欧美亚洲国产精品久久蜜芽| 最新日本中文字幕| 日韩小视频网站hq| 欧美人与性动交a欧美精品| 亚洲欧洲综合| 毛片在线播放a| 久久99国产综合精品女同| 亚洲天堂日韩av电影| 国产欧美日韩另类| 亚洲第七页| 在线观看精品自拍视频| 亚洲 日韩 激情 无码 中出| 无码精油按摩潮喷在线播放| 一本大道无码日韩精品影视| 精品一区二区三区无码视频无码| 日韩欧美国产综合| 欧美亚洲欧美| 无码在线激情片| 91人妻日韩人妻无码专区精品| 亚洲人成网站在线观看播放不卡| 99热线精品大全在线观看| 亚洲国产成人久久77| 久久一日本道色综合久久| 国产一级在线播放| 日韩精品免费一线在线观看 | 午夜在线不卡| 天天色综网| 亚洲成人一区二区三区| 日本www在线视频| 在线播放国产99re| 在线国产三级| 国产成人调教在线视频| 免费A级毛片无码免费视频| 潮喷在线无码白浆| 夜夜操狠狠操| 欧美国产综合色视频| 激情国产精品一区| 91无码人妻精品一区二区蜜桃 | 欧美在线一级片| 2022国产91精品久久久久久| 9啪在线视频| 999国产精品| 成人毛片免费在线观看|