`
feiyang404
  • 浏览: 56115 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
B7dcf87c-a349-3458-aa59-9c6036b3f5f6
从零开始一步一步做论坛
浏览量:10111
社区版块
存档分类
最新评论

乱码的由来

阅读更多

两个方向转换都有可能得到错误的结果:

  • Unicode-->Byte, 如果目标代码集不存在对应的代码,则得到的结果是 0x3f.

    如: 
    "\u00d6\u00ec\u00e9\u0046\u00bb\u00f9".getBytes("GBK") 的结果是 "? ìé F? ù", Hex 值是 3fa8aca8a6463fa8b4.

    仔细看一下上面的结果,你会发现 \u00ec 被转换为 0xa8ac, \u00e9 被转换为 \xa8a6... 它的实际有效位变长了! 这是因为 GB2312 符号区中的一些符号被映射到一些公共的符号编码,由于这些符号出现在 ISO-8859-1 或其它一些 SBCS 字符集中,故它们在 Unicode 中编码比较靠前,有一些其有效位只有 8 位,和汉字的编码重叠 ( 其实这种映射只是编码的映射,在显示时仔细不是一样的。Unicode 中的符号是单字节宽,汉字中的符号是双字节宽 ) . 在 Unicode\u00a0--\u00ff 之间这样的符号有 20 个。了解这个特征非常重要!由此就不难理解为什么 JAVA 编程中,汉字编码的错误结果中常常会出现一些乱码 ( 其实是符号字符 ), 而不全是'?'字符 , 就比如上面的例子。

  • Byte-->Unicode, 如果 Byte 标识的字符在源代码集不存在,则得到的结果是 0xfffd.

    如: 
    Byte ba[] = {(byte)0x81,(byte)0x40,(byte)0xb0,(byte)0xa1}; new String(ba,"gb2312");

    结果是"? 啊", hex 值是"\ufffd\u554a". 0x8140 是 GBK 字符,按 GB2312 转换表没有对应的值,取 \ufffd. ( 请注意:在显示该 uniCode 时,因为没有对应的本地字符,所以也适用上一种情况,显示为一个"?".)

实际编程中,JSP/Servlet 程序得到错误的汉字信息,往往是这两个过程的叠加,有时甚至是两个过程叠加后反复作用的结果 .

网上常出现的 JSP/Servlet encoding 问题一般都表现在 browser 或应用程序端,如 :

  • 浏览器中看到的 Jsp/Servlet 页面中的汉字怎么都成了 ’ ? ’ ?
  • 浏览器中看到的 Servlet 页面中的汉字怎么都成了乱码?
  • JAVA 应用程序界面中的汉字怎么都成了方块?
  • Jsp/Servlet 页面无法显示 GBK 汉字。
  • JSP 页面中内嵌在 <%...%>,<%=...%> 等 Tag 包含的 JAVA code 中的中文成了乱码,但页面的其它汉字是对的。
  • Jsp/Servlet 不能接收 form 提交的汉字。
  • JSP/Servlet 数据库读写无法获得正确的内容。

隐藏在这些问题后面的是各种错误的字符转换和处理(除第 3 个外,是因为 Java font 设置错误引起的)。解决类似的字符 encoding 问题,需要了解 Jsp/Servlet 的运行过程,检查可能出现问题的各个点。

其中有字符编码转换的地方有 :

  • JSP 编译。Java 应用服务器将根据 JVM 的 file.encoding 值读取 JSP 源文件,编译生成 JAVA 源文件,再根据 file.encoding 值写回文件系统。如果当前系统语言支持 GBK,那么这时候不会出现 encoding 问题。如果是英文的系统,如 LANG 是 en_US 的 Linux, AIX 或 Solaris,则要将 JVM 的 file.encoding 值置成 GBK 。系统语言如果是 GB2312,则根据需要,确定要不要设置 file.encoding,将 file.encoding 设为 GBK 可以解决潜在的 GBK 字符乱码问题

  • Java 需要被编译为 .class 才能在 JVM 中执行,这个过程存在与 a. 同样的 file.encoding 问题。从这里开始 servlet 和 jsp 的运行就类似了,只不过 Servlet 的编译不是自动进行的。对于 JSP 程序 , 对产生的 JAVA 中间文件的编译是自动进行的 ( 在程序中直接调用 sun.tools.javac.Main 类 ). 因此如果在这一步出现问题的话 , 也要检查 encoding 和 OS 的语言环境,或者将内嵌在 JSP JAVA Code 中的静态汉字转为 Unicode, 要么静态文本输出不要放在 JAVA code 中。 对于 Servlet, javac 编译时手工指定 -encoding 参数就可以了。

  • Servlet 需要将 HTML 页面内容转换为 browser 可接受的 encoding 内容发送出去。依赖于各 JAVA App Server 的实现方式,有的将查询 Browser 的 accept-charset 和 accept-language 参数或以其它猜的方式确定 encoding 值,有的则不管。因此采用固定 encoding 也许是最好的解决方法。对于中文网页,可在 JSP 或 Servlet 中设置 contentType="text/html; charset=GB2312";如果页面中有 GBK 字符,则设置为 contentType="text/html; charset=GBK",由于 IE 和 Netscape 对 GBK 的支持程度不一样,作这种设置时需要测试一下。 因为 16 位 JAVA char 在网络传送时高 8 位会被丢弃,也为了确保 Servlet 页面中的汉字(包括内嵌的和 servlet 运行过程中得到的)是期望的内码,可以用 PrintWriter out=res.getWriter() 取代 ServletOutputStream out=res.getOutputStream(). PrinterWriter 将根据 contentType 中指定的 charset 作转换 (ContentType 需在此之前指定! ); 也可以用 OutputStreamWriter 封装 ServletOutputStream 类并用 write(String) 输出汉字字符串。 对于 JSP,JAVA Application Server 应当能够确保在这个阶段将嵌入的汉字正确传送出去。

  • 这是解释 URL 字符 encoding 问题。如果通过 get/post 方式从 browser 返回的参数值中包含汉字信息, servlet 将无法得到正确的值。SUN 的 J2SDK 中,HttpUtils.parseName 在解析参数时根本没有考虑 browser 的语言设置,而是将得到的值按 byte 方式解析。这是网上讨论得最多的 encoding 问题。因为这是设计缺陷,只能以 bin 方式重新解析得到的字符串;或者以 hack HttpUtils 类的方式解决。参考文章 2 均有介绍,不过最好将其中的中文 encoding GB2312、 CP1381 都改为 GBK,否则遇到 GBK 汉字时,还是会有问题。 Servlet API 2.3 提供一个新的函数 HttpServeletRequest.setCharacterEncoding 用于在调用 request.getParameter(“param_name”) 前指定应用程序希望的 encoding,这将有助于彻底解决这个问题。

分享到:
评论

相关推荐

    JAVA常见中文乱码问题解决方法

    一、问题的由来 早期的计算机系统主要支持单字节编码的英文字符,但随着多语言需求的增加,Unicode编码应运而生,它能兼容英文和其他多字节字符,如中文。Java设计时采用了Unicode编码,以实现跨平台的兼容性。然而...

    java乱码处理

    #### 一、Java中文问题的由来 Java作为一种跨平台的编程语言,其内部实现和class文件均基于Unicode编码,这为Java程序带来了优秀的跨平台特性。然而,这也同时带来了一些关于中文乱码的问题。中文乱码问题大致可以...

    java插入数据乱码解决集锦

    #### 一、Java中文问题的由来及核心问题解析 Java作为一种广泛使用的编程语言,在处理中文等多语言文本时可能会遇到字符编码不匹配导致的乱码问题。这些问题主要源于Java程序在不同环境下与各种存储媒介(如数据库...

    JSP中文乱码问题综述,中文乱码解决大全

    **一、Java中文问题的由来** Java和JSP源文件的编码问题主要体现在两个方面: 1. **源文件编码**:Java和JSP源文件可能包含中文字符,如果源文件的保存编码与编译时使用的编码不匹配,编译后的class文件就可能出现...

    JavaJSP中文乱码问题解决心得.doc

    #### 一、Java中文问题的由来 Java作为一种广泛使用的编程语言,其核心设计目标之一就是提供良好的跨平台能力。为此,Java采用了Unicode作为其内部处理字符的标准,这使得Java程序能够很好地支持各种语言文字。然而...

    Java/JSP中文解决方案

    一、Java中文问题的由来 Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了中文乱码问题的麻烦。主要有两方面的原因:Java和JSP文件本身编译时产生的乱码问题和Java程序于其他...

    字符编码详解

    #### 一、编码问题的由来及相关概念理解 ##### 1.1 字符与编码的发展历程 字符编码的历史可以追溯到计算机发展的早期阶段,当时计算机仅能支持英语,即ASCII(American Standard Code for Information Interchange...

    字节、字符、编码的相关知识

    #### 编码问题的由来与概念理解 **1.1 字符与编码的发展** 计算机对多国语言的支持经历了三个主要阶段:ASCII、多字节字符(MBCS)和Unicode。早期的ASCII阶段,每个字符仅占用一个字节,适用于英语等拉丁字母为主...

    计算机趣味小故事.pdf

    趣味故事可能讲述了一些著名软件缺陷(BUG)的来历,比如著名的“千年虫”问题,以及为了解决这些BUG所作出的努力和创意方法。 3. 计算机科学理论的通俗解释:趣味故事可能用更容易理解的方式来解释复杂的计算机...

    JSP/Servlet 中的汉字编码问题

    JSP/Servlet 中的汉字编码问题 ...’、乱码的由来 JSP/Servlet 汉字编码问题及在 WAS 中的解决办法 结束语 参考文章 1. 问题的起源每个国家(或区域)都规定了计算机信息交换用的字符编码集,如美国的扩展 ASCII码, 中

    TortoiseGit

    TortoiseGit的名字由来是因为其设计灵感来源于TortoiseSVN,一个同样流行的Subversion客户端。 **1. Git基础理解** Git是一款分布式版本控制系统,由Linux创始人Linus Torvalds开发,旨在解决软件开发中的版本管理...

    css与js加密法

    这就是"CSS与JS加密法"的由来。 **CSS加密**的主要目的是保护样式信息不被轻易获取,防止他人抄袭或滥用。CSS加密通常包括混淆、编码和压缩等步骤。混淆是通过改变CSS规则的结构和命名,使得代码变得难以阅读和理解...

    跟我学习注册表

    &lt;br&gt;注册表基础知识 注册表的由来 注册表的数据结构 注册表的编辑 注册表的查找与修改 注册表的内部结构 注册表的分析 注册表--根键详解 HKEY_CLASSES_ROOT根键详解 HKEY_USERS根...

    六年级语文下册《橘逾淮为枳》教学设计模板.pdf

    根据提供的信息,我们可以...需要特别注意的是,由于原始文件【部分内容】的描述中存在大量的乱码字符,因此在实际教学设计中应避免使用这些无法解读的内容,而是依据已有的知识点进行合理的内容组织与教学活动策划。

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    21.1 中文乱码问题产生的由来 610 21.1.1 常用字符集 610 21.1.2 对乱码产生过程的分析 612 21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    21.1 中文乱码问题产生的由来 610 21.1.1 常用字符集 610 21.1.2 对乱码产生过程的分析 612 21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    21.1 中文乱码问题产生的由来 610 21.1.1 常用字符集 610 21.1.2 对乱码产生过程的分析 612 21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    21.1 中文乱码问题产生的由来 610 21.1.1 常用字符集 610 21.1.2 对乱码产生过程的分析 612 21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化...

    ydusi学习资料

    由于提供的部分内容是乱码,无法直接从中提取有意义的信息,因此我们将基于标题和描述来探讨可能涉及的知识点。 ### ydusi学习资料可能涵盖的知识点 #### 1. ydusi简介 - **定义与背景**:首先,我们需要了解ydusi...

    汉字基础数据词组.百家姓

    ### 百家姓的由来与演变 《百家姓》是一部记录中国古代姓氏的著作,其形成可以追溯到北宋时期,具体时间约为公元960年至1279年之间。它最初的形式是由一个名为王安石的人编纂的,但经过多次修订和补充,最终成为了...

Global site tag (gtag.js) - Google Analytics