海妖 发表于 2015-1-18 11:47:32

JAVA网页编程之Java 编程手艺中汉字成绩的剖析及办理,...

java主要分三块,j2se:java的基础核心语言。j2me:java的微型模块,专门针对内存小,没有持续电源等小型设备。j2ee:java的企业模块,专门针对企业数据库服务器的连接维护。编程|汉字|办理|成绩在基于Java言语的编程中,我们常常碰着汉字的处置及显现的成绩。一年夜堆看不懂的
乱码一定不是我们乐意看到的显现效果,如何才干够让那些汉字准确显现呢?Java言语
默许的编码体例是UNICODE,而我们中国人一般利用的文件和数据库都是基于GB2312
大概BIG5等体例编码的,如何才干够得当地选择汉字编码体例并准确地处置汉字的编
码呢?本文将从汉字编码的知识动手,分离Java编程实例,剖析以上两个成绩并提出
办理它们的计划。

如今Java编程言语已普遍使用于互联网天下,早在Sun公司开辟Java言语的时分
,就已思索到对非英笔墨符的撑持了。Sun公司发布的Java运转情况(JRE)自己就
分英文版和国际版,但只要国际版才撑持非英笔墨符。不外在Java编程言语的使用中
,对中笔墨符的撑持并不是好像JavaSoft的尺度标准中所传播鼓吹的那样完善,由于中笔墨
符集不但一个,并且分歧的操纵体系对中笔墨符的撑持也不尽不异,以是会有很多和汉
字编码处置有关的成绩在我们举行使用开辟中困扰着我们。有良多关于这些成绩的解答
,但都对照噜苏,其实不可以满意人人急切办理成绩的希望,关于Java中文成绩的体系
研讨其实不多,本文从汉字编码知识动身,剖析Java中文成绩,但愿对人人办理这个问
题有所匡助。
汉字编码的知识
我们晓得,英笔墨符通常为以一个字节来暗示的,最经常使用的编码办法是ASCII。但一个
字节最多只能辨别256个字符,而汉字不计其数,以是如今都以双字节来暗示汉字,为了
可以与英笔墨符分隔,每一个字节的最高位必定为1,如许双字节最多能够暗示64K格字符
。我们常常碰着的编码体例有GB2312、BIG5、UNICODE等。关于详细编码体例的具体资
料,有乐趣的读者能够查阅相干材料。我浅薄谈一下和我们干系亲切的GB2312和UNI
CODE。GB2312码,中华国民共和国国度尺度汉字信息互换用编码,是一个由中华国民共
和国国度尺度总局公布的关于简化汉字的编码,通行于中国年夜海洋区及新加坡,简称国
标码。两个字节中,第一个字节(高字节)的值为区号值加32(20H),第二个字节(低
字节)的值为位号值加32(20H),用这两个值来暗示一个汉字的编码。UNICODE码是微
软提出的办理多国字符成绩的多字节等长编码,它对英笔墨符接纳后面加“0”字节的策
略完成等长兼容。如“A”的ASCII码为0x41,UNICODE就为0x00,0x41。使用特别
的工具各类编码之间能够相互转换。
Java中文成绩的开端熟悉
我们基于Java编程言语举行使用开辟时,不成制止地要处置中文。Java编程言语默许
的编码体例是UNICODE,而我们一般利用的数据库及文件都是基于GB2312编码的,我
们常常碰着如许的情形:扫瞄基于JSP手艺的网站看到的是乱码,文件翻开后看到的也
是乱码,被Java修正过的数据库的内容在其余场所使用时没法持续准确地供应信息。
StringsEnglish=“apple”;
StringsChinese=“苹果”;
Strings=“苹果apple”;
sEnglish的长度是5,sChinese的长度是4,而s默许的长度是14。关于sEnglish来讲
,Java中的各个类都撑持得十分好,一定可以准确显现。但关于sChinese和s来讲
,固然JavaSoft声明Java的基础类已思索到对多国字符的撑持(默许UNICODE
编码),可是假如操纵体系的默许编码不是UNICODE,而是国标码等。从Java源代码
到失掉准确的了局,要经由“Java源代码->Java字节码->;假造机->操纵体系->显
示设备”的历程。在上述过程当中的每步骤,我们都必需准确地处置汉字的编码,才干
够使终极的显现了局准确。

“Java源代码->Java字节码”,尺度的Java编译器javac利用的字符集是体系默
认的字符集,好比在中文Windows操纵体系上就是GBK,而在Linux操纵体系上就是
ISO-8859-1,以是人人会发明在Linux操纵体系上编译的类中源文件中的中笔墨符都出
了成绩,办理的举措就是在编译的时分增加encoding参数,如许才干够与平台有关。
用法是
javacCencodingGBK。
“Java字节码->假造机->操纵体系”,Java运转情况(JRE)分英文版和国际版,
但只要国际版才撑持非英笔墨符。Java开辟工具包(JDK)一定撑持多国字符,但并
非一切的盘算机用户都安装了JDK。良多操纵体系及使用软件为了可以更好的撑持Ja
va,都内嵌了JRE的国际版本,为本人撑持多国字符供应了便利。
“操纵体系->显现设备”,关于汉字来讲,操纵体系必需撑持并可以显现它。英文操纵
体系假如不搭配特别的使用软件的话,是一定不克不及够显现中文的。
另有一个成绩,就是在Java编程过程当中,对中笔墨符举行准确的编码转换。比方,向
网页输入中笔墨符串的时分,不管你是用
out.println(string);//string是含中文的字符串
仍是用
,都必需作UNICODE到GBK的转换,大概手动,大概主动。在JSP1.0中
,能够界说输入字符集,从而完成内码的主动转换。用法是

