请教一个已有系统数据移置带来的中文问题

请教一个已有系统数据移置带来的中文问题

我们原来有一套在Linux 7.2, resin, apache, mysql 下的一个j2ee应用,它们的语言编码都是iso8859-1,对中文没有作任何的处理,中文进出数据库,显示都没有问题。但是现在客户要求要把数据库移置到AIX下的Oracle 9i上,并且Oracle 9i数据库字符集要求为gbk或gb2312(天知道客户为什么会有这样的要求),现在的现状是原来的应用部是我写的,如果通过改程序在中文进出数据库的时候做转码处理,那工作量不可估计,并且我们也没有源代码。所以修改程序应该是不可行的。

可行的方法一: EncodingFilter
好像EncodingFilter只能对进入数据库的中文做转换处理,中文出来显示
不能处理吧? 我对EncodingFilter还不是很熟悉,不知道能不能对程序不做任何的修改就可以达到目的(请高手回答这个问题)。并且现在系统的Resin版本很低,连<%@ page contentType="text/html;charset=GB2312"%>都不支持,报下面的错误:
Note: sun.tools.javac.Main has been deprecated.
/HeccTest2.jsp:32: Method setCharacterEncoding(java.lang.String) not found in interface javax.servlet.http.HttpServletRequest.
request.setCharacterEncoding("GB2312");
^
1 error, 1 warning

系统的resin和cocoon是配置在一起的,并且系统一直在运行,不能停,所以升级resin的方法也不行。

方法二:修改oracle的jdbc driver,正准备测试,也不知道行不行。


题外话:我开发时对中文的处理都是,安装Linux是选中gb2312中文,编译Mysql时设定charset=gb2312,安装resin,apache,php,然后对中文就不用做任何处理了

你的Resin连Servlet2.3都不支持?
我有一点不明白,你的字符集问题在数据库上,为什么在Web层设置字符集?

能不能这样,用动态代理拦截所有java.sql.PrepareStatement的setString方法调用,在其中做字符集转换,我没有用过这东西,不知道行不行

java.lang.reflect.Proxy

客户的要求是完全正确的,Oracle必须用GBK。你可以查一下我在前面一个谈到数据库中文问题的帖子。

你们遇到的中文问题只能怪你们自己,你们原来开发的系统中,中文解决方案就非常糟糕,现在迁移数据库出问题那也很正常。就算你们把Oracle改用ISO8859_1字符集暂时解决中文问题,也会存在大量潜在问题,随时都会出现中文乱码。修改Oracle的JDBC Driver更不可取。

热升级Resin根本就不是问题,你难道不会在另一个目录再安装一套Resin吗?

先把新的Resin配置好,不要用6702端口,另改一个端口启动Resin,然后在新的Resin下拷贝一套代码,进行调试,调试好再把目录指回去。

接着,编译Resin的mod_caucho,把它拷贝到Apache的相应的目录下。然后修改apache的httpd.conf,修改mod_caucho的指向,修改Resin的转发端口。

最后,apachectl restart
该命令一执行,整个系统就切换到新的Resin上来了,apache中断服务不会超过3秒钟。

最后给你的关于中文解决方案的建议:

最终极的解决方案是用UTF-8编码,但估计你们改动就大了。打点折扣,你在新的Resin下,要注意配置一个javac的选项,使用GBK编译。仔细看看resin.conf配置文件,有关于服务器的默认编码的选择项。

如果这还不能保证request取到的参数是GBK的话,可以写一个ServletFilter,在web.xml里面配置上所有Servlet/JSP使用这个Filter。

然后把所有JSP页面改成GBK编码。


说点题外话,个人意见,hecc觉得我说的不对也请不要在意。

前面看过你的帖子感觉到你好像对自己的技术还比较自负。所以碰到这个中文问题,你置疑客户的要求是无理的。但是我感觉到你的技术还很不扎实,结果你的置疑就显得你自己很肤浅了。

另外我感觉到你的知识面比较窄,如果你对Linux,Apache和Resin都比较熟悉的话,这个问题其实很好解决,不会让你束手无策。

谁年轻的时候都会比较高傲自负一点,我也不例外,但最好不要因为年轻带来的不成熟影响了你的前途。

谢谢各位的意见。
关于用UTF-8的编码,客户表示了不行,因为客户还有另外的应用读取该系统的数据,要求必须是gbk或gb2312。
原来的系统不是我做的,resin和cocoon的版本都很低,并且他们打包的方式都很怪,resin,apache,mysql都没有一级目录分开,全打包在一个目录里面,如一个bin目录,里面有apache的,resin的,mysql的,我真的是很服啊,原来的系统安装是一个很大的问题。我们怕把现在应用给搞坏了。

现在数据库oracle 9i的编码必须为gb2312,有什么比较简便的方法?

嗯,说实话既然原来的系统就如此糟糕,现在也该到整理一下的时候了。在你们原来的系统上再做文章,我也想不出什么特别简单有效的办法。

其实把整个系统热升级一下,是个很简单的活。要是我来做的话,有把握半个小时之内全部搞定。

最好的办法是在那台机器上装一套新系统,连接Oracle,把整个系统都调试好了,测试无误了。最后一个命令把系统切换过来,中间也就几秒的停顿,用户是感觉不到的。

呵呵,看来我还是少说话的好,一步小心成了出头鸟,大家都以贬低我的方式来抬高自己,呵呵,开句玩笑。
谁能保证自己说的话没有一点漏洞?我要攻击你的话也很容易的啊。

呵呵,看来我的想法是异想天开了,又受教了

>谁年轻的时候都会比较高傲自负一点,我也不例外,但最好不要因为年轻带来的不成熟影响了你的前途。

robbin 兄,你要相信你自己也很年轻,二十几岁的小伙子呢,不知道在中国干这个行业怎么总是那么容易言老。。。

我小你4、5岁,不知道4、5年后能不能超过你,有时候我真的觉得自己没有前途了。。。

一般来讲,解决编码问题,就是把所有和编码有关的位置统一起来,
数据库,服务器环境,客户端全部采用一样的。

系统停机可以在周末的午夜,呵呵。

>>呵呵,看来我还是少说话的好,一步小心成了出头鸟,大家都以贬低我的方式来抬高自己,呵呵,开句玩笑。谁能保证自己说的话没有一点漏洞?我要攻击你的话也很容易的啊。

其实没有人故意和你为难,提意见的人都是报着希望你更好的想法。
我以前也曾经特别自以为是,不屑理会那些在我看来很弱智的问题,瞧不起我认为很弱智的人,还对给我饭碗的老板发过脾气。大概不会比你的做法好多少。但是真的损失太大了,损失了很多年的青春。这些经验教训都是青春换来的。现在才明白“用心”去做事情,“敬业”才是最重要的。

>>robbin 兄,你要相信你自己也很年轻,二十几岁的小伙子呢,不知道在中国干这个行业怎么总是那么容易言老。。。我小你4、5岁,不知道4、5年后能不能超过你,有时候我真的觉得自己没有前途了。。。

呵呵,我现在才明白前途在哪里,看看下面的转贴内容:
----------------------------------------------------
我有一个对我帮助很多、很大的朋友。他帮助了很多人,有很多朋友。在我很年轻的时候,什么都没有,他经常帮助我,让我很不安,对他说:“你不要对我这么好,因为我实在觉得我没有什么可回报你的。”
他回答说:“如果功利地说报答的话,我帮你,你不必回报我,但是别人会回报我。比如,我帮了你,你可能会对某个人说我的好话。可能,某天,我会撞在这个人的手上,他可以帮我,也可以不帮。他可能会因为你曾经说过一句我的好话,而对我印象不同,也许我就有机会。”
这个朋友不能说很顺利,但是他确实能逢凶化吉;而且他的朋友实在太多,所以他的机会也多。我觉得他大概就是那种有“眷属般若”的人。
昨天,他又给我打电话,批评我不和大家走动,不主动打电话问候别人。
我确实因为过去摔了个大跟头,而现在筹备了一年想做的事情却阴差阳错总是开始不了,所以羞于和过去的朋友见面。
他就批评我说:“你刚大学毕业的时候,是凭着勤奋、敬业、肯被剥削才能被器重,拥有机会做大一点的事情,现在你要想被人尊重,绝不是你能像20岁的小姑娘那样加班熬夜,或者能陪人对着喝白酒,你比刚毕业的人有更高的价值,不是因为你一个人能当两个人用,而是你这些年来,你建立的人脉、你的交际圈子有多少人支持你。我们的体能会下降,知识也会落伍,唯一增长的就是人脉,你还不好好维护?”
听得我涔涔汗下。
让那些自命清高的人去孤芳自赏吧,他们即使出了家也成不了高僧;我们这些身陷万丈红尘之中的人,还是清点一下自己的人脉。说你好的人有几个?真心愿意帮你的人有几个?
如果不想工作几年后,除了经历一无所有的话,还是抓紧时间维护维护自己的人脉吧?趁着SARS时期,把平时没时间打的电话拨拨吧。

unicode 中的CJK 中日韩整合编码是按照部首编码的。
我印象中是。可以找ftp://ftp.unicode.org/Public/UNIDATA/Unihan.txt下载下来字库看看。

首先,我申明一下,我帮不到你什么。因为中文问题受很多东西的影响,光在这里说,没有真正见到系统,我是没法给你意见。这就像医生不给病人做望闻问切就没法确定病根一样。

我曾经花了很多时间来研究 Java 乱码的根本原因。可能是水平太差,根基太浅,我没有能最终找到问题的解决方案。虽然我知道乱码的起因,也积累了一些判断的经验,但是我还是没法预料在一个新的环境里,会发生什么样的情况。

所以,如果是使用我所熟悉的系统环境,如: Linux=en_US.iso885915,Oracle=ISO_8859_1,JSP charset=GBK,Tomcat4.* 那么我可以很顺利地使系统运行。但是换到新的环境,我相信很多人都需要做一个调整,区别可能也就是时间长短的问题。

========================================================
hecc 你说的情况我怎么觉得有些模糊:

一开始你说
"我们原来有一套在Linux 7.2, resin, apache, mysql 下的一个j2ee应用,它们的语言编码都是iso8859-1,对中文没有作任何的处理,中文进出数据库,显示都没有问题"
后来你又说:
我开发时对中文的处理都是,安装Linux是选中gb2312中文,编译Mysql时设定charset=gb2312,安装resin,apache,php,然后对中文就不用做任何处理了

我没法知道你们的系统是从哪个环境转移到 AIX+Oracle下?

=============================================================
最后说一些原则性的东东:

1.操作系统的环境设置,如 Unix 下的 LOCALE/LC_ALL 和 Windows 下的区域设置对 Java 字符结果会产生影响
2.数据库的字符集编码会产生影响(废话!!~_~)
3.数据库 JDBC 程序不同,结果也不一样(我有MySQL 和 SQL Server的经历)
4.不同的 Servlet Container 会产生不同的运行结果,主要原因可能是编译 jsp 文件时使用的 encoding 不同造成的。
5.Java 乱码产生的最重要原因是 JVM 内使用 Unicode 存贮数据。这是我个人对Java乱码产生机制分析后的结论。从JVM 外进入 JVM,使用了 InputStream, JVM 利用给定的 encoding 调用相应的 CharacterConveter 来将字符流转换成相应的Unicode.在输出的时候,也就是从 JVM 到 JVM 外的时候,使用 OutputStream, 按给定的 encoding 调用相应的 CharacterConverter 来转换字符,从 Unicode 转成相应的字符编码。如果在转入或者转出的环节上出现了给定的 encoding 不对的情况,那就会出现乱码。
这里还要注意,从 Java 转出来以后,外部系统也可能会对数据流做处理,这时,因为你从 Java 输入到外部系统的数据不符合外部系统的要求,又会产生乱码(我在 FileSystem 层次上遇到过这个问题)

还有其它的一些经验我就不一一列举了。
希望以上几条,特别是第五条能帮你找到你系统中乱码发生的节点。

Good Luck

"我们原来有一套在Linux 7.2, resin, apache, mysql 下的一个j2ee应用,它们的语言编码都是iso8859-1,对中文没有作任何的处理,中文进出数据库,显示都没有问题"

就是从上面的环境转移到 AIX+Oracle下的

我在本地的测试:
Linux系统我该为gb2312,oracle 8.1.7 encoding = gbk ,写一个java class 将中文插入到oracle中,再读出来没有任何问题,在java class中和在oracle中一个汉字的长度都是1,不用对汉字做任何特殊的处理。

但是这个resin的编码却怎么也配置不到gb2312去,在resin中运行一个jsp,一个汉字的长度是2,这个resin装的可真怪!

刚才再看了一下,实际系统运行的Linux不支持gb2312的编码(安装时没有安装中文字符)。我靠,真是faint!