⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 java 编程技术中汉字问题的分析及解决.htm

📁 写给JSP初级程序员的书
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<META content="MSHTML 5.00.2920.0" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff text=#000000>
<table>
  <TBODY>
  <TR>
    <TD height=21>
      <DIV align=center><B><FONT size=3>Java 编程技术中汉字问题的分析及解决 
      <BR><FONT size=2> </FONT></FONT></FONT>
      <HR align=center color=#cccccc noShade SIZE=1>
      </DIV></TD></TR>
  <TR>
    <TD class=line><FONT 
      color=#333300>Java&nbsp;编程技术中汉字问题的分析及解决<BR><BR><BR>段明辉<BR>自由撰稿人<BR>2000&nbsp;年&nbsp;11月&nbsp;8日<BR><BR>&lt;!--&nbsp;END&nbsp;title&nbsp;and&nbsp;author&nbsp;lines&nbsp;--&gt;&lt;!--&nbsp;Editor&nbsp;#5:&nbsp;Begin&nbsp;Table&nbsp;of&nbsp;Contents&nbsp;--&gt;&nbsp;<BR>内容:&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;汉字编码的常识&nbsp;<BR>&nbsp;Java&nbsp;中文问题的初步认识&nbsp;<BR>&nbsp;Java&nbsp;中文问题的表层分析及处理&nbsp;<BR>&nbsp;Java&nbsp;中文问题的根源分析及解决&nbsp;<BR>&nbsp;Java&nbsp;Servlet&nbsp;中文问题的根源&nbsp;<BR>&nbsp;修改&nbsp;Servlet.jar&nbsp;<BR>&nbsp;中文乱码的处理函数&nbsp;<BR>&nbsp;参考资料&nbsp;<BR>&nbsp;作者简介&nbsp;<BR>&nbsp;<BR><BR>&lt;!--&nbsp;End&nbsp;Table&nbsp;of&nbsp;Contents&nbsp;--&gt;&lt;!--&nbsp;comments&nbsp;#6:&nbsp;html&nbsp;content&nbsp;of&nbsp;the&nbsp;paper&nbsp;--&gt;&nbsp;<BR>在基于&nbsp;Java&nbsp;语言的编程中,我们经常碰到汉字的处理及显示的问题。一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Java&nbsp;语言默认的编码方式是UNICODE&nbsp;,而我们中国人通常使用的文件和数据库都是基于&nbsp;GB2312&nbsp;或者&nbsp;BIG5&nbsp;等方式编码的,怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编码呢?本文将从汉字编码的常识入手,结合&nbsp;Java&nbsp;编程实例,分析以上两个问题并提出解决它们的方案。<BR><BR><BR>现在&nbsp;Java&nbsp;编程语言已经广泛应用于互联网世界,早在&nbsp;Sun&nbsp;公司开发&nbsp;Java&nbsp;语言的时候,就已经考虑到对非英文字符的支持了。Sun&nbsp;公司公布的&nbsp;Java&nbsp;运行环境(JRE)本身就分英文版和国际版,但只有国际版才支持非英文字符。不过在&nbsp;Java&nbsp;编程语言的应用中,对中文字符的支持并非如同&nbsp;Java&nbsp;Soft&nbsp;的标准规范中所宣称的那样完美,因为中文字符集不只一个,而且不同的操作系统对中文字符的支持也不尽相同,所以会有许多和汉字编码处理有关的问题在我们进行应用开发中困扰着我们。有很多关于这些问题的解答,但都比较琐碎,并不能够满足大家迫切解决问题的愿望,关于&nbsp;Java&nbsp;中文问题的系统研究并不多,本文从汉字编码常识出发,分析&nbsp;Java&nbsp;中文问题,希望对大家解决这个问题有所帮助。<BR><BR>汉字编码的常识&nbsp;<BR><BR>我们知道,英文字符一般是以一个字节来表示的,最常用的编码方法是&nbsp;ASCII&nbsp;。但一个字节最多只能区分256个字符,而汉字成千上万,所以现在都以双字节来表示汉字,为了能够与英文字符分开,每个字节的最高位一定为1,这样双字节最多可以表示64K格字符。我们经常碰到的编码方式有&nbsp;GB2312、BIG5、UNICODE&nbsp;等。关于具体编码方式的详细资料,有兴趣的读者可以查阅相关资料。我肤浅谈一下和我们关系密切的&nbsp;GB2312&nbsp;和&nbsp;UNICODE。GB2312&nbsp;码,中华人民共和国国家标准汉字信息交换用编码,是一个由中华人民共和国国家标准总局发布的关于简化汉字的编码,通行于中国大陆地区及新加坡,简称国标码。两个字节中,第一个字节(高字节)的值为区号值加32(20H),第二个字节(低字节)的值为位号值加32(20H),用这两个值来表示一个汉字的编码。UNICODE&nbsp;码是微软提出的解决多国字符问题的多字节等长编码,它对英文字符采取前面加“0”字节的策略实现等长兼容。如&nbsp;“A”&nbsp;的&nbsp;ASCII&nbsp;码为0x41,UNICODE&nbsp;就为0x00,0x41。利用特殊的工具各种编码之间可以互相转换。<BR><BR>Java&nbsp;中文问题的初步认识&nbsp;<BR><BR>我们基于&nbsp;Java&nbsp;编程语言进行应用开发时,不可避免地要处理中文。Java&nbsp;编程语言默认的编码方式是&nbsp;UNICODE,而我们通常使用的数据库及文件都是基于&nbsp;GB2312&nbsp;编码的,我们经常碰到这样的情况:浏览基于&nbsp;JSP&nbsp;技术的网站看到的是乱码,文件打开后看到的也是乱码,被&nbsp;Java&nbsp;修改过的数据库的内容在别的场合应用时无法继续正确地提供信息。&nbsp;<BR><BR>String&nbsp;sEnglish&nbsp;=&nbsp;“apple”;&nbsp;<BR><BR>String&nbsp;sChinese&nbsp;=&nbsp;“苹果”;&nbsp;<BR><BR>String&nbsp;s&nbsp;=&nbsp;“苹果&nbsp;apple&nbsp;”;&nbsp;<BR><BR>sEnglish&nbsp;的长度是5,sChinese的长度是4,而&nbsp;s&nbsp;默认的长度是14。对于&nbsp;sEnglish来说,&nbsp;Java&nbsp;中的各个类都支持得非常好,肯定能够正确显示。但对于&nbsp;sChinese&nbsp;和&nbsp;s&nbsp;来说,虽然&nbsp;Java&nbsp;Soft&nbsp;声明&nbsp;Java&nbsp;的基本类已经考虑到对多国字符的支持(默认&nbsp;UNICODE&nbsp;编码),但是如果操作系统的默认编码不是&nbsp;UNICODE&nbsp;,而是国标码等。从&nbsp;Java&nbsp;源代码到得到正确的结果,要经过&nbsp;“Java&nbsp;源代码-&gt;&nbsp;Java&nbsp;字节码-&gt;&nbsp;;虚拟机-&gt;操作系统-&gt;显示设备”的过程。在上述过程中的每一步骤,我们都必须正确地处理汉字的编码,才能够使最终的显示结果正确。&nbsp;<BR><BR>“&nbsp;Java&nbsp;源代码-&gt;&nbsp;Java&nbsp;字节码”,标准的&nbsp;Java&nbsp;编译器&nbsp;javac&nbsp;使用的字符集是系统默认的字符集,比如在中文&nbsp;Windows&nbsp;操作系统上就是&nbsp;GBK&nbsp;,而在&nbsp;Linux&nbsp;操作系统上就是ISO-8859-1,所以大家会发现在&nbsp;Linux&nbsp;操作系统上编译的类中源文件中的中文字符都出了问题,解决的办法就是在编译的时候添加&nbsp;encoding&nbsp;参数,这样才能够与平台无关。用法是&nbsp;<BR><BR>javac&nbsp;–encoding&nbsp;GBK。&nbsp;<BR><BR>“&nbsp;Java&nbsp;字节码-&gt;虚拟机-&gt;操作系统”,&nbsp;Java&nbsp;运行环境&nbsp;(JRE)&nbsp;分英文版和国际版,但只有国际版才支持非英文字符。&nbsp;Java&nbsp;开发工具包&nbsp;(JDK)&nbsp;肯定支持多国字符,但并非所有的计算机用户都安装了&nbsp;JDK&nbsp;。很多操作系统及应用软件为了能够更好的支持&nbsp;Java&nbsp;,都内嵌了&nbsp;JRE&nbsp;的国际版本,为自己支持多国字符提供了方便。&nbsp;<BR><BR>“操作系统-&gt;显示设备”,对于汉字来说,操作系统必须支持并能够显示它。英文操作系统如果不搭配特殊的应用软件的话,是肯定不能够显示中文的。&nbsp;<BR><BR>还有一个问题,就是在&nbsp;Java&nbsp;编程过程中,对中文字符进行正确的编码转换。例如,向网页输出中文字符串的时候,不论你是用&nbsp;<BR><BR>out.println(string);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;string&nbsp;是含中文的字符串&nbsp;<BR><BR>还是用&nbsp;<BR><BR>&lt;%=string%&gt;,都必须作&nbsp;UNICODE&nbsp;到&nbsp;GBK&nbsp;的转换,或者手动,或者自动。在&nbsp;JSP&nbsp;1.0中,可以定义输出字符集,从而实现内码的自动转换。用法是&nbsp;<BR><BR>&lt;%@page&nbsp;ContentType=”text/html;charset=gb2312”&nbsp;%&gt;&nbsp;<BR><BR>但是在一些&nbsp;JSP&nbsp;版本中并没有提供对输出字符集的支持,(例如&nbsp;JSP&nbsp;0.92),这就需要手动编码输出了,方法非常多。最常用的方法是&nbsp;<BR><BR>String&nbsp;s1&nbsp;=&nbsp;request.getParameter(“keyword”);&nbsp;<BR><BR>String&nbsp;s2&nbsp;=&nbsp;new&nbsp;String(s1.getBytes(“ISO-8859-1”),”GBK”);&nbsp;<BR><BR>getBytes&nbsp;方法用于将中文字符以“ISO-8859-1”编码方式转化成字节数组,而“GBK”&nbsp;是目标编码方式。我们从以ISO-8859-1方式编码的数据库中读出中文字符串&nbsp;s1&nbsp;,经过上述转换过程,在支持&nbsp;GBK&nbsp;字符集的操作系统和应用软件中就能够正确显示中文字符串&nbsp;s2&nbsp;。&nbsp;<BR><BR>Java&nbsp;中文问题的表层分析及处理&nbsp;<BR><BR>&lt;div&nbsp;align=center&gt;&nbsp;背景&nbsp;<BR>&nbsp;<BR>开发环境&nbsp;<BR>&nbsp;JDK1.15&nbsp;<BR>&nbsp;Vcafe2.0&nbsp;<BR>&nbsp;JPadPro&nbsp;<BR>&nbsp;<BR>服务器端&nbsp;<BR>&nbsp;NT&nbsp;IIS&nbsp;<BR>&nbsp;Sybase&nbsp;System&nbsp;<BR>&nbsp;Jconnect(JDBC)&nbsp;<BR>&nbsp;<BR>客户端&nbsp;<BR>&nbsp;IE5.0&nbsp;<BR>&nbsp;Pwin98&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;<BR><BR>.CLASS&nbsp;文件存放在服务器端,由客户端的浏览器运行&nbsp;APPLET&nbsp;,&nbsp;APPLET&nbsp;只起调入&nbsp;FRAME&nbsp;类等主程序的作用。界面包括&nbsp;Textfield&nbsp;,TextArea,List,Choice&nbsp;等。&nbsp;<BR><BR>I.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;取中文&nbsp;<BR><BR>用&nbsp;JDBC&nbsp;执行&nbsp;SELECT&nbsp;语句从服务器端读取数据(中文)后,将数据用&nbsp;APPEND&nbsp;方法加到&nbsp;TextArea(TA)&nbsp;,不能正确显示。但加到&nbsp;List&nbsp;中时,大部分汉字却可正确显示。&nbsp;<BR><BR>将数据按“ISO-8859-1”&nbsp;编码方式转化为字节数组,再按系统缺省编码方式&nbsp;(Default&nbsp;Character&nbsp;Encoding)&nbsp;转化为&nbsp;STRING&nbsp;,即可在&nbsp;TA&nbsp;和&nbsp;List&nbsp;中正确显示。&nbsp;<BR><BR>程序段如下:&nbsp;<BR><BR>dbstr2&nbsp;=&nbsp;results.getString(1);&nbsp;<BR><BR>//After&nbsp;reading&nbsp;the&nbsp;result&nbsp;from&nbsp;DB&nbsp;server,converting&nbsp;it&nbsp;to&nbsp;string.&nbsp;<BR><BR>dbbyte1&nbsp;=&nbsp;dbstr2.getBytes(“iso-8859-1”);&nbsp;<BR><BR>dbstr1&nbsp;=&nbsp;new&nbsp;String(dbbyte1);&nbsp;<BR><BR>在转换字符串时不采用系统默认编码方式,而直接采用“&nbsp;GBK”&nbsp;或者&nbsp;“GB2312”&nbsp;,在&nbsp;A&nbsp;和&nbsp;B&nbsp;两种情况下,从数据库取数据都没有问题。&nbsp;<BR><BR>II.&nbsp;&nbsp;&nbsp;&nbsp;写中文到数据库&nbsp;<BR><BR>处理方式与“取中文”相逆,先将&nbsp;SQL&nbsp;语句按系统缺省编码方式转化为字节数组,再按“ISO-8859-1”编码方式转化为&nbsp;STRING&nbsp;,最后送去执行,则中文信息可正确写入数据库。&nbsp;<BR><BR>程序段如下:&nbsp;<BR><BR>sqlstmt&nbsp;=&nbsp;tf_input.getText();&nbsp;<BR><BR>//Before&nbsp;sending&nbsp;statement&nbsp;to&nbsp;DB&nbsp;server,converting&nbsp;it&nbsp;to&nbsp;sql&nbsp;statement.&nbsp;<BR><BR>dbbyte1&nbsp;=&nbsp;sqlstmt.getBytes();&nbsp;<BR><BR>sqlstmt&nbsp;=&nbsp;newString(dbbyte1,”iso-8859-1”);&nbsp;<BR><BR>_stmt&nbsp;=&nbsp;_con.createStatement();&nbsp;<BR><BR>_stmt.executeUpdate(sqlstmt);&nbsp;<BR><BR>……&nbsp;<BR><BR>问题:如果客户机上存在&nbsp;CLASSPATH&nbsp;指向&nbsp;JDK&nbsp;的&nbsp;CLASSES.ZIP&nbsp;时(称为&nbsp;A&nbsp;情况),上述程序代码可正确执行。但是如果客户机只有浏览器,而没有&nbsp;JDK&nbsp;和&nbsp;CLASSPATH&nbsp;时(称为&nbsp;B&nbsp;情况),则汉字无法正确转换。&nbsp;<BR><BR>我们的分析:&nbsp;<BR><BR>1.经过测试,在&nbsp;A&nbsp;情况下,程序运行时系统的缺省编码方式为&nbsp;GBK&nbsp;或者&nbsp;GB2312&nbsp;。在&nbsp;B&nbsp;情况下,程序启动时浏览器的&nbsp;JAVA&nbsp;控制台中出现如下错误信息:&nbsp;<BR><BR>Can't&nbsp;find&nbsp;resource&nbsp;for&nbsp;sun.awt.windows.awtLocalization_zh_CN&nbsp;<BR><BR>然后系统的缺省编码方式为“8859-1”。&nbsp;<BR><BR>2.如果在转换字符串时不采用系统缺省编码方式,而是直接采用&nbsp;“GBK”&nbsp;或“GB2312”,则在&nbsp;A&nbsp;情况下程序仍然可正常运行,在&nbsp;B&nbsp;情况下,系统出现错误:&nbsp;<BR><BR>UnsupportedEncodingException。&nbsp;<BR><BR>3.在客户机上,把&nbsp;JDK&nbsp;的&nbsp;CLASSES.ZIP&nbsp;解压后,放在另一个目录中,&nbsp;CLASSPATH&nbsp;只包含该目录。然后一边逐步删除该目录中的&nbsp;.CLASS&nbsp;文件,另一边运行测试程序,最后发现在一千多个&nbsp;CLASS&nbsp;文件中,只有一个是必不可少的,该文件是:&nbsp;<BR><BR>sun.io.CharToByteDoubleByte.class。&nbsp;<BR><BR>将该文件拷到服务器端和其它的类放在一起,并在程序的开头&nbsp;IMPORT&nbsp;它,在&nbsp;B&nbsp;情况下程序仍然无法正常运行。&nbsp;<BR><BR>4.在&nbsp;A&nbsp;情况下,如果在&nbsp;CLASSPTH&nbsp;中去掉&nbsp;sun.io.CharToByteDoubleByte.class&nbsp;,则程序运行时测得默认编码方式为“8859-1”,否则为&nbsp;“GBK”&nbsp;或&nbsp;“GB2312”&nbsp;。&nbsp;<BR><BR>如果&nbsp;JDK&nbsp;的版本为1.2以上的话,在&nbsp;B&nbsp;情况下遇到的问题得到了很好的解决,测试的步骤同上,有兴趣的读者可以尝试一下。&nbsp;<BR><BR>Java&nbsp;中文问题的根源分析及解决&nbsp;<BR><BR>在简体中文&nbsp;MS&nbsp;Windows&nbsp;98&nbsp;+&nbsp;JDK&nbsp;1.3&nbsp;下,可以用&nbsp;System.getProperties()&nbsp;得到&nbsp;Java&nbsp;运行环境的一些基本属性,类&nbsp;PoorChinese&nbsp;可以帮助我们得到这些属性。&nbsp;<BR><BR>类&nbsp;PoorChinese&nbsp;的源代码:&nbsp;<BR><BR>public&nbsp;class&nbsp;PoorChinese&nbsp;{&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.getProperties().list(System.out);&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;}&nbsp;<BR><BR>}&nbsp;<BR><BR>执行&nbsp;java&nbsp;PoorChinese&nbsp;后,我们会得到:&nbsp;<BR><BR>系统变量&nbsp;file.encoding&nbsp;的值为&nbsp;GBK&nbsp;,user.language&nbsp;的值为&nbsp;zh&nbsp;,&nbsp;user.region&nbsp;的值为&nbsp;CN&nbsp;,这些系统变量的值决定了系统默认的编码方式是&nbsp;GBK&nbsp;。&nbsp;<BR><BR>在上述系统中,下面的代码将&nbsp;GB2312&nbsp;文件转换成&nbsp;Big5&nbsp;文件,它们能够帮助我们理解&nbsp;Java&nbsp;中汉字编码的转化:&nbsp;<BR><BR>&nbsp;&nbsp;<BR><BR>import&nbsp;java.io.*;&nbsp;<BR><BR>import&nbsp;java.util.*;&nbsp;<BR><BR>&nbsp;&nbsp;<BR><BR>public&nbsp;class&nbsp;gb2big5&nbsp;{&nbsp;<BR><BR>&nbsp;&nbsp;<BR><BR>static&nbsp;int&nbsp;iCharNum=0;&nbsp;<BR><BR>&nbsp;&nbsp;<BR><BR>public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp;<BR><BR>System.out.println("Input&nbsp;GB2312&nbsp;file,&nbsp;output&nbsp;Big5&nbsp;file.");&nbsp;<BR><BR>if&nbsp;(args.length!=2)&nbsp;{&nbsp;<BR><BR>System.err.println("Usage:&nbsp;jview&nbsp;gb2big5&nbsp;gbfile&nbsp;big5file");&nbsp;<BR><BR>System.exit(1);&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;}&nbsp;<BR><BR>String&nbsp;inputString&nbsp;=&nbsp;readInput(args[0]);&nbsp;<BR><BR>writeOutput(inputString,args[1]);&nbsp;<BR><BR>System.out.println("Number&nbsp;of&nbsp;Characters&nbsp;in&nbsp;file:&nbsp;"+iCharNum+".");&nbsp;<BR><BR>}&nbsp;<BR><BR>&nbsp;&nbsp;<BR><BR>static&nbsp;void&nbsp;writeOutput(String&nbsp;str,&nbsp;String&nbsp;strOutFile)&nbsp;{&nbsp;<BR><BR>try&nbsp;{&nbsp;<BR><BR>FileOutputStream&nbsp;fos&nbsp;=&nbsp;new&nbsp;FileOutputStream(strOutFile);&nbsp;<BR><BR>Writer&nbsp;out&nbsp;=&nbsp;new&nbsp;OutputStreamWriter(fos,&nbsp;"Big5");&nbsp;<BR><BR>out.write(str);&nbsp;<BR><BR>out.close();&nbsp;<BR><BR>}&nbsp;<BR><BR>catch&nbsp;(IOException&nbsp;e)&nbsp;{&nbsp;<BR><BR>e.printStackTrace();&nbsp;<BR><BR>e.printStackTrace();&nbsp;<BR><BR>}&nbsp;<BR><BR>}&nbsp;<BR><BR>&nbsp;&nbsp;<BR><BR>static&nbsp;String&nbsp;readInput(String&nbsp;strInFile)&nbsp;{&nbsp;<BR><BR>StringBuffer&nbsp;buffer&nbsp;=&nbsp;new&nbsp;StringBuffer();&nbsp;<BR><BR>try&nbsp;{&nbsp;<BR><BR>FileInputStream&nbsp;fis&nbsp;=&nbsp;new&nbsp;FileInputStream(strInFile);&nbsp;<BR><BR>InputStreamReader&nbsp;isr&nbsp;=&nbsp;new&nbsp;InputStreamReader(fis,&nbsp;"GB2312");&nbsp;<BR><BR>Reader&nbsp;in&nbsp;=&nbsp;new&nbsp;BufferedReader(isr);&nbsp;<BR><BR>int&nbsp;ch;&nbsp;<BR><BR>while&nbsp;((ch&nbsp;=&nbsp;in.read())&nbsp;&gt;&nbsp;-1)&nbsp;{&nbsp;<BR><BR>iCharNum&nbsp;+=&nbsp;1;&nbsp;<BR><BR>buffer.append((char)ch);&nbsp;<BR><BR>}&nbsp;<BR><BR>in.close();&nbsp;<BR><BR>return&nbsp;buffer.toString();&nbsp;<BR><BR>}&nbsp;<BR><BR>catch&nbsp;(IOException&nbsp;e)&nbsp;{&nbsp;<BR><BR>e.printStackTrace();&nbsp;<BR><BR>return&nbsp;null;&nbsp;<BR><BR>}&nbsp;<BR><BR>}&nbsp;<BR><BR>}&nbsp;<BR><BR>&nbsp;&nbsp;<BR><BR>编码转化的过程如下:&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteToCharGB2312&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CharToByteBig5&nbsp;<BR><BR>GB2312------------------&gt;Unicode-------------&gt;Big5&nbsp;<BR><BR>执行&nbsp;java&nbsp;gb2big5&nbsp;gb.txt&nbsp;big5.txt&nbsp;,如果&nbsp;gb.txt&nbsp;的内容是“今天星期三”,则得到的文件&nbsp;big5.txt&nbsp;中的字符能够正确显示;而如果&nbsp;gb.txt&nbsp;的内容是“情人节快乐”,则得到的文件&nbsp;big5.txt&nbsp;中对应于“节”和“乐”的字符都是符号“?”(0x3F),可见&nbsp;sun.io.ByteToCharGB2312&nbsp;和&nbsp;sun.io.CharToByteBig5&nbsp;这两个基本类并没有编好。&nbsp;<BR><BR>正如上例一样,&nbsp;Java&nbsp;的基本类也可能存在问题。由于国际化的工作并不是在国内完成的,所以在这些基本类发布之前,没有经过严格的测试,所以对中文字符的支持并不像&nbsp;Java&nbsp;Soft&nbsp;所声称的那样完美。前不久,我的一位技术上的朋友发信给我说,他终于找到了&nbsp;Java&nbsp;Servlet&nbsp;中文问题的根源。两周以来,他一直为&nbsp;Java&nbsp;Servlet&nbsp;的中文问题所困扰,因为每面对一个含有中文字符的字符串都必须进行强制转换才能够得到正确的结果(这好象是大家公认的唯一的解决办法)。后来,他确实不想如此继续安分下去了,因为这样的事情确实不应该是高级程序员所要做的工作,他就找出&nbsp;Servlet&nbsp;解码的源代码进行分析,因为他怀疑问题就出在解码这部分。经过四个小时的奋斗,他终于找到了问题的根源所在。原来他的怀疑是正确的,&nbsp;Servlet&nbsp;的解码部分完全没有考虑双字节,直接把&nbsp;%XX&nbsp;当作一个字符。(原来&nbsp;Java&nbsp;Soft&nbsp;也会犯这幺低级的错误!)&nbsp;<BR><BR>如果你对这个问题有兴趣或者遇到了同样的烦恼的话,你可以按照他的步骤对&nbsp;Servlet.jar&nbsp;进行修改:&nbsp;<BR><BR>找到源代码&nbsp;HttpUtils&nbsp;中的&nbsp;static&nbsp;private&nbsp;String&nbsp;parseName&nbsp;,在返回前将&nbsp;sb(StringBuffer)&nbsp;复制成&nbsp;byte&nbsp;bs[]&nbsp;,然后&nbsp;return&nbsp;new&nbsp;String(bs,”GB2312”)。作上述修改后就需要自己解码了:&nbsp;<BR><BR>HashTable&nbsp;form=HttpUtils&nbsp;.parseQueryString(request.getQueryString())或者&nbsp;<BR><BR>form=HttpUtils.parsePostData(……)&nbsp;<BR><BR>千万别忘了编译后放到&nbsp;Servlet.jar&nbsp;里面。&nbsp;<BR><BR>五、&nbsp;关于&nbsp;Java&nbsp;中文问题的总结&nbsp;<BR><BR>Java&nbsp;编程语言成长于网络世界,这就要求&nbsp;Java&nbsp;对多国字符有很好的支持。&nbsp;Java&nbsp;编程语言适应了计算的网络化的需求,为它能够在网络世界迅速成长奠定了坚实的基础。&nbsp;Java&nbsp;的缔造者&nbsp;(Java&nbsp;Soft)&nbsp;已经考虑到&nbsp;Java&nbsp;编程语言对多国字符的支持,只是现在的解决方案有很多缺陷在里面,需要我们付诸一些补偿性的措施。而世界标准化组织也在努力把人类所有的文字统一在一种编码之中,其中一种方案是&nbsp;ISO10646&nbsp;,它用四个字节来表示一个字符。当然,在这种方案未被采用之前,还是希望&nbsp;Java&nbsp;Soft&nbsp;能够严格地测试它的产品,为用户带来更多的方便。&nbsp;<BR><BR>附一个用于从数据库和网络中取出中文乱码的处理函数,入参是有问题的字符串,出参是问题已经解决了的字符串。&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;parseChinese(String&nbsp;in)&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;=&nbsp;null;&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte&nbsp;temp&nbsp;[];&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(in&nbsp;==&nbsp;null)&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Warn:Chinese&nbsp;null&nbsp;founded!");&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;String("");&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp=in.getBytes("iso-8859-1");&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp=in.getBytes("iso-8859-1");&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;=&nbsp;new&nbsp;String(temp);&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Warn:Chinese&nbsp;null&nbsp;founded!");&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;String("");&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp=in.getBytes("iso-8859-1");&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;=&nbsp;new&nbsp;String(temp);&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch(UnsupportedEncodingException&nbsp;e)&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(e.toString());&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s;&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR><BR><BR>参考资料<BR><BR>BBS&nbsp;水木清华站的&nbsp;Java&nbsp;讨论区<BR><BR><BR>中国最大的电子公告板的&nbsp;Java&nbsp;讨论区,有众多高校的&nbsp;Java&nbsp;爱好者在此进行关于&nbsp;Java&nbsp;技术的讨论&nbsp;<BR>作者简介&nbsp;<BR><BR>段明辉,清华大学电子工程系学生&nbsp;<BR>现在正在清华大学微电子学研究所从事&nbsp;Java&nbsp;智能卡微处理器的研究和开发&nbsp;<BR>领导&nbsp;BBS&nbsp;水木清华站的&nbsp;Java&nbsp;讨论组,为众多&nbsp;Java&nbsp;技术应用者提供解决方案&nbsp;<BR></FONT></TD></TR>
  <TR>
    <TD height=5>
      <HR align=center color=#cccccc noShade SIZE=1>
    </TD></TR></TBODY></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -