首  页 | 资讯中心 | 网络学院 | 天新汽车 | 天新手机 | 天新游戏 | 软件开发 | 考试认证
品 牌 机 | 笔 记 本 | 服 务 器 | 天新数码 - DC - DV - MP3 - MP4 - GPS - TV | 数字家庭
硬件 DIY - 主板 - CPU - 内 存 - 硬 盘 - 显示器 - 显卡 - 光驱 - 机箱 - 键鼠 - 网络设备
办公设备 | 打 印 机 | 扫 描 仪 | 投 影 仪 | 一 体 机 | 传 真 机 | 路 由 器 | 交 换 机
软件下载 | 驱动下载 | 游戏下载 | 源码下载 | 教程下载 | 站长在线 | 产品中心 | 报价中心
开发首页 | 开发语言 | .Net开发 | Java开发 | Web开发 | 移动开发 | 游戏开发 | 数据库开发 | 企业开发 | 操作系统 | 软件工程
VB VC Delphi PB BCB C++ - ASP.net C# VB.net - J2EE J2SE J2ME EJB - ASP PHP JSP CGI - MSSQL Oracle DB2 MySQL - CodingLife
  Java开发首页 | Java基础 | Java高级编程 | J2EE | J2SE | EJB | J2ME | Servlet/JSP | Applet/Swing | Struts/Hibernate
  您现在的位置:天新网 > 软件开发 > Java开发 > Java基础 > Java语言基础
漫谈Java中的中文问题
http://dev.21tx.com 2002年12月31日 Yesky

每日文章精萃
.Net:利用ASP.NET DataGrid显示主次关系 Java:联通彩e接口开发(1)
ASP:web应用程序中的数据库连接(1) PHP:针对PHP木马攻击的防御之道
JSP:在JSP中用bean封装常用的功能 CGI:perl实例分析教程之十三
VB:用Visual Basic设计三维图形按钮 VC:用Viusal C++实现字符串分割函数

摘要:关于Java应用在处理中文时所存在问题的讨论已经相当多了,与大部分的讨论不同,本文将从汉字字符的输入和输出的角度来讨论Java语言处理中文时所存在的问题。

  尽管关于Java在处理中文字符时所存在的问题的讨论已不乏其数,但由于Java技术涉及内容广(J2EE包含了十几种相关技术),技术供应商繁多,面向Java的Web服务器应用服务器以及JDBC数据库驱动等都没有官方的标准,所以Java应用在处理中文时出了存在固有的问题外也会随着选用的服务器、驱动程序的不同产生一些与平台相关的问题。也就是说,在处理中文问题时,Java代码的可移植性打了折扣。

  总的看来,Java的中文处理问题较为集中地出现在JSP技术应用和Java的数据库访问过程中。这是因为无论是JSP应用还是基于JDBC的数据库访问都涉及到了Java程序与另外一种应用系统的交互,这种交互不可避免的要求系统之间进行数据的交互和参数的传递,而Java处理中文出现问题的地方往往就是这些数据读入和输出的地方。

  JSP程序所应该注意的中文问题

  以Tomcat 3.2.1的JSP应用为例,一般遇到中文问题可以使用如下的编码强制转换函数进行内码的转换。

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;
}
}

  注意,在使用该函数前,我们需要分析中文无法正确输出的原因到底是什么,而不能将所有的中文处理的问题都用这个方法来解决。例如,如果是由于忘记将JSP的输出代码定义为GB2312或GBK而产生的中文无法正确输出就不能用这个函数来解决。一个好的习惯是在我们编写每一个JSP页面时都在文件的第一行定义程序所要输出的字符集,如

<%@ page contentType="text/html; charset=GBK" %>或<%@ page contentType="text/html; charset=GB2312" %>

  对于一些不支持定义输出的字符集的JSP版本,我们也可以作如下的设置:

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">

  另外还需要注意的是,这个函数是用来解决那些确实出现了无法正确输出中文的代码,而不是一个通用的用来保证中文字符正确输出的函数。由于中文字符无法正确的输出或读入的原因都是因为这个字符的编码和系统缺省的字符集编码(或者是应用所要输出的字符集,二者一般情况下是相同的)的不同引起的,所以在应用该函数前我们必须确定我们所要读入或输出的字符的编码到底与系统缺省的字符集编码是否相同。
下面的例子将给出该函数的正确和错误使用的情况。例子所采用的JSP的系统为Tomcat 3.2.1,客户端和服务器端的运行环境都是中文的Windows2000。

  例1

<%@ page contentType="text/html; charset=GBK" %>

<html>

<head>

 <title>

  testJSP

 </title>

</head>

<body>

<h1>

<%

 class testChina extends Object{

  public 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;

  }

 }

 public void test(){

 }

}

testChina testC = new testChina();

String str1 =new String("这是一个对中文支持的测试".getBytes("GBK"));

String str2=new String("这是一个对中文支持的测试".getBytes("GBK"),"ISO-8859-1");

String str3 =new String(testC.toChinese(str2));

out.println("Begin<br>");

out.println("str1");

out.println(str1+"<br>");

out.println("str2");

out.println(str2+"<br>");

out.println("str3");

out.println(str3+"<br>");

out.println("End<br>");

System.getProperties().list(System.out);

%>

</h1>

</body>

</html>

  我们知道,Java编程语言默认的编码方式是UNICODE但Java编译器所使用的字符集则是操作系统的默认字符集,中文的Windows 是GBK,英文系统则是ISO-8895-1。对于例1来讲,系统的默认字符集是GBK,JSP的输出字符集也是GBK,二者是一致的。对于str1,我们令其采用系统默认的字符集编码;对于str2我们刻意的将其转换为ISO-8895-1编码以产生中文无法正确输出的结果;str3是testC类的toChinese函数的一个不正确用法,它将原本正确的字符输出转化成了与系统字符集不符合的字符编码,反而引起了造成了中文输出的错误;str3则是testC类toChinese函数的一个正确用法,它将str2的字符输出错误纠正了过来。所以我们一定要正确分析字符输出不正常的原因再使用toChinese函数。那么我们如何来区分那些字符可能出现问题呢。下面有几个主要的原则需要注意:

  1) 主要考虑字符变量情况。由于变量的字符编码形式较为隐蔽,多次的变量间数值的改变和运算可能会引起字符集的改变;在变量与页面所提交数据的各种操作中,较容易发生不同编码格式字符进行运算的情况。

  2) 注意字符的读入,读出。大部分字符的编码格式与目标编码格式发生冲突的情况势发生在字符的读入和输出过程。例如Form的提交,URL的得到以及控件内容的显示(如List控件)等等。

  3) 必要的时候需要作测试。由于Java的中文问题的产生随着Web服务器,浏览器,运行环境和开发工具的不同都可能发生变化,所以为了更好的避免问题的发生,我们必须作一些针对性的测试。

  当然解决Java中文问题的方法并不局限于强制编码输出这一种。我们也可以采用下面的方法练解决:

  1) 以javac -encoding big5 sourcefile.java 或者javac -encoding gb2312 sourcefile.java的方式编译源程序。

  2) 采用Java2 JDK的中文本地化版本(http://java.sun.com/products/jdk/1.2/chinesejdk.html),但该版本是一种非官方的版本,Sun公司并不保证它的升级。

  数据库访问过程中的中文问题

  经过了上面的讨论,对于数据库访问过程中所存在的中文问题也就不太难理解了。

  目前,大部分的JDBC驱动程序并不是针对中文系统来设计的(中文数据大都采用ISO-8859-1编码方式),所以在数据读写过程中往往需要字符编码的转化。

  如果系统运行在中文操作系统平台下,则:

  1) 中文字符的读入,可以采用如下的代码:

