|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
java也能做一些底层语言开发做的事情(难度很高,不是java顶尖高手是做不来的),js|servlet|办理|成绩|中文JSP/Servlet中的汉字编码成绩
(张建芳,转自IBMDeveloperWorks中国网站 2001年04月18日15:08)
网上就JSP/Servlet中DBCS字符编码成绩有很多优异的文章和会商,本文对它们作一些收拾,并分离IBMWebSphereApplicationServer3.5(WAS)的办理办法作一些申明,但愿它不是过剩的。
1.成绩的劈头
每一个国度(或地区)都划定了盘算机信息互换用的字符编码集,如美国的ASCII,中国的GB2312-80,日本的JIS等,作为该国度/地区内信息处置的基本,有着一致编码的主要感化。字符编码集按长度分为SBCS(单字节字符集),DBCS(双字节字符集)两年夜类。初期的软件(特别是操纵体系),为懂得决当地字符信息的盘算机处置,呈现了各类当地化版本(L10N),为了辨别,引进了LANG,Codepage等观点。可是因为各个当地字符集代码局限堆叠,互相间信息互换坚苦;软件各个当地化版本自力保护本钱较高。因而有需要将当地化事情中的个性抽掏出来,作分歧处置,将出格的当地化处置内容下降到起码。这也就是所谓的国际化(I18N)。各类言语信息被进一步标准为Locale信息。处置的底层字符集酿成了几近包括了一切字形的Unicode。
如今年夜部分具有国际化特性的软件中心字符处置都是以Unicode为基本的,在软件运转时依据事先的Locale/Lang/Codepage设置断定响应的当地字符编码设置,并依此处置当地字符。在处置过程当中必要完成Unicode和当地字符集的互相转换,甚或以Unicode为两头的两个分歧当地字符集的互相转换。这类体例在收集情况下被进一步延长,任何收集两头的字符信息也必要依据字符集的设置转换成可承受的内容。
Java言语外部是用Unicode暗示字符的,恪守UnicodeV2.0。Java程序不管是从/往文件体系以字符流读/写文件,仍是往URL毗连写HTML信息,或从URL毗连读取参数值,城市有字符编码的转换。如许做固然增添了编程的庞大度,简单引发搅浑,但倒是切合国际化的头脑的。
从实际下去说,这些依据字符集设置而举行的字符转换不该该发生太多成绩。而现实是因为使用程序的实践运转情况分歧,Unicode和各个当地字符集的增补、完美,和体系或使用程序完成的不标准,转码时呈现的成绩不时困扰着程序员和用户。
2.GB2312-80,GBK,GB18030-2000汉字字符集
实在办理JAVA程序中的汉字编码成绩的办法常常很复杂,但了解其面前的缘故原由,定位成绩,还必要懂得现有的汉字编码和编码转换。
GB2312-80是在国际盘算机汉字信息手艺开展初始阶段制订的,个中包括了年夜部分经常使用的1、二级汉字,和9区的标记。该字符集是几近一切的中文体系和国际化的软件都撑持的中笔墨符集,这也是最基础的中笔墨符集。其编码局限是高位0xa1-0xfe,低位也是0xa1-0xfe;汉字从0xb0a1入手下手,停止于0xf7fe;
GBK是GB2312-80的扩大,是向上兼容的。它包括了20902个汉字,其编码局限是0x8140-0xfefe,剔除高位0x80的字位。其一切字符都能够一对一映照到Unicode2.0,也就是说JAVA实践上供应了GBK字符集的撑持。这是现阶段Windows和别的一些中文操纵体系的缺省字符集,但并非一切的国际化软件都撑持该字符集,感到是他们其实不完整晓得GBK是怎样回事。值得注重的是它不是国度尺度,而只是标准。跟着GB18030-2000国标的公布,它将在不久的未来完成它的汗青任务。
GB18030-2000(GBK2K)在GBK的基本长进一步扩大了汉字,增添了躲、蒙等多数平易近族的字形。GBK2K从基本上办理了字位不敷,字形不敷的成绩。它有几个特性:
●它并没有断定一切的字形,只是划定了编码局限,留待今后扩大。
●编码是变长的,其二字节部分与GBK兼容;四字节部分是扩大的字形、字位,其编码局限是首字节0x81-0xfe、二字节0x30-0x39、三字节0x81-0xfe、四字节0x30-0x39。
●它的推行是分阶段的,起首请求完成的是可以完整映照到Unicode3.0尺度的一切字形。
●它是国度尺度,是强迫性的。
如今还没有任何一个操纵体系或软件完成了GBK2K的撑持,这是现阶段和未来汉化的事情内容。
3.JSP/Servlet汉字编码成绩及在WAS中的办理举措
3.1罕见的encoding成绩的征象
网上常呈现的JSP/Servletencoding成绩一样平常都体现在browser或使用程序端,如:
●扫瞄器中看到的Jsp/Servlet页面中的汉字怎样都成了’?’?
●扫瞄器中看到的Servlet页面中的汉字怎样都成了乱码?
●JAVA使用程序界面中的汉字怎样都成了方块?
●Jsp/Servlet页面没法显现GBK汉字。
●Jsp/Servlet不克不及吸收form提交的汉字。
●JSP/Servlet数据库读写没法取得准确的内容。
埋没在这些成绩前面的是各类毛病的字符转换和处置(除第3个外,是由于Javafont设置毛病引发的)。办理相似的字符encoding成绩,必要懂得Jsp/Servlet的运转历程,反省大概呈现成绩的各个点。
3.2JSP/Servletweb编程时的encoding成绩
运转于Java使用服务器的JSP/Servlet为Browser供应HTML内容,其历程以下图所示:
个中有字符编码转换的中央有:
a.JSP编译。Java使用服务器将依据JVM的file.encoding值读取JSP源文件,并转换为外部字符编码举行JSP编译,天生JAVA源文件,依据file.encoding值写回文件体系。假如以后体系言语撑持GBK,那末这时候候不会呈现encoding成绩。假如是英文的体系,如LANG是en_US的Linux,AIX或Solaris,则要将JVM的file.encoding值置成GBK。体系言语假如是GB2312,则依据必要,断定要不要设置file.encoding,将file.encoding设为GBK能够办理潜伏的GBK字符乱码成绩。
b.Java必要被编译为.class才干在JVM中实行,这个历程存在与a.一样的file.encoding成绩。从这里入手下手servlet和jsp的运转就相似了,只不外Servlet的编译不是主动举行的。
c.Servlet必要将HTML页面内容转换为browser可承受的encoding内容发送进来。依附于各JAVAAppServer的完成体例,有的将查询Browser的accept-charset和accept-language参数或以别的猜的体例断定encoding值,有的则不论。因而constant-encoding大概是最好的办理办法。关于中文网页,可在JSP或Servlet中设置contentType="text/html;charset=GB2312";假如页面中有GBK字符,则设置为contentType="text/html;charset=GBK",因为IE和Netscape对GBK的撑持水平纷歧样,作这类设置时必要测试一下。
由于16位JAVAchar在收集传送时高8位会被抛弃,也为了确保Servlet页面中的汉字(包含内嵌的和servlet运转过程当中失掉的)是希冀的内码,能够用PrintWriterout=res.getWriter()代替ServletOutputStreamout=res.getOutputStream(),PrinterWriter将依据contentType中指定的charset作转换(ContentType需在此之前指定!);也能够用OutputStreamWriter封装ServletOutputStream类并用write(String)输入汉字字符串。
关于JSP,JAVAApplicationServer应该可以确保在这个阶段将嵌进的汉字准确传送进来。
d.这是URL字符encoding成绩。假如经由过程get/post体例从browser前往的值中包括汉字信息,servlet将没法失掉准确的值。SUN的J2SDK中,HttpUtils.parseName在剖析参数时基本没有思索browser的言语设置,而是将失掉的值按byte体例剖析。这是网上会商得最多的encoding成绩。由于这是计划缺点,只能以bin体例从头剖析失掉的字符串;大概以hackHttpUtils类的体例办理。参考文章2、3均有先容,不外最好将个中的中文encodingGB2312、CP1381都改成GBK,不然碰到GBK汉字时,仍是会有成绩。
ServletAPI2.3供应一个新的函数HttpServeletRequest.setCharacterEncoding用于在挪用request.getParameter(“param_name”)前指定使用程序但愿的encoding,这将有助于完全办理这个成绩。
WebSphereApplicationServer对尺度的ServletAPI2.x作了扩大,供应较好的多言语撑持。上述c,d情形,WAS都要查询Browser的言语设置,在缺省情况下zh、zh-cn等均被映照为JAVAencodingCP1381(注重:CP1381只是同等于GB2312的一个codepage,没有GBK撑持)。如许做我想是由于没法确认Browser运转的操纵体系是撑持GB2312,仍是GBK,以是取其小。可是实践的使用体系仍是请求页面中呈现GBK汉字,最出名的是朱总理名字中的“?”(rong2,0xe946,u9555),以是偶然仍是必要将Encoding/Charset指定为GBK。固然WAS中变动缺省的encoding没有下面说的那末贫苦,针对a,b,参考文章5),在ApplicationServer的命令行参数中指定-Dfile.encoding=GBK便可;针对d,在ApplicationServer的命令行参数中指定-Ddefault.client.encoding=GBK。假如指定了-Ddefault.client.encoding=GBK,那末c情形下能够不再指定charset。
3.3数据库读写时的encoding成绩
JSP/Servlet编程中常常呈现encoding成绩的另外一个中央是读写数据库中的数据。
盛行的干系数据库体系都撑持数据库encoding,也就是说在创立数据库时能够指定它本人的字符集设置,数据库的数据以指定的编码情势存储。当使用程序会见数据时,在出口和出口处城市有encoding转换。关于中文数据,应该包管数据的完全性。GB2312,GBK,UTF-8等都是可选的数据库encoding;假如选择ISO8859-1(8-bitSBCS),那末使用程序在写数据之前须将16Bit的一个汉字或Unicode拆分红两个8-bit的字符,读数据以后则需将两个字节兼并起来,同时另有辨别个中的SBCS字符。没有充实使用数据库encoding的感化,反而增添了编程的庞大度,ISO8859-1不是保举的数据库encoding。JSP/Servlet编程时,能够先用数据库办理体系供应的功效反省个中的中文数据是不是准确。
然后应该注重的是读出来的数据的encoding,JAVA程序中一样平常失掉的是Unicode。写数据时则相反。
3.4定位成绩经常用的技能
定位中文encoding成绩一般接纳最笨的也是最无效的举措――在你以为有怀疑的程序处置后打印字符串的内码。经由过程打印字符串的内码,你能够发明甚么时分中笔墨符被转换成Unicode,甚么时分Unicode被转回中文内码,甚么时分一其中笔墨成了两个Unicode字符,甚么时分中笔墨符串被转成了一串问号,甚么时分中笔墨符串的高位被截失落了……
取用符合的样本字符串也有助于辨别成绩的范例。如:”aa啊aa?aa”等中英相间、GB、GBK特性字符均有的字符串。一样平常来讲,英笔墨符不管怎样转换或处置,都不会掉真(假如碰到了,能够实验着增添一连的英笔墨母长度)。
4.停止语
实在JSP/Servlet的中文encoding并没有想像的那末庞大,固然定位息争决成绩没有定例,各类运转情况也各不尽然,但前面的道理是一样的。懂得字符集的常识是办理字符成绩的基本。不外,跟着中笔墨符集的变更,不单单是java编程,中文信息处置中的成绩仍是会存在一段工夫的。
5.参考文章
1)CharacterProblemReview
2)Java编程手艺中汉字成绩的剖析及办理
3)NLSCharactersinWebSphere:SBCS/DBCSdisplayonsamepage
4)GB18030
5)Settinglanguageencodinginwebapplications:WebsphereapplicationsServer
作者简介
张建芳,软件工程师,卒业于北京理工年夜学盘算机使用学院,有多年中文当地化履历。您可经由过程jfzhang@usa.net与他接洽。
转自IBM
市场分额,java比asp高一点,因为C#是仿照java开发的,所以哦C#能做的java都能做到,但是java能做的,C#不一定都能做到。毕竟是抄袭吗。 |
|