应的字符。 从上述过程来看,读取和写入的过程是可逆的,那么理应不会出现中文乱码问题。然而,实际应用的 情形,比上述过程要复杂得多。在 Web 应用中,通常都包括了浏览器、Web 服务器、Web
应用程序和数
据库等部分,每一部分都有可能使用不同的字符集,从而导致字符数据在各种不同的字符集之间转换时, 出现乱码的问题。 在 Java 语言中,不同字符集编码的转换,都是通过 Unicode 编码作为中介来完成的。例如,GBK 编 码的字符“中”要转换为 ISO-8859-1(同 ISO8859-1)编码,其过程如下: 同 (1)因为在 Java 中的字符,都是用 Unicode 来表示的,所以 GBK 编码的字符“中”要转换为 Unicode 表示:0xD6D0->0x4E2D。 (2)将字符“中”的 Unicode 编码转换为 ISO-8859-1 编码,因为 Unicode 编码 0x4E2D 在 ISO-8859-1 中没有对应的编码,于是得到 0x3f,也就是字符“?” 。 下面的代码演示了这一过程:
//GBK 编码的字符“中”转换为 Unicode 编码表示 String str="中"; //将字符“中”的 Unicode 编码转换为 ISO-8859-1 编码 byte[] b=str.getBytes("ISO-8859-1");
for(int i=0;i
编码向某个字符集转换时,如果在该字符集中没有对应的编码, 当从 Unicode 编码向某个字符集转换时,如果在该字符集中没有对应的编码,则得到 0x3f(即问号字 ( 。这就是为什么有时候我们输入的是中文,在输出时却变成了问号。 符?) ) 。 从其他字符集向 Unicode 编码转换时,如果这个二进制数在该字符集中没有标识任何的字符,则得到 编码转换时,如果这个二进制数在该字符集中没有标识任何的字符, 的结果是 0xfffd。例如一个 GBK 的编码值 0x8140,从 GB2312 向 Unicode 转换,然而由于 0x8140 不在 。 GB2312 字符集的编码范围(0xa1a1-0xfefe) ,当然也就没有对应任何的字符,所以转换后会得到 0xfffd。 下面的代码演示了这一过程。
//构造一个二进制数据。 byte[] buf={(byte)0x81,(byte)0x40,(byte)0xb0,(byte)0xa1}; //将二进制数据按照 GB2312 向 Unicode 编码转换。 String str=new String(buf,"GB2312");
for(int i=0;i 在输出字符和字符串的时候, 会从 Unicode 编码向中文系统默认的编码 GBK 转换, 由于 Unicode 编码 0xfffd 在 GBK 字符集中没有对应的编码,于是得到 0x3f,输出字符“?” 。最后输出的结果如下:
fffd--? 40--@ 554a--啊
从上述所知,由于存在着多种不同的字符集,在各种字符集之间进行转换,就有可能出现乱码,同样 是中文字符集 GB2312 和 GBK,由于编码范围的不同,某些字符在转换时也会出现乱码。 在一个使用了数据库的 Web 应用程序中, 乱码可能会
在多个环节产生。 由于浏览器会根据本地系统默 认的字符集来提交数据,而 Web 容器默认采用的是 ISO-8859-1 的编码方式解析 POST 数据,在浏览器提 交中文数据后,Web 容器会按照 ISO-8859-1 字符集来解码数据,在这一环节可能会导致乱码的产生。由于 大多数数据库的 JDBC 驱动程序默认采用 ISO-8859-1 的编码方式在 Java 程序和数据库之间传递数据,我 们的程序在向数据库中存储包含中文的数据时,JDBC 驱动首先将程序内部的 Unicode 编码格式的数据转 化为 ISO-8859-1 的格式,然后传递到数据库中,在这一环节可能会导致乱码的产生。目前流行的关系型数 据库系统都支持数据库编码,也就是说在创建数据库时可以指定它自己的字符集设置,数据库的数据以指 定的编码形式存储。当 JDBC 驱动向数据库中保存数据时,有可能还会发生字符集的转换。正是由于在 Web 应用程序运行过程中,输入的中文字符需要在不同的字符集之间来回转换,也就导致了中文乱码问题 的频繁出现。 图 17-1 描述了在 Web 应用的请求响应过程中,发生的字符编码转换过程,其中浏览器是 IE 6.0,Web 容器的是 Tomcat 6.0.16。 从图 17-1 描述的过程中可以看到,如果在 Web 应用程序中不指定任何的字符集,从浏览器端传来的 中文字符,输出回浏览器时,可以正常显示(以简体中文的方式查看网页) 。然而,事情并没有这么简单, 在 Servlet/JSP 中,可能存在着直接写入的或从其他来源读取的中文字符,如果这些字符对应的 Unicode 码 是从 GB2312 编码转换而来,那么以 ISO-8859-1 编码方式输出,这些字符将不能正常显示。所以对于中文 的处理,应该在图 17-1②和⑤的位置明确指定使用 GB2312 或 GBK 字符集。
② ① 浏览器发送 GB2312 编码的 中文数据,例如字符“中” 的 GB2312 编码值 0xd6d0 Web 容器内部使用 ISO-8859-1 编码 格式, 将接收到的二进制编码数据转 换为 Unicode 编码。 相当于调用 new String(buf,"ISO-8859-1"),得到的 Unicode 值为:\u00d6\u00d0 ④ 默认采用 ISO-8859-1,此时相当于调用 "\u00d6\u00d0". getBytes("ISO-8859-1"), 得到 ISO-8859-1 的编码值 0xd6d0,在浏览 器中选择以简体中文的方式查看,因为 0xd6d0 正好是字
上一篇:java中文乱码问题_java代码
下一篇:法律专业开题报告范文