strChinese= new String(String(rs.getObject(j).toString().getBytes("ISO-8859-1"));

  对于Win2000平台下,采用Weblogic 6.0所提供的JDBC驱动来读入中文代码可如下来编写(例子中进行了字符运算):

Driver myDriver = (Driver) Class.forName("weblogic.jdbc.MSSQLserver4.Driver").newInstance();

conn = myDriver.connect("jdbc:weblogic:mssqlserver4", props);

conn.setCatalog("labmanager");

Statement st = conn.createStatement();

file://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"));

}

}


  2) 中文的输出。中文的输出与读入正好是个逆过程。我们需要将字符的系统缺省编码转化为JDBC支持的ISO-8859-1编码。代码可以如下编写:

temPBytes=strInput.getText().getBytes();

SQLstr=new String(tempBytes,”ISO-8859-1”);

  需要注意的是,不同的JDBC驱动对相同的数据库的支持并不同,而同一类JDBC驱动对不同的数据库的支持也不相同,也就是说我们的字符转化代码在JDBC驱动改变的时候必须作必要的测试才能确定其是否工作正常,不然我们反而会变成了画蛇添足。例如对于i-net 的Una 2000 Driver Version 2.03 for MS SQL Server,我们根本就不需要做任何的编码转化就可以实现中文的正常操作。但是,由于很多的JDBC的驱动并没有明确的给出其对中文字符的支持情况,所以建议在使用JDBC时都作一下测试。

  结论

  事实上,Java中文处理之所以存在问题,其根本原因是由于被操作的中文字符(变量)的编码格式与目标的编码格式不同造成的,所有这些问题其实都是发生在字符的读入、输出过程中的,只要我们把握住这一环节,就可以更好的理解和处理Java的中文问题了。

上一篇: Java 平台透析
下一篇: 谈谈java的学习方向(转载)

编辑推荐
相关内容
·JAVA 方法重载
·浮点型(Floating-Point Types)
·字符
·布尔型
·java 变量
·C/C++程序员请注意指针的用法
·位运算符
·Java咖啡馆(4)——品味第一杯咖啡
·Java学习:了解什么叫做JavaBean
·java基础学习:常用的ant的操作
·数组排序1例
·JAVA - IO包的学习引导文章
·高效编写JAVA代码的30条建议
·编写跨平台Java程序注意事项
·一个很好解释java的面向对象及信息隐藏的模
·java学习:VisualAge使用技巧二
·Java新手学习:IIS6和Tomcat5的整合
·Java高级学习:Java代码编写的30条建议
·合格的程序员
·Java入门:理解构造器
最近更新
人气最热
·Java 平台透析
·谈谈java的学习方向(转载)
·用java获取ip
·简析Java RMI 与 .NET Remoting
·解析Java对象引用与JVM自动内存管理
·idltojava编译器使用的 IDL-to-Java映射
·四种Java脚本语言之评测
·浅谈Java与C#的事件处理机制
·Java 相关的编译技术
·javac命令用法
·解析Java对象引用与JVM自动内存管理
·Java入门:理解构造器
·Java编程规则
·java中的变量
·简析Java RMI 与 .NET Remoting
·滴滴香浓,意犹未尽—畅游Java世界(2)
·idltojava编译器使用的 IDL-to-Java映射
·浅谈Java与C#的事件处理机制
·Java平台乱弹一
·LOG处理SystemLoggerEvent.java

 
·[硬件]HDPC机箱首选 讯凯CoolerMaster机箱赏
·[数码]安耐克SF-700a待机时间测试
·[汽车]北京4成受访车主响应6月5日不开车
·[开发]Quick Report V4.0 For D6 汉化加强版
·[资讯]全球磁盘存储市场增势强劲 得益于存储
·[游戏]《天堂2》20级暗精法师安全之路经验
·[本本]AMD调低单核Athlon64/Sempron售价
·[办公]全能之美 柯尼卡美能达2480MF彩色激光
·[手机]D500急降200 三星滑盖军团价格崩溃
·[考试]数学教育(专科)专业基本规范
·[学院]unix大杂烩--基础型一
·[娱乐]魔力彩蛋
 

关于我们 | 联系我们 | 广告服务 | 工作机会 | 版权声明 | 欢迎投稿 | 网站地图
Copyright © 2000-2008 , www.21tx.com , All Rights Reserved .
© 晨新科技 版权所有 Created by TXSite.net