您的位置:首页 > 其它

有关中文转码的几个基本问题

2010-08-10 18:41 288 查看
以下是我在最近的实践中的总结,写给做J2EE web开发中遇到中文问题的初学者,个中高手就不需过目了。
文中举到的例子取自我自己参与的项目。我是在简体系统下开发繁体web。

网页向servlet传递中文参数的转码过程

一. 在网页的输入框中键入中文字符串,点击提交。

二. 浏览器将键入的中文字符串A编码成字节流A,提交给服务器. (浏览器编码的方式采用的浏览器设定的编码,如IE6中即为"菜单:查看->编码"中指定的编码,下面以MS950为例)。

三. 服务器得到字节流A后,将其按ISO8859_1(默认)解码为字符串B。具体可分为以下两步。
1. 用ISO8859_1的编码规则解释传入的字节流A。得到字符串B。
2. 将解释后的字符串B用UNICODE编码,放在内存中。
servlet程式中用request.getParameter("paraName");得到的便是这样的字符串。
以上可以看出,此时服务器并不知道客户端浏览器发送的字节流是用什么方式编码的,而统一以ISO8859_1来解释传入的以MS950编码的字节流A,此时解释出来的字符串B自然是与网页中输入的字符串A是不同的,也就是错误的。此时无论如何输出,得到的都会是乱码。

四. 了解了上述过程,要使servlet得到正确的字符串A,原理就是将上述过程还原。具体步骤如下:
1. String sPara = request.getParameter("paraName");得到上述“错误”的字符串B。
2. byte bPara = sPara.getBytes("ISO8859_1");得到字节流A,以上还原过程三.1。
3. String sPara = new String(bPara,"MS950");得到字符串A,以上还原过程二。

此时sTmpParaName中保存的就是以UNICODE编码的正确的字符串了。servlet对此字符串一般会有两种操作:读写数据库或向客户端输出。

五. JAVA程式通过JDBC连接器与数据库进行数据交互,交互过程都是以ISO8859_1编码的字节流进行的。以下举例将sPara插入数据库。
1.执行 UPDATE INTO TBNAME SET COLNAME := :sPara
2JAVA程将此SQL语句中的sPara字符串按ISO8859_1编码成字节流,发送给JDBC连接器,JDBC连接器再将此字节流发送给数据库。数据库再根据ISO8859_1方式将此字节流还原为字符串,并将字符串写入数据库中。字符串在数据库中的存储编码方式与数据库设置有关(以UTF8为例)。
以上可以看出,JDBC传输字节流的过程对用户来说是透明的。无论数据库中用何种编码存放,只要保证SQL语句中是“正确”的字符串,就可以正确无误的写入数据库。不需做任何转码。
当JAVA程式从数据库中读取字符串时,有两种方式,一种是直接读出字符串,用sMsg = ResultSet.getString("colName");另一种是读出字节数组,用bMsg = ResultSet.getBytes("colName");前一种直接得到字符串,后一种要得到字符串需要知道数据库的存储编码方式,如:sMsg = new String(bMsg, "utf-8"));。

向客户端输出字符串时,服务器是根据servlet或JSP中的设置,将字符串转码为字节流向浏览器发送的。在JSP中通过<%@page contentType="text/html; charset=MS950"%>设置,在servlet程式中通过response.setContentType("text/html;charset=MS950"); 设置。
客户想要看到正常显示的网页,只要让浏览器的编码设置和上述设置一致,或者兼容即可。如没有上述设置,刚服务器默认以ISO8859_1方式编码后向客户端输出,由于ISO8859_1是单字节编码,无法编码中文字,因而在编码过程中已经失真,因此是无法在浏览器中正确显示的。

关于文字的字节数:
要得到正确的字节数,即字符串存储的大小,关键有以下两点。
1. 正确的字符串,在JAVA中保证UNICODE字符串是真正需要的字符串。
2. 确定的编码方式,不同的编码方式中,同一汉字所占的字节数可能是不同的。
如,我们要得到字符串sPara的MS950编码的字节数,可分以下两步。
1.得到正确的sPara字符串,参考过程四。
2.bPara = sPara.getBytes("MS950");得到MS950编码。
3.bPara.length得到字节数。
如果不指定编码方式,谈论字符串的字节数是没有意义的。

补充:在JAVA中,字符串对象使终是以UNICODE在内存中存放的,而在数据库,文件,网络传输,浏览器中则有不同的编码和存储方式,因些。在遇到中文内码问题时,最方便的思考办法就是以UNICODE字符串为中心,然后确认需要将字符串与字节流或数组进行转换的编码方式。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/javaflute/archive/2005/02/04/280398.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: