Java编程的中文问题的几条阐明原则
副标题#e#
尽量关于Java中文问题的接头已经相当多了,但由于Java的相关技能尺度繁多,面向Java的Web处事器、应用处事器以及JDBC数据库驱动等都没有官方的尺度,所以Java应用在处理惩罚中文时所存在的问题不只没有消失并且跟着所选用的处事器、驱动措施以及运行情况等因素的差异而变革。那么我们如何从浩瀚现象中找出问题地址,并举办阐明息争决呢?与大部门的接头差异,本文将主要从如何预测、发明和检盘查题的角度给出发起,辅佐开拓人员找出大概引起问题的各类源头,从而更好地办理Java的中文问题。
引言
尽量对付Java中文处理惩罚问题的接头已不乏其数,但由于Java技能涉及内容广(J2EE包括了十几种相关技能),技能供给商繁多,面向Java的Web处事器、应用处事器以及JDBC数据库驱动等都没有官方的尺度,所以Java应用在处理惩罚中文进程中出了存在固有的问题外也存在跟着选用的处事器,驱动措施的差异而带来的Java中文问题的多变性,增加了问题的巨大度。那么,我们如安在这么纷繁的现象中找到问题的症结呢?
Java中文问题的一般办理步伐
事实上,Java的中文问题都是由于Java应用所回收的缺省编码名目与方针可能应用所要读入字符的编码名目差异而造成的(详细拜见文献1)。对付如何办理Java的中文问题,凡是有四种要领:
1)选择JDK的中文当地化版本。尽量Java2 JDK的中文当地化版本(http://java.sun.com/products/jdk/1.2/chinesejdk.html)并不是一个官方的版本,Sun公司也没有理睬会对应当地化版本举办进级,但其仍不失为一个Java中文问题的办理方案。
2)选择符合的编译参数。对付Java的国际版原来讲,我们也可以在编译Java应用的时候通过指定确定的编码机制来实现其编译功效对中文的支持。譬喻,对付需要支持繁体中文和简体中文应用可以通过javac -encoding big5 sourcefile.java 和javac -encoding gb2312 sourcefile.java来编译源措施。
3)通过编程的方法实现字符编码的转换代码。通过编程的方法来办理Java的中文问题,已经成为了一种较为普遍的做法。下面就是一种最常见的字符编码转换函数,其将字符的编码名目转换为中文Windows系统的GBK编码形式。
public static String toChinese(String strvalue)
{
try{
if(strvalue==null)
return null;
else
{
strvalue=new String(strvalue.getBytes("ISO8859_1"), "GBK");
return strvalue;
}
}catch(Exception e){
return null;
}
}
4)界说字符输出集。对付JSP应用,我们可以通过或来界说JSP页面的字符输出集。虽然,我们也可以通过HTML的标志来界说字符的输出集。
存在的问题
按照要领实现的方法,我们可以将以上四种要领分为两类,一类是通过操作某些尺度可能法则来实现的要领,上面的1)、2)、4)都属于此类;一类是通过针对性的编程来实现的要领,上面所提的要领3)就属于此类。
由于要领1),2),4)是具有类型性的一类要领,所以要领较量简朴,办理方案也不具备较大的针对性,较为通用,譬喻我们可以回收要领2)的编译方法通过编译Java源文件来实现内码的预置,而无需思量源码到底有哪些部门呈现了Java的中文处理惩罚问题,诸如输出乱码等等。
可是,正由于这些要领不具备针对性,办理问题的要领过于统一,所以在某些环境下,它们并不能彻底地办理Java的中文问题。举一个非经常见的例子。在凡是环境下,用户的Java应用往往需要与其它Java应用接口举办交互,譬喻通过某种版本的JDBC会见数据库。由于JDBC的驱动所支持的编码跟着提供商以致版本的差异而差异,所以假如在数据库的输入输出进程中呈现中文不能正确处理惩罚问题时,我们需要在数据的输入和输出进程做两次正好相反的编码转换,这对付要领1),2),4)来说,往往是无法办理的。虽然,对付要领2,我们也可以通过回收一些能力使来满意上面的环境,一个最有效的步伐就是只管将Java应用的各个部门组件化。譬喻我们可以通过将数据库的读入和输出代码解析在差异的源文件上来实现别离编译,从而满意差异的字符编码要求。可是凡是的措施设计都不太大概满意这种要求,因为这种措施的分别功效很大概是不公道的。譬喻,我们将数据库的读出和写入要领封装到一个类中是较量符合的一种设计,但假如将该类的这两个要领别离实此刻两个文件里则变得很是不公道。因此对付1),2),4)要领来说,固然实现较量简朴,但却具有一些无法降服的缺点。这也是那些实现起来相对巨大的编程要领得以风行的原因。
#p#分页标题#e#
相对付要领1),2),4)来说,要领3)具有更好的针对性和机动性。措施可以按照差异的环境做出机动的处理惩罚,在任何需要的处所举办字符的编码转换,可是该要领的特点也对软件的开拓人员提出了更高要求–必需可以或许精确的捕获到有大概产生中文处理惩罚问题的处所,并做出正确的判定和处理惩罚。
#p#副标题#e#
阐明的原则
总的说来,所有办理Java中文处理惩罚的要领都不是很巨大。相反的是,由于Java技能出格是J2EE技能涉及的内容繁多,各类Web处事器、应用处事器以及JDBC数据库驱动等东倒西歪,所以如何正确而实时的发明应用的中文处理惩罚问题则变得相对巨大的多。那么我们如何来发明这些问题呢?
凡是,Java处理惩罚中文时所发生的问题都是由于用户的Java应用所回收的缺省编码名目与方针可能应用所要读入字符的编码名目差异而造成的,而引起这些差异的一个主要原因就是用户的Java应用与其它应用举办了编码名目不匹配的数据互换(包罗直接或间接的数据输入、输出)。所以,为了实时发明问题,我们可以由这一点入手,按照以下的原则对应用举办阐明:
1.留意字符变量环境。由于变量的字符编码形式较为隐蔽,多次变量间数值的改变和运算大概会引起字符集的改变;在变量与页面所提交数据的各类操纵中,较容易产生差异编码名目字符举办运算的环境。
2.留意任何形式的字符读入与输出。之所以要提到任何形式,是因为Java应用大大都都是作为网络应用开拓的,所以与其它语言的应用对比,Java应用需要面临网络世界各类百般的字符数据互换形式。譬喻各类表单的数据提交,URL形式的数据读入,颠末加密运算的字符数据互换,网页控件选择功效的输入,控件内容的的显示(如List控件)等等。
3.小心利用第三方的组件和应用。由于第三方组件和应用的实现长短透明的,所以一般环境下,我们很难判定这些组件或驱动的缺省编码名目是什么,也无法对其举办节制。因此,在利用它们所提供的接口函数举办数据互换的时候要出格留意,假如确实呈现中文无法正确处理惩罚环境,应首先查抄我们本身的代码并调解相关代码以适应这些接口,因为这些组件可能应用根基上不会提供调解编码机制的接口。须要时,我们大概需要回收其它可替换的组件可能应用。
4.留意被请求工具所含有的数据输入与输出。这长短常隐蔽的一类环境,当我们的应用以工具的方法(譬喻序列化的工具)举办交互时,假如这个工具内部含有字符数据的处理惩罚进程,可能含有某些数据的输入、输出,甚至是抛出一段用中文注解的异常,都大概呈现中文无法正确显示等问题。由于这些行为往往被封装在工具中,所以我们在编写措施时,很容易忽略这种大概环境。而且这种环境带有必然的不行预见性,譬喻我们大概不清楚这个工具会在什么时候抛出什么样的异常,所以这时我们就需要做必然的测试事情。
5.留意数据库的数据会见进程。Java通过JDBC与数据库成立毗连。对付JDBC驱动措施来说,由于今朝大部门的JDBC驱动措施并不是针对中文系统而设计的(中文数据多半回收ISO-8859-1编码方法),所以一般环境下在数据读写进程中往往都需要字符编码的转化。可是我们仍发起用户在利用这些JDBC驱动时,仔细阅读它的说明。假如确实无法弄清JDBC字符数据的编码到底是什么,我们的发起是做一些须要的测试。譬喻下面是一组在简体中文Win2000平台下,回收Weblogic 6.0所提供的JDBC驱动从MS SQL Server2000中正确读入中文字符的代码(例子中举办了字符运算):
...
Class.forName("weblogic.jdbc.mssqlserver4.Driver").newInstance();
conn = myDriver.connect("jdbc:weblogic:mssqlserver4", props);
conn.setCatalog("labmanager");
Statement st = conn.createStatement();
//execute a query
String testStr;
String testTempStr = new String() ;
testStr=new String(testTempStr.getBytes("ISO-8859-1"));//编码转化
DatabaseMetaData DBMetaData =conn.getMetaData();
ResultSet rs=DBMetaData.getTables(null,null,null,new String[]{"TABLE"});
while (rs.next()){
for(int j=1; j<=rs.getMetaData().getColumnCount(); j++){
testStr=testStr+String(rs.getObject(j).toString().getBytes("ISO-8859-1"));
}
}
#p#分页标题#e#
然而,需要留意的是,差异的JDBC驱动对沟通的数据库的支持并差异,而同一类JDBC驱动对差异的数据库的支持也不沟通,也就是说我们的字符转化代码在JDBC驱动改变甚至是版本变革环境下都有大概无法正确事情。譬喻对付上面的例子,在同样的情况下改用i-net 的Una 2000 Driver Version 2.03 for MS SQL Server时,是无法正确处理惩罚中文的。原因很简朴,这个JDBC驱动自己支持的就是GBK的编码机制,所以基础就不需要做任何的编码转化。
6.须要的测试。由于Java中文问题的发生跟着Web处事器,欣赏器,运行情况和开拓东西的差异都大概产生变革,所觉得了更好的制止问题的产生,我们必需作一些针对性的测试。别的,在我们确实无法通过阐明来确定Java的中文处理惩罚问题是否大概产生的环境下可能无法知道问题的产生是由于哪个环节(是Web处事器,欣赏器照旧JDBC数据驱动等等)引起的时候,测试事情则变得很是重要。而且我们大概需要较为全面的测试,譬喻对Web处事器,欣赏器和JDBC数据驱动等都要做测试,这样有利于我们找出那些埋没在多个环节协调进程中所发生的问题。
结论
事实上,Java中文处理惩罚之所以存在问题,其基础原因是由于被操纵的中文字符(变量)的编码名目与方针的编码名目差异造成的,所有这些问题其实都是产生在字符的读入、输出进程中的,只要我们掌握住这一环节,就可以更好的发明、阐明、处理惩罚和防范Java的中文问题了。