首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

JSP/Servlet 中的汉字编码问题(1)

JSP/Servlet 中的汉字编码问题(1)

问题的起源每个国家(或区域)都规定了计算机信息交换用的字符编码集,如美国的扩展 ASCII 码 , 中国的 GB2312-80,日本的 JIS 等,作为该国家 / 区域内信息处理的基础,有着统一编码的重要作用。字符编码集按长度分为 SBCS(单字节字符集),DBCS(双字节字符集)两大类。早期的软件(尤其是操作系统),为了解决本地字符信息的计算机处理,出现了各种本地化版本(L10N),为了区分,引进了 LANG, Codepage 等概念。但是由于各个本地字符集代码范围重叠,相互间信息交换困难;软件各个本地化版本独立维护成本较高。因此有必要将本地化工作中的共性抽取出来,作一致处理,将特别的本地化处理内容降低到最少。这也就是所谓的国际化(I18N)。各种语言信息被进一步规范为 Locale 信息。处理的底层字符集变成了几乎包含了所有字形的 Unicode。
现在大部分具有国际化特征的软件核心字符处理都是以 Unicode 为基础的,在软件运行时根据当时的 Locale/Lang/Codepage 设置确定相应的本地字符编码设置,并依此处理本地字符。在处理过程中需要实现 Unicode 和本地字符集的相互转换,甚或以 Unicode 为中间的两个不同本地字符集的相互转换。这种方式在网络环境下被进一步延伸,任何网络两端的字符信息也需要根据字符集的设置转换成可接受的内容。
Java 语言内部是用 Unicode 表示字符的,遵守 Unicode V2.0。Java 程序无论是从 / 往文件系统以字符流读 / 写文件,还是往 URL 连接写 HTML 信息,或从 URL 连接读取参数值,都会有字符编码的转换。这样做虽然增加了编程的复杂度,容易引起混淆,但却是符合国际化的思想的。
从理论上来说,这些根据字符集设置而进行的字符转换不应该产生太多问题。而事实是由于应用程序的实际运行环境不同,Unicode 和各个本地字符集的补充、完善,以及系统或应用程序实现的不规范,转码时出现的问题时时困扰着程序员和用户。        
GB2312-80,GBK,GB18030-2000 汉字字符集及 Encoding其实解决 JAVA 程序中的汉字编码问题的方法往往很简单,但理解其背后的原因,定位问题,还需要了解现有的汉字编码和编码转换。
GB2312-80 是在国内计算机汉字信息技术发展初始阶段制定的,其中包含了大部分常用的一、二级汉字,和 9 区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位 0xa1-0xfe,低位也是 0xa1-0xfe;汉字从 0xb0a1 开始,结束于 0xf7fe;
GBK 是 GB2312-80 的扩展,是向上兼容的。它包含了 20902 个汉字,其编码范围是 0x8140-0xfefe,剔除高位 0x80 的字位。其所有字符都可以一对一映射到 Unicode 2.0,也就是说 JAVA 实际上提供了 GBK 字符集的支持。这是现阶段 Windows 和其它一些中文操作系统的缺省字符集,但并不是所有的国际化软件都支持该字符集,感觉是他们并不完全知道 GBK 是怎么回事。值得注意的是它不是国家标准,而只是规范。随着 GB18030-2000 国标的发布,它将在不久的将来完成它的历史使命。
GB18030-2000(GBK2K) 在 GBK 的基础上进一步扩展了汉字,增加了藏、蒙等少数民族的字形。GBK2K 从根本上解决了字位不够,字形不足的问题。它有几个特点,
  • 它并没有确定所有的字形,只是规定了编码范围,留待以后扩充。
  • 编码是变长的,其二字节部分与 GBK 兼容;四字节部分是扩充的字形、字位,其编码范围是首字节 0x81-0xfe、二字节 0x30-0x39、三字节 0x81-0xfe、四字节 0x30-0x39。
  • 它的推广是分阶段的,首先要求实现的是能够完全映射到 Unicode 3.0 标准的所有字形。
  • 它是国家标准,是强制性的。
现在还没有任何一个操作系统或软件实现了 GBK2K 的支持,这是现阶段和将来汉化的工作内容。
Unicode 的介绍 ...... 就免了吧。
JAVA 支持的 encoding 中与中文编程相关的有:( 有几个在 JDK 文档中未列出 )
ASCII7-bit, 同 ascii7ISO8859-18-bit, 同 8859_1,ISO-8859-1,ISO_8859-1,latin1...GB2312-80同 gb2312,gb2312-1980,EUC_CN,euccn,1381,Cp1381, 1383, Cp1383,  ISO2022CN,ISO2022CN_GB......GBK( 注意大小写 ), 同 MS936UTF8UTF-8GB18030( 现在只有 IBM JDK1.3.? 有支持 ), 同 Cp1392,1392
JAVA 语言采用 Unicode 处理字符 . 但从另一个角度来说,在 java 程序中也可以采用非 Unicode 的转码,重要的是保证程序入口和出口的汉字信息不失真。如完全采用 ISO-8859-1 来处理汉字也能达到正确的结果。网络上流行的许多解决方法,都属于这种类型。为了不致引起混淆,本文不对这种方法作讨论。
返回列表