可是在一些JSP版本中并没有供应对输入字符集的撑持,(比方JSP0.92),这就需
要手动编码输入了,办法十分多。最经常使用的办法是
Strings1=request.getParameter(“keyword”);
Strings2=newString(s1.getBytes(“ISO-8859-1”),”GBK”);
getBytes办法用于将中笔墨符以“ISO-8859-1”编码体例转化成字节数组,而“GBK”
是方针编码体例。我们从以ISO-8859-1体例编码的数据库中读出中笔墨符串s1,经由
上述转换历程,在撑持GBK字符集的操纵体系和使用软件中就可以够准确显现中笔墨符串
s2。
Java中文成绩的表层剖析及处置
背景
开辟情况
JDK1.15
Vcafe2.0
JPadPro
服务器端
NTIIS
SybaseSystem
Jconnect(JDBC)
客户端
IE5.0
Pwin98
.CLASS文件寄存在服务器端,由客户真个扫瞄器运转APPLET,APPLET只起调进FR
AME类等主程序的感化。界面包含Textfield,TextArea,List,Choice等。
I.取中文
用JDBC实行SELECT语句从服务器端读取数据(中文)后,将数据用APPEND办法加
到TextArea(TA),不克不及准确显现。但加到List中时,年夜部分汉字却可准确显现。将数据按“ISO-8859-1”编码体例转化为字节数组,再按体系缺省编码体例(Defaul
tCharacterEncoding)转化为STRING,便可在TA和List中准确显现。
程序段以下:
dbstr2=results.getString(1);
//AfterreadingtheresultfromDBserver,convertingittostring.
dbbyte1=dbstr2.getBytes(“iso-8859-1”);
dbstr1=newString(dbbyte1);
在转换字符串时不接纳体系默许编码体例,而间接接纳“GBK”大概“GB2312”,在
A和B两种情形下,从数据库取数据都没有成绩。
II.写中文到数据库
处置体例与“取中文”相逆,先将SQL语句按体系缺省编码体例转化为字节数组,再按
“ISO-8859-1”编码体例转化为STRING,最初送往实行,则中文信息可准确写进数据
库。
程序段以下:
sqlstmt=tf_input.getText();
//BeforesendingstatementtoDBserver,convertingittosqlstatement.
dbbyte1=sqlstmt.getBytes();
sqlstmt=newString(dbbyte1,”iso-8859-1”);
_stmt=_con.createStatement();
_stmt.executeUpdate(sqlstmt);
……
成绩:假如客户机上存在CLASSPATH指向JDK的CLASSES.ZIP时(称为A情形),
上述程序代码可准确实行。可是假如客户机只要扫瞄器,而没有JDK和CLASSPATH时
(称为B情形),则汉字没法准确转换。
我们的剖析:
1.经由测试,在A情形下,程序运转时体系的缺省编码体例为GBK大概GB2312。在
B情形下,程序启动时扫瞄器的JAVA把持台中呈现以下毛病信息:
Cantfindresourceforsun.awt.windows.awtLocalization_zh_CN
然后体系的缺省编码体例为“8859-1”。
2.假如在转换字符串时不接纳体系缺省编码体例,而是间接接纳“GBK”或“GB2312”
,则在A情形下程序仍旧可一般运转,在B情形下,体系呈现毛病:
UnsupportedEncodingException。
3.在客户机上,把JDK的CLASSES.ZIP解压后,放在另外一个目次中,CLASSPATH只包
含该目次。然后一边慢慢删除该目次中的.CLASS文件,另外一边运转测试程序,最初发
如今一千多个CLASS文件中,只要一个是必不成少的,该文件是:
sun.io.CharToByteDoubleByte.class。
将该文件拷到服务器端和别的的类放在一同,并在程序的开首IMPORT它,在B情形下
程序仍旧没法一般运转。
4.在A情形下,假如在CLASSPTH中往失落sun.io.CharToByteDoubleByte.class,则
程序运转时测得默许编码体例为“8859-1”,不然为“GBK”或“GB2312”。
假如JDK的版本为1.2以上的话,在B情形下碰到的成绩失掉了很好的办理,测试的步
骤同上,有乐趣的读者能够实验一下。
Java中文成绩的本源剖析及办理
在简体中文MSWindows98+JDK1.3下,能够用System.getProperties()失掉Ja
va运转情况的一些基础属性,类PoorChinese能够匡助我们失掉这些属性。
类PoorChinese的源代码:
publicclassPoorChinese{
publicstaticvoidmain(String[]args){
System.getProperties().list(System.out);
}
}
实行javaPoorChinese后,我们会失掉:
体系变量file.encoding的值为GBK,user.language的值为zh,user.region的
值为CN,这些体系变量的值决意了体系默许的编码体例是GBK。
在上述体系中,上面的代码将GB2312文件转换成Big5文件,它们可以匡助我们了解
Java中汉字编码的转化:
importjava.io.*;
importjava.util.*;
publicclassgb2big5{
staticintiCharNum=0;
publicstaticvoidmain(String[]args){
System.out.println("InputGB2312file,outputBig5file.");
if(args.length!=2){
System.err.println("Usage:jviewgb2big5gbfilebig5file");
System.exit(1);
}
StringinputString=readInput(args);
writeOutput(inputString,args);
System.out.println("NumberofCharactersinfile:"+iCharNum+".");
}
staticvoidwriteOutput(Stringstr,StringstrOutFile){
try{
FileOutputStreamfos=newFileOutputStream(strOutFile);
Writerout=newOutputStreamWriter(fos,"Big5");
out.write(str);
out.close();
}
catch(IOExceptione){
e.printStackTrace();
e.printStackTrace();
}
}
staticStringreadInput(StringstrInFile){
StringBufferbuffer=newStringBuffer();
try{
FileInputStreamfis=newFileInputStream(strInFile);
InputStreamReaderisr=newInputStreamReader(fis,"GB2312");
Readerin=newBufferedReader(isr);
intch;
while((ch=in.read())>-1){
iCharNum+=1;
buffer.append((char)ch);
}
in.close();
returnbuffer.toString();
}
catch(IOExceptione){
e.printStackTrace();
returnnull;
}
}
}
编码转化的历程以下:
ByteToCharGB2312CharToByteBig5
GB2312------------------>Unicode------------->Big5
实行javagb2big5gb.txtbig5.txt,假如gb.txt的内容是“明天礼拜三”,则得
到的文件big5.txt中的字符可以准确显现;而假如gb.txt的内容是“恋人节康乐”
,则失掉的文件big5.txt中对应于“节”和“乐”的字符都是标记“?”(0x3F),
可见sun.io.ByteToCharGB2312和sun.io.CharToByteBig5这两个基础类并没有编好

