14.10. PostgreSQL + JDBC + Servlet + XMLC 中文完全解決方案

作者:smallufo,Email:smallufo@bigfoot.com

自古以來 Servlet 連結 Database 在中文方面總是有許多問題,尤其是在 web 端,要考慮的因素更多了。有時候,form的文字遇到「許,功」等字, 要使用者自行輸入“\”這個跳說字元;有時候明明把「許,功」insert 進資料庫,但是取出來又會變成〈?〉;而中文的許多次常用字, 例如宏眭滿u痋v,等怪怪的字元,更是讓 programmer 頭髮白了一半。而 encoding 又是個最重要的關鍵,常見的 encoding 有以下幾點:

code  +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
F9D0                              
F9E0                 
F9F0            ╭ ╮ ╰ ╯  

這幾種 encoding 萬馬奔騰,常使 programmer 轉的暈頭轉向, 不知目前身在何處,不知多少 programmer 在此浪費青春。

中文解決方案以前在網路上有許多做法,但是通常都不太完整, 要不然就得大刀闊斧更動到 JDBC driver,或是重新 compile 整個資料庫系統。而為了系統的「完整性」,我並不考慮這些做法。 我的作法可以完整保留 postgreSQL 的完整性〈以 RPM 安裝,不用重新 compile〉,而且 JDBC driver 不用重新 compile。 以下的步驟後半部主要是針對 XMLC 而言,不過一般「純」的 servlet 程式,應該很容易粹取出來。

以下是我的一些環境:

RedHat Linux 7.0 (CLE 1.0),其他的中文環境也應該沒問題。 如果您是英文版的,請安裝 Chinese locale patch 即可。 重點是,當您輸入 'set' 時,可以看到 'LANG=zh_TW' 這個環境變數。

Servlet Engine:Resin 2.0.2

posrgreSQL-7.1.3-1PGDG.i386.rpm,檔案大小 1164817 bytes,直接以 rpm -Uvh 安裝即可,不用重新 compile。JDBC driver 也是直接使用 postgresql-jdbc-7.1.3-1PGDG.i386.rpm 所安裝的 jdbc7.1-1.2.jar 即可。

資料庫請以 Unicode 編碼〈createdb -E Unicode〉,這點最為重要。

Web application Deployment(web.xml) 中的 <web-app> 不要加上 character-encoding="xxx" 這個 attribute

在 servlet 中,請設定 res.setcontentType("text/html; charset=CP950");

form 的參數,直接以 getParameter("xxx") 讀取, 再 insert 進資料庫,不用作任何轉碼。

要從資料庫中讀取資料,得利用: new String(rs.getString("ColName").getBytes("8859_1"),"CP950")

要輸出整份文件〈implement org.enhydra.xml.xmlc.html.HTMLObject 的文件〉時, 不要用 out.println(doc.toDocument()),請改用如下的方法:

org.enhydra.xml.io.OutputOptions options = new OutputOptions();
options.setOmitEncoding(false);
options.setXmlEncoding("Big5");
DOMFormatter formatter = new DOMFormatter(options);
if(iChingVotingsPage.getDelefate() != null) {
  out.println(formatter.toString(iChingVotingsPage.getDelegate()));
) else {
  out.println(formatter.toString(iChingVoringPage));
}

Servlet 檔案要以 javac -encoding CP950 來編譯。

大功告成,如此解決方案,則可以完全正常處理所有罕見以及特殊字元, 不論是插入資料庫,從資料庫取出來在網頁上,都沒有問題。