====================http://www.glgg.net/[email protected]================ 開發java應用出現亂碼是很常見的,畢竟現在unicode的使用還不是很廣泛,在使用gb2312(包含了gbk簡體,big5繁體)的系統中要正確實現 中文的display和數據庫的存儲是最基本的要求。 ========================http://www.glgg.net/blog======================================= 1,首先developer要明確自己為什么會遇到亂碼,遇到什么樣的亂碼(無意義的符號還是一串問號或者其它什么東西)。新手遇到一堆很亂的字符時通常不知所措,最直接的反映就是打開google搜索”java中文”(這個字符串在搜索引擎上的查詢頻率非常高), 然后一個一個的去看別人的解決方法。這樣做沒有錯,但是很難達到目的,原因下面會提到??傊霈F亂碼的原因是非常多的,解決的方法也完全不一樣,要解決
====================http://[email protected]================
開發java應用出現亂碼是很常見的,畢竟現在unicode的使用還不是很廣泛,在使用gb2312(包含了gbk簡體,big5繁體)的系統中要正確實現
中文的display和數據庫的存儲是最基本的要求。
========================http://www.babatu.com=======================================
1,首先developer要明確自己為什么會遇到亂碼,遇到什么樣的亂碼(無意義的符號還是一串問號或者其它什么東西)。
新手遇到一堆很亂的字符時通常不知所措,最直接的反映就是打開google搜索”java中文”(這個字符串在搜索引擎上的查詢頻率非常高),
然后一個一個的去看別人的解決方法。這樣做沒有錯,但是很難達到目的,原因下面會提到。
總之,出現亂碼的原因是非常多的,解決的方法也完全不一樣,要解決問題必須先分析自己的”上下文環境”。
========================http://www.babatu.com=====================================
2,具體說來,需要哪些信息才能確定項目中的亂碼的根源。
a,開發者所用的操作系統
b,j2ee容器的名稱,版本
c,數據庫的名稱,版本(精確版本)以及jdbc驅動的版本
d,出現亂碼的source code(比如是system out 出來的,還是jsp頁面中的,如果是jsp中的,那么頭部聲明的情況也很重要)
=========================http://www.glgg.net/blog========================================
3,如何初步分析亂碼出現的原因。
有了上述的信息,基本上就可以發帖求助了,相信放到javaworld等論壇上,很快就會有高手給你提出有效的解決方案的。
當然不能總靠發帖求助,也要試試自行解決問題。如何下手呢?
a,分析一下你的”亂碼”到底是什么編碼。這個其實不難,比如
system.out.println(teststring);
這一段出現了亂碼,那么不妨用窮舉法猜測一下它的實際編碼格式。
system.out.println(new string(teststring.getbytes(”iso-8859-1″),”gb2312″));
system.out.println(new string(teststring.getbytes(”utf8″),”gb2312″));
system.out.println(new string(teststring.getbytes(”gb2312″),”gb2312″));
system.out.println(new string(teststring.getbytes(”gbk”),”gb2312″));
system.out.println(new string(teststring.getbytes(”big5″),”gb2312″));
等等,上述代碼的意思是用制定的編碼格式去讀取teststring這個”亂碼”,并轉換成gb2312(此處僅以中文為例)
然后你看哪一個轉換出來的結果是ok的,那就。。。
b,如果用上面的步驟能得到正確的中文,說明你的數據肯定是在的,只不過是界面中沒有正確顯示而已。那么第二步就該糾正你的view部分了
,通常需要檢查的是jsp中是否選擇了正確的頁面編碼。
在此要聲明被很多人誤解的一點,那就是<%@ page contenttype=”text/html; charset=gb2312″ %>指令和<meta http-equiv=content-type
content=”text/html; charset=gb2312″>兩者的不同。通常網上的很多文章在提到中文問題時都是說數據庫中選擇unicode或者gb2312存儲,同
時在jsp中用page指令聲明編碼就可以解決。但是我覺得這種說法很不負責任,害的我費了n多時間為本來并不存在的亂碼而郁悶。實際上page
的作用是在jsp被編譯成為html的過程中提供編碼方式讓java來”讀取”表達式當中的string(有點類似于上面的第三個語句的作用),而meta
的作用是眾所周知的為ie瀏覽器提供編碼選擇,是用來”顯示”最后的數據的。但是沒有看到有人提醒這一點,我一直把page當成meta在用,
導致本來是iso-8859的數據,被page指令讀成gb2312,于是亂碼,所以又加了編碼轉化的函數把所有的string數據都從iso8859轉到gb2312(為
什么這么轉,當時也沒考慮這么多,因為這么做可以正常顯示了,所以就這么改了,呵呵當時實在沒有時間慢慢排查問題了)。
===========================http://www.glgg.net/blog==========================================
4,數據庫選擇什么樣的編碼比較好。
目前流行的db主要有sql server,mysql,oracle,db2等,其中mysql作為免費db中的老大,性能和功能是得到公認的,安裝配置比較方便,相
應的driver也比較完善,性價比是絕對的ok。所以就以mysql為例。
我個人建議采用mysql的默認編碼來存儲,也就是iso-8859-1(在mysql的選項中對應于latin-1)。理由主要有這么幾個,一是iso-8859-1對中
文的支持不錯;二是跟java中的默認編碼一致,至少在很多地方免除了轉換編碼的麻煩;三是默認的比較穩定,兼容性也更好,因為多編碼的
支持是由具體的db產品提供的,別說跟其它的db會不兼容,即使自身的不同版本也可能出現兼容性的問題。
例如mysql 4.0以前的產品中,很多中文的解決方案是利用connection中的characterencoding字段來制定編碼,比如gb2312什么的,這樣是ok
的,因為原數據都是iso8859_1編碼,jdbc驅動會采用url里面指定的character set來進行編碼,resultset.getstring(*)取出的就是編碼后的
字符串。這樣就直接拿到gb2312的數據了。
但是mysql 4.1的推出給很多dbadmin帶來了不小的麻煩,因為mysql4.1支持column level的character set,每個table,column都可以指定編碼
,不指定就是iso8895_1,因此jdbc取出數據后會根據column的character set來進行編碼,而不再是用一個全局的參數來取所有的數據了。
這從另一個方面也說明了亂碼問題的產生實在是很復雜的事情,原因太多了。我也只是針對自己遇到的實際情況提供一些解決思路,有什么錯
誤的地方請email至[email protected]希望能更多的看到達人自己的文章,而不是一堆以訛傳訛的拷貝。
internel use only.
any question,please reffer to [email protected]
================================http://www.glgg.net/blog======================================
終于找到最完美的解決中文問題的方案了。。。謝謝網上的這個文章的作者。。。
我的原文是根據自己的經驗總結出來的。雖然沒什么錯誤,但是始終沒有找到最終的病根??戳诉@個文章之后,開始恍然大悟,哈哈,
———————————————————————————————————————————————————————————-
由于java編程中的中文問題是一個老生常談的問題,在閱讀了許多關于java中文問題解決方法之后,結合作者的編程實踐,我發現過去談的許多方法都不能清晰地說明問題及解決問題,尤其是跨平臺時的中文問題。
于是我給出此篇文章,內容包括對控制臺運行的class、servelets、jsp及ejb類中的中文問題我剖析和建議解決辦法。希望大家指教。
abstract:本文深入分析了java程序設計中java編譯器對java源文件和jvm對class類文件的編碼/解碼過程,通過此過程的解析透視出了java編程中中文問題產生的根本原因,最后給出了建議的最優化的解決java中文問題的方法。
1、中文問題的來源
計算機最初的操作系統支持的編碼是單字節的字符編碼,于是,在計算機中一切處理程序最初都是以單字節編碼的英文為準進行處理。
隨著計算機的發展,為了適應世界其它民族的語言(當然包括我們的漢字),人們提出了unicode編碼,它采用雙字節編碼,兼容英文字符和其它民族的雙字節字符編碼,所以,目前,大多數國際性的軟件內部均采用unicode編碼,在軟件運行時,它獲得本地支持系統(多數時間是操作系統)默認支持的編碼格式,然后再將軟件內部的unicode轉化為本地系統默認支持的格式顯示出來。
java的jdk和jvm即是如此,我這里說的jdk是指國際版的jdk,我們大多數程序員使用的是國際化的jdk版本,以下所有的jdk均指國際化的jdk版本。我們的漢字是雙字節編碼語言,為了能讓計算機處理中文,我們自己制定的gb2312、gbk、gbk2k等標準以適應計算機處理的需求。
所以,大部分的操作系統為了適應我們處理中文的需求,均定制有中文操作系統,它們采用的是gbk,gb2312編碼格式以正確顯示我們的漢字。如:中文windows默認采用的是gbk編碼顯示,在中文windows2000中保存文件時默認采用的保存文件的編碼格式也是gbk的,即所有在中文windows2000中保存的文件它的內部編碼默認均采用gbk編碼,注意:gbk是在gb2312基礎上擴充來的。
由于java語言內部采用unicode編碼,所以在java程序運行時,就存在著一個從unicode編碼和對應的操作系統及瀏覽器支持的編碼格式轉換輸入、輸出的問題,這個轉換過程有著一系列的步驟,如果其中任何一步出錯,則顯示出來的漢字就會出是亂碼,這就是我們常見的java中文問題。
同時,java是一個跨平臺的編程語言,也即我們編寫的程序不僅能在中文windows上運行,也能在中文linux等系統上運行,同時也要求能在英文等系統上運行(我們經??吹接腥税言谥形膚indows2000上編寫的java程序,移植到英文linux上運行)。這種移植操作也會帶來中文問題。
還有,有人使用英文的操作系統和英文的ie等瀏覽器,來運行帶中文字符的程序和瀏覽中文網頁,它們本身就不支持中文,也會帶來中文問題。
幾乎所有的瀏覽器默認在傳遞參數時都是以utf-8編碼格式來傳遞,而不是按中文編碼傳遞,所以,傳遞中文參數時也會有問題,從而帶來亂碼現象。
總之,以上幾個方面是java中的中文問題的主要來源,我們把以上原因造成的程序不能正確運行而產生的問題稱作:java中文問題。
2、java編碼轉換的詳細過程
我們常見的java程序包括以下類別:
*直接在console上運行的類(包括可視化界面的類)
*jsp代碼類(注:jsp是servlets類的變型)
*servelets類
*ejb類
*其它不可以直接運行的支持類
這些類文件中,都有可能含有中文字符串,并且我們常用前三類java程序和用戶直接交互,用于輸出和輸入字符,如:我們在jsp和servlet中得到客戶端送來的字符,這些字符也包括中文字符。無論這些java類的作用如何,這些java程序的生命周期都是這樣的:
*編程人員在一定的操作系統上選擇一個合適的編輯軟件來實現源程序代碼并以.java擴展名保存在操作系統中,例如我們在中文windows2000中用記事本編輯一個java源程序。
*編程人員用jdk中的javac.exe來編譯這些源代碼,形成.class類(jsp文件是由容器調用jdk來編譯的)。
*直接運行這些類或將這些類布署到web容器中去運行,并輸出結果。
那么,在這些過程中,jdk和jvm是如何將這些文件如何編碼和解碼并運行的呢?
這里,我們以中文windows2000操作系統為例說明java類是如何來編碼和被解碼的。
第一步,我們在中文windows2000中用編輯軟件如記事本編寫一個java源程序文件(包括以上五類java程序),程序文件在保存時默認采用了操作系統默認支持gbk編碼格式(操作系統默認支持的格式為file.encoding格式)形成了一個.java文件,也即,java程序在被編譯前,我們的java源程序文件是采用操作系統默認支持的file.encoding編碼格式保存的,java源程序中含有中文信息字符和英文程序代碼;要查看系統的file.encoding參數,可以用以下代碼:
public class showsystemdefaultencoding
{
public static void main(string[] args)
{
string encoding =
system.getproperty(”file.encoding”);
system.out.println(encoding);
}
}
第二步,我們用jdk的javac.exe文件編譯我們的java源程序,由于jdk是國際版的,在編譯的時候,如果我們沒有用-encoding參數指定我們的java源程序的編碼格式,則javac.exe首先獲得我們操作系統默認采用的編碼格式,也即在編譯java程序時,若我們不指定源程序文件的編碼格式,jdk首先獲得操作系統的file.encoding參數(它保存的就是操作系統默認的編碼格式,如windows2000,它的值為gbk),然后jdk就把我們的java源程序從file.encoding編碼格式轉化為java內部默認的unicode格式放入內存中。
然后,javac把轉換后的unicode格式的文件進行編譯成.class類文件,此時.class文件是unicode編碼的,它暫放在內存中,緊接著,jdk將此以unicode編碼的編譯后的class文件保存到我們的操作系統中形成我們見到的.class文件。
對我們來說,我們最終獲得的.class文件是內容以unicode編碼格式保存的類文件,它內部包含我們源程序中的中文字符串,只不過此時它己經由file.encoding格式轉化為unicode格式了。
這一步中,對于jsp源程序文件是不同的,對于jsp,這個過程是這樣的:即web容器調用jsp編譯器,jsp編譯器先查看jsp文件中是否設置有文件編碼格式,如果jsp文件中沒有設置jsp文件的編碼格式,則jsp編譯器調用jdk先把jsp文件用jvm默認的字符編碼格式(也即web容器所在的操作系統的默認的file.encoding)轉化為臨時的servlet類,然后再把它編譯成unicode格式的class類,并保存在臨時文件夾中。
如:在中文windows2000上,web容器就把jsp文件從gbk編碼格式轉化為unicode格式,然后編譯成臨時保存的servlet類,以響應用戶的請求。
第三步,運行第二步編譯出來的類,分為三種情況:
a、 直接在console上運行的類
b、 ejb類和不可以直接運行的支持類(如javabean類)
c、 jsp代碼和servlet類
d、 java程序和數據庫之間
下面我們分這四種情況來看。
a、直接在console上運行的類
這種情況,運行該類首先需要jvm支持,即操作系統中必須安裝有jre。運行過程是這樣的:首先java啟動jvm,此時jvm讀出操作系統中保存的class文件并把內容讀入內存中,此時內存中為unicode格式的class類,然后jvm運行它,如果此時此類需要接收用戶輸入,則類會默認用file.encoding編碼格式對用戶輸入的串進行編碼并轉化為unicode保存入內存(用戶可以設置輸入流的編碼格式)。
程序運行后,產生的字符串(unicode編碼的)再回交給jvm,最后jre把此字符串再轉化為file.encoding格式(用戶可以設置輸出流的編碼格式)傳遞給操作系統顯示接口并輸出到界面上。以上每一步的轉化都需要正確的編碼格式轉化,才能最終不出現亂碼現象。 b、ejb類和不可以直接運行的支持類(如javabean類)
由于ejb類和不可以直接運行的支持類,它們一般不與用戶直接交互輸入和輸出,它們常常與其它的類進行交互輸入和輸出,所以它們在第二步被編譯后,就形成了內容是unicode編碼的類保存在操作系統中了,以后只要它與其它的類之間的交互在參數傳遞過程中沒有丟失,則它就會正確的運行。
c、jsp代碼和servlet類
經過第二步后,jsp文件也被轉化為servlets類文件,只不過它不像標準的servlets一校存在于classes目錄中,它存在于web容器的臨時目錄中,故這一步中我們也把它做為servlets來看。
對于servlets,客戶端請求它時,web容器調用它的jvm來運行servlet,首先,jvm把servlet的class類從系統中讀出并裝入內存中,內存中是以unicode編碼的servlet類的代碼,然后jvm在內存中運行該servlet類,如果servlet在運行的過程中,需要接受從客戶端傳來的字符如:表單輸入的值和url中傳入的值,此時如果程序中沒有設定接受參數時采用的編碼格式,則web容器會默認采用iso-8859-1編碼格式來接受傳入的值并在jvm中轉化為unicode格式的保存在web容器的內存中。
servlet運行后生成輸出,輸出的字符串是unicode格式的,緊接著,容器將servlet運行產生的unicode格式的串(如html語法,用戶輸出的串等)直接發送到客戶端瀏覽器上并輸出給用戶,如果此時指定了發送時輸出的編碼格式,則按指定的編碼格式輸出到瀏覽器上,如果沒有指定,則默認按iso-8859-1編碼發送到客戶的瀏覽器上。
d、java程序和數據庫之間
對于幾乎所有數據庫的jdbc驅動程序,默認的在java程序和數據庫之間傳遞數據都是以iso-8859-1為默認編碼格式的,所以,我們的程序在向數據庫內存儲包含中文的數據時,jdbc首先是把程序內部的unicode編碼格式的數據轉化為iso-8859-1的格式,然后傳遞到數據庫中,在數據庫保存數據時,它默認即以iso-8859-1保存,所以,這是為什么我們常常在數據庫中讀出的中文數據是亂碼。
3、分析常見的java中文問題幾個必須清楚的原則
首先,經過上面的詳細分析,我們可以清晰地看到,任何java程序的生命期中,其編碼轉換的關鍵過程是在于:最初編譯成class文件的轉碼和最終向用戶輸出的轉碼過程。
其次,我們必須了解java在編譯時支持的、常用的編碼格式有以下幾種:
*iso-8859-1,8-bit, 同8859_1,iso-8859-1,iso_8859_1等編碼
*cp1252,美國英語編碼,同ansi標準編碼
*utf-8,同unicode編碼
*gb2312,同gb2312-80,gb2312-1980等編碼
*gbk,同ms936,它是gb2312的擴充及其它的編碼,如韓文、日文、繁體中文等。同時,我們要注意這些編碼間的兼容關體系如下:
unicode和utf-8編碼是一一對應的關系。gb2312可以認為是gbk的子集,即gbk編碼是在gb2312上擴展來的。同時,gbk編碼包含了20902個漢字,編碼范圍為:0×8140-0xfefe,所有的字符可以一一對應到unicode2.0中來。
再次,對于放在操作系統中的.java源程序文件,在編譯時,我們可以指定它內容的編碼格式,具體來說用-encoding來指定。注意:如果源程序中含有中文字符,而你用-encoding指定為其它的編碼字符,顯然是要出錯的。
用-encoding指定源文件的編碼方式為gbk或gb2312,無論我們在什么系統上編譯含有中文字符的java源程序都不會有問題,它都會正確地將中文轉化為unicode存儲在class文件中。
然后,我們必須清楚,幾乎所有的web容器在其內部默認的字符編碼格式都是以iso-8859-1為默認值的,同時,幾乎所有的瀏覽器在傳遞參數時都是默認以utf-8的方式來傳遞參數的。
所以,雖然我們的java源文件在出入口的地方指定了正確的編碼方式,但其在容器內部運行時還是以iso-8859-1來處理的。
4、中文問題的分類及其建議最優解決辦法
了解以上java處理文件的原理之后,我們就可以提出了一套建議最優的解決漢字問題的辦法。我們的目標是:我們在中文系統中編輯的含有中文字符串或進行中文處理的java源程序經編譯后可以移值到任何其它的操作系統中正確運行,或拿到其它操作系統中編譯后能正確運行,能正確地傳遞中文和英文參數,能正確地和數據庫交流中英文字符串。我們的具體思路是:在java程序轉碼的入口和出口及java程序同用戶有輸入輸出轉換的地方限制編碼方法使之正確即可。
具體解決辦法如下:
1、 針對直接在console上運行的類
對于這種情況,我們建議在程序編寫時,如果需要從用戶端接收用戶的可能含有中文的輸入或含有中文的輸出,程序中應該采用字符流來處理輸入和輸出,具體來說,應用以下面向字符型節點流類型:
對文件:filereader,filewrieter
其字節型節點流類型為:fileinputstream,fileoutputstream
對內存(數組):chararrayreader,chararraywriter
其字節型節點流類型為:bytearrayinputstream,bytearrayoutputstream
對內存(字符串):stringreader,stringwriter
對管道:pipedreader,pipedwriter
其字節型節點流類型為:pipedinputstream,pipedoutputstream
同時,應該用以下面向字符型處理流來處理輸入和輸出:
bufferedwriter,bufferedreader
其字節型的處理流為:bufferedinputestream,bufferedoutputstream
inputstreamreader,outputstreamwriter
其字節型的處理流為:datainputstream,dataoutputstream
其中inputstreamreader和inputstreamwriter用于將字節流按照指定的字符編碼集轉換到字符流,如:
inputstreamreader in = new inputstreamreader(system.in,”gb2312″); outputstreamwriter out = new outputstreamwriter (system.out,”gb2312″);例如:采用如下的示例java編碼就達到了要求:
//read.java
import java.io.*;
public class read
{
public static void main(string[] args)
throws ioexception
{
string str =
“/n中文測試,這是內部硬編碼的串
“+”/ntest english character”;
string strin= “”;
bufferedreader stdin =
new bufferedreader(new
inputstreamreader(system.in,”gb2312″));
//設置輸入接口按中文編碼
bufferedwriter stdout =
new bufferedwriter(new
outputstreamwriter(system.out,”gb2312″));
//設置輸出接口按中文編碼
stdout.write(”請輸入:”);
stdout.flush();
strin = stdin.readline();
stdout.write(”這是從用戶輸入的串:”+strin);
stdout.write(str);
stdout.flush();
}}
同時,在編譯程序時,我們用以下方式來進行:
javac -encoding gb2312 read.java
2、針對ejb類和不可以直接運行的支持類(如javabean類)
由于這種類它們本身被其它的類調用,不直接與用戶交互,故對這種類來說,我們的建議的處理方式是內部程序中應該采用字符流來處理程序內部的中文字符串(具體如上面一節中一樣),同時,在編譯類時用-encoding gb2312參數指示源文件是中文格式編碼的即可。
3、針對servlet類
針對servlet,我們建議用以下方法:
在編譯servlet類的源程序時,用-encoding指定編碼為gbk或gb2312,且在向用戶輸出時的編碼部分用response對象的setcontenttype(”text/html;charset=gbk”);或gb2312來設置輸出編碼格式,同樣在接收用戶輸入時,我們用request.setcharacterencoding(”gb2312″);這樣無論我們的servlet類移植到什么操作系統中,只有客戶端的瀏覽器支持中文顯示,就可以正確顯示。如下是一個正確的示例:
//helloworld.java
package hello;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class helloworld
extends httpservlet
{
public void init()
throws servletexception
{
}
public void doget
(httpservletrequest request,
httpservletresponse response)
throws ioexception, servletexception
{
request.setcharacterencoding(”gb2312″);
//設置輸入編碼格式
response.setcontenttype
(”text/html;charset=gb2312″);
//設置輸出編碼格式
printwriter out = response.getwriter();
//建議使用printwriter輸出
out.println(”<hr>”);
out.println(”hello world!
this is created by servlet!測試中文!”);
out.println(”<hr>”);
}
public void dopost(httpservletrequest request,
httpservletresponse response)
throws ioexception, servletexception
{
request.setcharacterencoding(”gb2312″);
//設置輸入編碼格式
response.setcontenttype
(”text/html;charset=gb2312″);
//設置輸出編碼格式
string name = request.getparameter(”name”);
string id = request.getparameter(”id”);
if(name==null) name=”";
if(id==null) id=”";
printwriter out = response.getwriter();
//建議使用printwriter輸出
out.println(”<hr>”);
out.println(”你傳入的中文字串是:” + name);
out.println(”<hr>你輸入的id是:” + id);
out.println(”<hr>”);
}
public void destroy()
{
}
}
請用javac -encoding gb2312 helloworld.java來編譯此程序。
測試此servlet的程序如下所示:
<%@page contenttype=”text/html;
charset=gb2312″%>
<%request.setcharacterencoding(”gb2312″);%>
<html><head><title></title>
<script language=”javascript”>
function submit()
{
//通過url傳遞中文字符串值給servlet
document.base.action =
“./helloworld?name=中文”;
document.base.method = “post”;
document.base.submit();
}
</script>
</head>
<body bgcolor=”#ffffff”
text=”#000000″ topmargin=”5″>
<form name=”base” method =
“post” target=”_self”>
<input name=”id” type=”text”
value=”" size=”30″>
<a href = “javascript:submit()”>
傳給servlet</a>
</form></body></html>
4、java程序和數據庫之間
為避免java程序和數據庫之間數據傳遞出現亂碼現象,我們建議采用以下最優方法來處理:
1、對于java程序的處理方法按我們指定的方法處理。
2、把數據庫默認支持的編碼格式改為gbk或gb2312的。
如:在mysql中,我們可以在配置文件my.ini中加入以下語句實現:
在[mysqld]區增加:
default-character-set=gbk
并增加:
[client]
default-character-set=gbk
在sql server2k中,我們可以將數據庫默認的語言設置為simplified chinese來達到目的。
5、針對jsp代碼
由于jsp是在運行時,由web容器進行動態編譯的,如果我們沒有指定jsp源文件的編碼格式,則jsp編譯器會獲得服務器操作系統的file.encoding值來對jsp文件編譯的,它在移植時最容易出問題,如在中文windows2000中可以很好運行的jsp文件拿到英文linux中就不行,盡管客戶端都是一樣的,那是因為容器在編譯jsp文件時獲取的操作系統的編碼不同造成的(在中文wink中的file.encoding和在英文linux中file.encoding是不同的,且英文linux的file.encoding對中文不支持,所以編譯出來的jsp類就會有問題)。
網絡上討論的大多數是此類問題,多是因為jsp文件移植平臺時不能正確顯示的問題,對于這類問題,我們了解了java中程序編碼轉換的原理,解決起來就容易多了。我們建議的解決辦法如下:
1、我們要保證jsp向客戶端輸出時是采用中文編碼方式輸出的,即無論如何我們首先在我們的jsp源代編中加入以下一行:
<%@page contenttype=”text/html;
charset=gb2312″%>
2、為了讓jsp能正確獲得傳入的參數,我們在jsp源文件頭加入下面一句:
<%request.setcharacterencoding(”gb2312″);
%>
3、為了讓jsp編譯器能正確地解碼我們的含有中文字符的jsp文件,我們需要在jsp源文件中指定我們的jsp源文件的編碼格式,具體來說,我們在jsp源文件頭上加入下面的一句即可:
<%@page pageencoding=”gb2312″%>
或<%@page pageencoding=”gbk”%>
這是jsp規范2.0新增加的指令。
我們建議使用此方法來解jsp文件中的中文問題,下面的代碼是一個正確做法的jsp文件的測試程序:
//testchinese.jsp
<%@page pageencoding=”gb2312″%>
<%@page contenttype=”text/html;
charset=gb2312″%>
<%request.setcharacterencoding(”gb2312″);
%>
<%
string action = request.getparameter(”action”);
string name = “”;
string str = “”;
if(action!=null && action.equals(”sent”))
{
name = request.getparameter(”name”);
str = request.getparameter(”str”);
}
%>
<html>
<head>
<title></title>
<script language=”javascript”>
function submit()
{
document.base.action =
“?action=sent&str=傳入的中文”;
document.base.method = “post”;
document.base.submit();
}
</script>
</head>
<body bgcolor=”#ffffff”
text=”#000000″ topmargin=”5″>
<form name=”base” method =
“post” target=”_self”>
<input type=”text” name=”name”
value=”" size=”30″>
<a href = “javascript:submit()”>提交</a>
</form>
<%
if(action!=null && action.equals(”sent”))
{
out.println(”<br>你輸入的字符為:”+name);
out.println(”<br>你通過url傳入的字符為:”+str);
}
%>
</body>
</html>
新聞熱點
疑難解答