正如上例一样,Java的基础类也大概存在成绩。因为国际化的事情并非在国际完成
的,以是在这些基础类公布之前,没有经由严厉的测试,以是对中笔墨符的撑持其实不像
JavaSoft所宣称的那样完善。前不久,我的一名手艺上的伴侣发信给我说,他终究找
到了JavaServlet中文成绩的本源。两周以来,他一向为JavaServlet的中文成绩
所困扰,由于每面临一个含有中笔墨符的字符串都必需举行强迫转换才干够失掉准确的
了局(这好象是人人公认的独一的办理举措)。厥后,他的确不想云云持续循分下往了
,由于如许的事变的确不该该是初级程序员所要做的事情,他就找出Servlet解码的源
代码举行剖析,由于他嫌疑成绩就出在解码这部分。经由四个小时的搏斗,他终究找到
了成绩的本源地点。本来他的嫌疑是准确的,Servlet的解码部分完整没有思索双字节
,间接把%XX看成一个字符。(本来JavaSoft也会犯这幺初级的毛病!)
假如你对这个成绩有乐趣大概碰到了一样的懊恼的话,你能够依照他的步骤对Servlet
.jar举行修正:
找到源代码HttpUtils中的staticprivateStringparseName,在前往前将sb(S
tringBuffer)复制成bytebs[],然后returnnewString(bs,”GB2312”)。作上
述修正后就必要本人解码了:
HashTableform=HttpUtils.parseQueryString(request.getQueryString())大概
form=HttpUtils.parsePostData(……)
万万别忘了编译后放到Servlet.jar内里。
5、关于Java中文成绩的总结
Java编程言语发展于收集天下,这就请求Java对多国字符有很好的撑持。Java编程
言语顺应了盘算的收集化的需求,为它可以在收集天下敏捷发展奠基了坚固的基本。J
ava的创作发明者(JavaSoft)已思索到Java编程言语对多国字符的撑持,只是如今
的办理计划有良多缺点在内里,必要我们付诸一些抵偿性的措施。而天下尺度化构造也
在勉力把人类一切的笔墨一致在一种编码当中,个中一种计划是ISO10646,它用四个
字节来暗示一个字符。固然,在这类计划未被接纳之前,仍是但愿JavaSoft可以严厉
地测试它的产物,为用户带来更多的便利。
附一个用于从数据库和收集中掏出中文乱码的处置函数,进参是有成绩的字符串,出参
是成绩已办理了的字符串。
StringparseChinese(Stringin)
{
Strings=null;
bytetemp[];
if(in==null)
{
System.out.println("Warn:Chinesenullfounded!");
returnnewString("");
}
try
{
temp=in.getBytes("iso-8859-1");
temp=in.getBytes("iso-8859-1");
s=newString(temp);
}
{
System.out.println("Warn:Chinesenullfounded!");
returnnewString("");
}
try
{
temp=in.getBytes("iso-8859-1");
s=newString(temp);
}
catch(UnsupportedEncodingExceptione)
{
System.out.println(e.toString());
}
returns;
}


再举这样一个例子:如果你想对一个数字取绝对值,你会怎么做呢?java的做法是intc=Math.abs(-166);而ruby的做法是:c=-166.abs。呵呵,这就看出了java与ruby的区别。

飘飘悠悠 发表于 2015-1-21 14:53:21

是一种突破用户端机器环境和CPU

仓酷云 发表于 2015-1-30 20:09:19

自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。

愤怒的大鸟 发表于 2015-2-5 15:57:06

不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。

灵魂腐蚀 发表于 2015-2-8 08:46:54

其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。

变相怪杰 发表于 2015-2-19 13:45:25

你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。

柔情似水 发表于 2015-3-11 07:22:53

是一种突破用户端机器环境和CPU

深爱那片海 发表于 2015-3-17 23:09:13

是一种为 Internet发展的计算机语言

小妖女 发表于 2015-3-21 17:13:01

一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从

蒙在股里 发表于 2015-4-6 08:37:49

应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展

海妖 发表于 2015-4-7 01:08:02

在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。

再见西城 发表于 2015-4-7 22:32:47

其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。

再现理想 发表于 2015-4-10 23:25:12

接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。

爱飞 发表于 2015-4-12 19:50:47

Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。

因胸联盟 发表于 2015-4-14 22:50:49

如果要向java web方向发展也要吧看看《Java web从入门到精通》学完再到《Struts2.0入门到精通》这样你差不多就把代码给学完了。有兴趣可以看一些设计模块和框架的包等等。

兰色精灵 发表于 2015-4-16 10:11:49

任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言

活着的死人 发表于 2015-4-21 20:12:00

是一种简化的C++语言 是一种安全的语言,具有阻绝计算机病毒传输的功能

简单生活 发表于 2015-4-23 03:56:34

Java是一个纯的面向对象的程序设计语言,它继承了 C++语言面向对象技术的核心。Java舍弃了C ++语言中容易引起错误的指针(以引用取代)、运算符重载(operator overloading)

只想知道 发表于 2015-5-3 06:53:50

一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。
页: [1]
查看完整版本: JAVA网页编程之Java 编程手艺中汉字成绩的剖析及办理,...