| cinc 回复于:2002-11-14 00:20:26
|
刚才和 eclipse 一起试了老半天才把 mysql 的中文搞出来,呵呵有意思,也挺高兴的。
Java 的 Unicode 功能很强大,但要真正理解他才能用的好。
顺便贴一篇: 別人解決server side java中文問題的方法 時間: Sun Jul 28 21:57:16 2002
Java Server Side 中文解決方案 gerrykuo
在這個網站上看了很多文章關於在Java裡面使用中文的方法,只有嘆氣搖頭。 為什麼要用getBytes然後再轉BIG5呢?這種解決方法從一開始根本就錯了。
最好的解決方法是從資料進來的時候就要正確的抓到資料。
我這一兩個月利用下班時間寫了一個用Java Servlet以及XML/XSL來作的留言 板,同時支援簡體、繁體,甚至日文的輸入與顯示,這是怎麼做到的呢?很 簡單,利用Unicode。
我的servlet處理中文只要兩個指令: response.setContentType("text/html;charset=UTF-8" ; request.setCharacterEncoding("UTF-8" ; (此功能j2ee 1.3就有了)
之後不管你要getParameter或是printWriter.write都可以把所有的String直接 拿來用,不用再做什麼轉換。存到database裡面的資料也是直接儲存unicode。 我用的資料庫是PostgreSQL因為它是唯一支援Unicode的開放軟體資料庫(唯一 要注意的是PostgreSQL在initdb要用SQL-ASCII或是UNICODE,不能用 mule-internal,如果你用過PostgreSQL應該知道我在講什麼)。你如 果用的是Oracle或SQLserver, DB2他們的新版應該都是支援Unicode的。mySQL 雖然很快,但是它的功能實在不足(也沒有支援unicode),尤其JDBC的driver 還沒有官方版,不用也罷。 我本來想移植到mySQL上,但是它竟然連resultSet.isBeforeFirst()都沒有 實作,那我怎麼判斷結果有沒有資料啊?
你會說,但是user輸入的是BIG5啊?別擔心,browser早就幫你解決這個問題了。 只要你用response.setContentType("text/html;charset=UTF-8" ;接下來雖然 你輸入的是big5,但是當browser送出來的時候,它就會根據charset來作編碼轉換。 這樣我們再設request.setCharacterEncoding("UTF-8" ;然後你用getParameter 時它就會把UTF-8轉成真正的unicode。
這個就是系統的美妙之處了,當你在簡體的系統上看同樣的page時,因為文件的 內容Java已經幫你從unicode轉成UTF-8了,所以你還是可以看到繁體字,而你在 reply這篇文章時雖然用的是GB,但是當從browser送出來的時候,它又轉成UTF-8 了,然後我們的程式一樣處理,當你回到繁體系統來看,又可以看到剛剛發的 簡體的reply。
如果你在英文的系統下,想要copy一篇中文文章進來,絕對不能用BIG5直接貼, 因為這時系統的default encoding不對,轉碼會錯。這時你要先用browser先把 文章讀出來,把"中文字"(不是BIG5碼)copy,貼進來。因為當你在browser裡面 看到中文字時,這個中文字已經是用unicode在顯示了。
所以這個解決方案才能真正做到: "所見即所得"。也就是說,只要你看得到你 輸入的東西,你就可以看到你想要的輸出結果。這也就是你在英文環境下,貼 BIG5的"亂碼",這個程式也會回big5的"亂碼"給你的原因。
Unicode是Java一個對國際化/本土化很好的支援,我們要好好利用這個優點, 做出以前想都沒辦法想的軟體。LinuxFab雖然可以顯示繁體與簡體,但我若是 大陸的使用者,沒看到"簡繁"那小小的兩個字,而在繁體的網頁輸入了簡體呢? 會有問題。除了用unicode,其他解決的方法都會很複雜,現在Java對server side的國際化支援算是完整了(1.3之前沒有request.setCharaterEncoding(), 總是礙手礙腳),希望大家不要在把unicode當成是不如php, perl的缺點,東 拼西湊的湊到可以顯示中文;把精力放在程式本身,而不是轉碼上。
台灣用Java的人還是不多,尤其是企業;理由不外是performance, 穩定性。 但是你如果知道美國的嘉信理財(我工作的公司),擁有全世界最強大的商用 超級電腦,我們的程式已經有大約20-30%轉換成Java,轉換的工作還在繼續 中,那你會怎麼想?Server side的Java有絕大多數CGI無法比擬的優點:Thread 執行序,在只比較一個request的時候,CGI會佔優勢,但是當成百上千個 request來的時候,Thread的優勢就會出來。我們公司也是在比較過兩者的 表現之後,才決定進行CGI到Java的轉換的。
我的工作是把這些Java的功能加以中文化來提供給住在美國的華裔,對於Java 中文化的問題已經研究了快兩年了,期間碰過不少問題,幸而跟我們合作的IBM 對於我們提出的問題都能迅速改進,所以我還能保住我的工作。其實這些問題, 在apache, tomcat等等的開放原始碼都已經解決了,我真的不得不佩服這些熱 心的人。所以每次我的問題提出來之後,都還會附加:Tomcat不會有這個問題。 我想這多少也刺激他們迅速的改進。
|
| eclipse 回复于:2002-11-14 00:26:03
|
真要感谢cinc老大从昨天晚上AO到今天早上帮我解决这个问题,我决心这几周挑个周日请他吃烧烤,厦门的朋友谁愿意可以约一下,俺们也聚会一下
上边问题的补充说明,可以直接将"?"换成你所设得变量,而不用setString();方法也可实现中文的正常输入和输出。这样当你的变量是从数组中得来时,并且变量本身是数组的数组时可以让程序变得很easy & short(比如我用得是从另一类中的jtable中返回的数组,本身有个变量,如果在输入还需要一个循环,还要考虑列,行,正确对应。。。。。。恐怕头大了都写不出的),呵呵
给cinc老大再次鼓掌 
|
| iorilu 回复于:2003-01-08 17:09:45
|
太谢谢了,我正好用到
|
| kpflysky 回复于:2003-01-08 17:16:01
|
原来斑竹是厦门的
|
| mydreaming 回复于:2003-02-21 09:59:48
|
[quote:6d41cae8c3="cinc"]最后由cinc在 2002/11/14 00:16am 编辑]
Java 中文问题一直困扰许多学习者。总结了下面的一些情况的解决方法。
希望对大家有帮助。
连接 Mysql Database Server:
----------------------------------------------..........[/quote:6d41cae8c3]
一楼的这篇文章简直是胡说八道,不要误导人家
|
| ii 回复于:2003-02-21 21:23:24
|
追求真的过程,总有反复嘛,人家不为名,不为利,人者见人,知者见知~
|
| joint 回复于:2003-02-28 22:12:24
|
我按照台湾人说的去做了,但是中文显示还是乱码,我附上代码,哪位大哥有空能帮我看看吗?
数据库是postgresql
createdb -E unicode idg;
//----------------------------------------
package web;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;
import java.sql.*;
public class Sender extends HttpServlet
{
public void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException
{
resp.setContentType("text/html; charset=utf-8");
req.setCharacterEncoding("UTF-8");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String driver = "org.postgresql.Driver";
String url = "jdbc:postgresql://localhost:5432/idg";
String user = "postgres";
String passwd = null;
String update = "insert into area values (21, '上海')";
String select = "select * from area";
PrintWriter pw = resp.getWriter();
try
{
Class.forName(driver);
conn = DriverManager.getConnection(url, user, passwd);
stmt = conn.createStatement();
stmt.executeUpdate(update);
rs = stmt.executeQuery(select);
while(rs.next())
{
int areaId = rs.getInt("area_id");
String areaName = rs.getString("area_name");
pw.println( areaId + " " + areaName + "<br>");
}
}
catch (Exception e)
{
e.printStackTrace(pw);
}
finally
{
try
{
// Always close properly
if(rs != null)
{
rs.close();
}
if(stmt != null)
{
stmt.close();
}
if(conn != null)
{
conn.close();
}
}
catch(Exception e)
{
e.printStackTrace(pw);
}
}
}
}
|
| gadfly 回复于:2003-03-03 05:15:44
|
以下是我的测试代码,No problem now.
客户端直接连的,用jsp,我这边现在没环境。不过没什么区别了。
基本上和楼主说的方式一样,但是getBytes不能带编码参数,否则还是有问题。
[code:1:655fde05bc]
package testpostgres;
import java.util.*;
import java.io.*;
import java.sql.*;
public class TestMain
{
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String driver = "org.postgresql.Driver";
String url = "jdbc:postgresql://dbserver:5432/testdb";
String user = "postgres";
String passwd = null;
String update = "";
String select = "select * from area";
try
{
Class.forName(driver);
conn = DriverManager.getConnection(url, user, passwd);
stmt = conn.createStatement();
String str = "上海";
PreparedStatement pStmt = conn.prepareStatement("insert into area values (21, ?)");
pStmt.setString(1,new String(str.getBytes(),"gb2312"));
pStmt.executeUpdate();
rs = stmt.executeQuery(select);
while(rs.next())
{
int areaId = rs.getInt("area_id");
String areaName = rs.getString("area_name");
System.out.println( areaId + ": " + areaName + "<br>");
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
// Always close properly
if(rs != null)
{
rs.close();
}
if(stmt != null)
{
stmt.close();
}
if(conn != null)
{
conn.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
[/code:1:655fde05bc]
|