相信了解JSP代碼的讀者對ISO8859-1一定不陌生,ISO8859-1是我們平時(shí)使用比較多的一個(gè)CodePage,它屬于西歐語(yǔ)系。GB2312-80 是在國內計算機漢字信息技術(shù)發(fā)展初始階段制訂的,其中包含了大部分常用的一、二級漢字和9區的符號。該字符集是幾乎所有的中文系統和國際化的軟件都支持的中文字符集,這也是最基本的中文字符集。
GBK 是 GB2312-80 的擴展,是向上兼容的。它包含了20902個(gè)漢字,其編碼范圍是 0x8140~0xFEFE,剔除高位 0x80 的字位,其所有字符都可以一對一映射到 Unicode 2.0,也就是說(shuō) Java 實(shí)際上提供了對 GBK 字符集的支持。
>GB18030-2000(GBK2K) 在 GBK 的基礎上進(jìn)一步擴展了漢字,增加了藏、蒙等少數民族的文字。GBK2K 從根本上解決了字位不夠、字形不足的問(wèn)題。
1.Tomcat 4開(kāi)發(fā)平臺
這個(gè)版本應該是我們經(jīng)常用到的版本,所以討論得會(huì )比較詳細。
Windows 98/2000下的Tomcat 4以上版本都會(huì )出現中文問(wèn)題(而在Linux下和Tomcat 3.x中則沒(méi)有問(wèn)題),主要表現是頁(yè)面顯示亂碼。
為解決這個(gè)問(wèn)題,最簡(jiǎn)單的方法就是在每個(gè)JSP的頁(yè)面開(kāi)始處加上<%@ page language=“Java” contentType=“text/html; charset=gb2312”%>。不過(guò),這還不夠,雖然這時(shí)顯示了中文,但是發(fā)現從數據庫讀出的字段變成了亂碼。經(jīng)過(guò)分析發(fā)現: 在數據庫中保存的中文字符是正常的,數據庫用ISO8859-1字符集存取數據,而Java程序在處理字符時(shí)默認采用統一的ISO8859-1字符集(這也體現了Java國際化思想),所以在數據添加的時(shí)候Java和數據庫都是以ISO8859-1方式處理,這樣不會(huì )出錯。但是在讀取數據的時(shí)候就出現問(wèn)題了,因為數據讀出也采用ISO8859-1字符集,而 JSP的文件頭中有語(yǔ)句<%@ page language=“Java” contentType=“text/html; charset=gb2312”%>,這說(shuō)明頁(yè)面采用GB2312的字符集顯示,這樣就和讀出的數據不一樣。這時(shí)頁(yè)面顯示從數據庫中讀出的字符是亂碼,解決的方法是對這些字符轉碼,從ISO8859-1轉成GB2312,就可以正常顯示了。這個(gè)解決辦法對很多平臺具有通用性,讀者可以靈活運用。具體的方法會(huì )在以下詳細講解。另外,對于不同的數據庫如SQL Server,Oracle,Mysql,Sybase等,字符集的選擇很重要。如果考慮多語(yǔ)言版本,數據庫的字符集就應該統一采用ISO8859-1,需要輸出的時(shí)候在不同的字符集之間做轉換就可以了。
以下是針對不同平臺的總結:
(1) JSWDK只適合于普通開(kāi)發(fā),穩定性和其他問(wèn)題可能不如商業(yè)軟件。 由于JDK 1.3版性能要好于JDK 1.2.2很多,并且對中文的支持也較好,所以應該盡量采用。 現在jdk已經(jīng)出到1.4版本了,所以如果允許最好升級到最新的版本,這樣對中文的也會(huì )較好,而且還可以得到更多的支持。
(2) Tomcat僅僅是一個(gè)對JSP 1.1、Servlet 2.2標準的實(shí)現, 我們不應該要求這個(gè)免費軟件在細節和性能上都面面俱到, 它主要考慮英文用戶(hù), 這也是為什么不做特殊轉換,漢字用URL方法傳遞就有問(wèn)題的原因。大部分IE瀏覽器缺省始終以UTF-8發(fā)送, 這似乎是Tomcat的一個(gè)不足, 另外Tomcat不管當前的操作系統是什么語(yǔ)言, 都按ISO8859去編譯JSP, 似乎也欠妥。
2.JSP代碼的中文處理
(1)如果與數據無(wú)關(guān)的操作,可以在頁(yè)面首行加入<%@ page language=“Java” contentType=“text/html; charset=gb2312”%>
(2)將Form中的值傳送到數據庫中再取出來(lái)后全變成了“?”。Form用POST提交數據,代碼中使用了語(yǔ)句:
String st=new(request.getParameter(“name”).getBytes(“ISO8859_1”)), 而且也聲明了charset=gb2312。
要處理Form中傳遞的中文參數,應該在JSP中加入下面的代碼,另外定義一個(gè)專(zhuān)門(mén)解決這個(gè)問(wèn)題的getStr類(lèi),然后對接收到的參數進(jìn)行轉換:
String keyword1=request.getParameter(“keyword1”);
keyword1=getStr(keyword1);
這樣就可以解決問(wèn)題了,代碼如下:
<%@ page contentType=“text/html;charset=gb2312”%>
<%!
public String getStr(String str){
try{String temp_p=str;
byte[] temp_t=temp_p.getBytes(“ISO8859-1”);
String temp=new String(temp_t);
return temp;
}
catch(Exception e){ }
return “NULL”;
}
%>
<%--http://www.cndes.com測試--%>
<% String keyword=“創(chuàng )聯(lián)網(wǎng)絡(luò )技術(shù)中心歡迎您的到來(lái)”;
String keyword1=request.getParameter(“keyword1”);
keyword1=getStr(keyword1);
out.print(keyword);
out.print(keyword1);
%>
另外,流行的關(guān)系數據庫系統都支持數據庫Encoding,也就是說(shuō)在創(chuàng )建數據庫時(shí)可以指定它自己的字符集設置,數據庫的數據以指定的編碼形式存儲。當應用程序訪(fǎng)問(wèn)數據時(shí),在入口和出口處都會(huì )有 Encoding 轉換。對于中文數據,數據庫字符編碼的設置應當保證數據的完整性。 GB2312、GBK、UTF-8 等都是可選的數據庫 Encoding,也可以選擇 ISO8859-1 (8-bit), 但會(huì )增加了編程的復雜度,ISO8859-1不是推薦的數據庫 Encoding。在JSP/Servlet編程時(shí),可以先用數據庫管理系統提供的管理功能檢查其中的中文數據是否正確。
(3)JDBC Driver的字符轉換
目前大多數JDBC Driver采用本地編碼格式來(lái)傳輸中文字符,例如中文字符“0x4175”會(huì )被轉成“0x41”和“0x75”進(jìn)行傳輸。因此需要對JDBC Driver返回的字符以及要發(fā)給JDBC Driver的字符進(jìn)行轉換。當用JDBC Driver向數據庫中插入數據時(shí),需要先將Unicode轉成Native code; 當 JDBC Driver從數據庫中查詢(xún)數據時(shí),則需要將Native code轉換成Unicode。下面給出了這兩種轉換的實(shí)現:
String native2Unicode(String s) {
if (s == null || s.length() == 0) {
return null;
}
byte[] buffer = new byte[s.length()];
for (int i = 0; i s.length(); i++) { if (s.charAt(i)>= 0x100) {
c = s.charAt(i);
byte []buf = (“”+c).getBytes();
buffer[j++] = (char)buf[0];
buffer[j++] = (char)buf[1];
}
else {buffer[j++] = s.charAt(i);}
}
return new String(buffer, 0, j);
}
要注意的是,有些JDBC Driver如果通過(guò)JDBC Driver Manager設置了正確的字符集屬性,以上方法就不需要了。具體情況可參考相關(guān)JDBC的資料。
其實(shí)理解了,中文亂碼就這么一回事!反復使用就會(huì )摸出一定的門(mén)道了!我覺(jué)得以上的三種方法,只要你真的能弄懂,在遇到中文問(wèn)題時(shí),在這三種方法多試嘗,我保證你不再會(huì )使這種中文問(wèn)題所煩!
以上只是自己的一些經(jīng)驗所談,如果有什么不對,希望能提出,共同學(xué)習!
聯(lián)系客服