JAVA开发中的中文处理问题.docx
- 文档编号:30540082
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:18
- 大小:28.29KB
JAVA开发中的中文处理问题.docx
《JAVA开发中的中文处理问题.docx》由会员分享,可在线阅读,更多相关《JAVA开发中的中文处理问题.docx(18页珍藏版)》请在冰豆网上搜索。
JAVA开发中的中文处理问题
JAVA开发中的中文处理问题
在应用开发的过程中,总会遇到一些“难以理解”的系统缺陷和“不易解决”的问题。
其实,通过认真分析,不必购买昂贵的产品依然可以解决多数问题。
■JDBCODBCBridge的Bug及其解决方法
在编写一数据库管理程序时,发现JDBC-ODBCBridge存在不易发现的Bug。
在向数据表插入数据时,如果为英文字符,存储内容完全正确,如果存入中文字符,部分数据库只能存储前七八个中文字符,其他内容被截去,导致存储内容的不完整(有些数据库不存在这个问题,如SybaseSQLAnywhere5.0。
JDBC-ODBCBridge还存在无法建表的Bug)。
对于广大需要存储中文信息的Java程序员来说,这可是一个不好的消息。
要么改用其他语言编程,要么选择其他价格昂贵的数据库产品。
“一次编写,到处运行”的目标,也大打折扣。
能不能采用变通的方法,将中文信息进行处理后再存储来解决这个问题呢?
答案是肯定的。
解决问题的具体思路、方法
Java采用Unicode码编码方式,中英文字符均采用16bit存储。
既然存储英文信息是正确的,根据一定规则,将中文信息转换成英文信息后存储,自然不会出现截尾现象。
读取信息时再进行逆向操作,将英文信息还原成中文信息即可。
由GB2312编码规则可知,汉字一般为二个高位为1的ASCII码,在转换时将一个汉字的二个高位1去掉,还原时再将二个高位1加上。
为了处理含有英文字符的中文字串,对英文字符则需要加上一个Byte0标记。
以下提供的两个公用静态方法,可加入任何一个类中使用。
将中英文字串转换成纯英文字串
publicstaticStringtoTureAsciiStr(Stringstr){
StringBuffersb=newStringBuffer();
byte[]bt=str.getBytes();
for(inti=0;i〈bt.length;i++〉{
if(bt[i]〈0〉{
//是汉字去高位1
sb.append((char)(bt[i]&&0x7f));
}else{//是英文字符补0作记录
sb.append((char)0);
sb.append((char)bt[i]);
}
}
returnsb.toString();
}
将经转换的字串还原
publicstaticStringunToTrueAsciiStr(Stringstr){
byte[]bt=str.getBytes();
inti,l=0,length=bt.length,j=0;
for(i=0;i〈length;i++〉{
if(bt[i]==0){
l++;
}
}
byte[]bt2=newbyte[length-l];
for(i=0;i〈length;i++){
if(bt[i]==0){
i++;
bt2[j]=bt[i];
}else{
bt2[j]=(byte)(bt[i]|0x80);
}
j++;
}
Stringtt=newString(bt2);
returntt;
}
上例在实际编程中效果很好,只是存储的中文信息需要经过同样处理,才能被其他系统使用。
而且如果中文字串出现英文字符,实际上增加了额外的存储空间。
■Solaris下Servlet编程的中文问题及解决办法
在使用Java开发Internet上的一个应用系统时,发现在Windows下调试完全正常的Servlet,上传到Solaris服务器上,运行却出现故障——返回的网页不能显示中文,应为中文的信息全为乱码;用中文信息做关键字,不能正确检索数据库。
后来采用加入检查代码等方法探知故障原因如下:
显示乱码主要是因为通过类HttpServletResponse提供的方法setContentType无法改变返回给客户的数据的编码方式,正确的编码方式应为GB2312或者GBK,而事实上为缺省的ISO8859-1。
无法检索中文信息则是因为,客户提交的中文信息经浏览器编码到达服务器后,Servlet无法将其正确解码。
举例说明显示乱码解决方法
Servlet一般通常做法如下:
publicclassZldTestServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//在使用Writer向浏览器返回数据前,设置content-typeheader,在这里设置相应的字符集gb2312
response.setContentType("text/html;charset=gb2312");
PrintWriterout=response.getWriter();//*
//正式返回数据
out.println("〈html〉〈head〉〈title〉Servlettest〈/title〉〈/head〉");
out.println("这是一个测试页!
");
out.println("〈/body〉〈/html〉");
out.close();
}
...
}
解决页面显示乱码问题,需将*处代码换成如下内容:
PrintWriterout=newPrintWriter(newOutputStreamWriter(response.getOutputStream(),"gb2312"));
Solaris中文信息检索问题的解决
浏览器利用表单向服务器提交信息时,一般采用x-www-form-urlencoded的MIME格式对数据进行编码。
如果使用get方法,参数名称和参数值经编码后附加在URL后,在Java中称作查询串(querystring)。
在Servlet程序中,如果采用ServletRequest的方法getParameter取得参数值,在Solaris环境下,对汉字却不能正确解码。
因而无法正确检索数据库。
在Java1.2的包——中提供了URLEncode和URLDecode类。
类URLEncode提供了按x-www-form-urlencoded格式对给定串进行转换的方法。
类URLEncode则提供了逆方法。
在编写某网上114查询的Servlet时,采用先取得查询串,再利用类URLDecode解码,再从解码后的串中取得参数,很好地解决了Solrais环境下,中文信息检索的问题。
solaris上开发J2EE应用中文问题的解决
关于JSP和J2EE的中文问题和处理方法,网上已经有很多文章。
一般在中文内核的操作系统(如中文NT,windows2000)上,该问题不是很突出,而在其他一些系统(如linux,solaris)中就比较明显了。
近日在solaris上开发一个J2EE的应用系统,环境是solaris2.7+minij2ee+mysql。
系统在windows和linux下均没有出现中文处理的问题,但部署到solaris上面后所有中文显示为?
。
后来经过分析,发现原因出在系统编码上。
由于安装solaris时默认的系统编码为ASCII,因此以默认的系统编码处理字符串时汉字高位信息丢失。
下面一段简单的jsp程序说明了这个问题:
<%@pagecontentType="text/html;charset=gb2312"%>
<%
Stringstr=request.getParameter("i");
//byte[]b=str.getBytes("iso-8859-1");
byte[]b=str.getBytes();
out.println(newString(b,"gb2312"));
%>
在浏览器中输入foo.jsp?
i=中文,结果显示为?
?
。
如果将byte[]b=str.getBytes();换成上面注释掉的byte[]b=str.getBytes("iso-8859-1");,则正常显示出“中文”二字。
查阅了mysqlJDBC的驱动程序,问题相同。
考虑解决的方法有两个,一个是修改JDBC驱动程序,另一个是将汉字编码成7位,从实现方便的角度选择了后者。
不过后者的缺点是字符串长度增加,并且无法直接通过sql工具来修改数据库了。
网上有一种汉字编码的方法,是将汉字高位去1,英文则补一个0表示。
这种方法有缺陷,因为特定的汉字编码后会出现“'”等SQL语句中有歧义的字符,导致sql失败。
我摘取了minij2ee中uniString的编码方法,该方法将字节表示为其16进制编码,下面是源代码:
publicStringencode()
{
try
{
StringBuffersb=newStringBuffer();
byte[]bytes=m_pareTo("")==0?
m_str.getBytes():
m_str.getBytes(m_enc);
for(inti=0;i { charch; ch=Character.forDigit((bytes[i]>>4)&0xF,16); sb.append(ch); ch=Character.forDigit(bytes[i]&0xF,16); sb.append(ch); } returnsb.toString(); } catch(java.io.UnsupportedEncodingExceptione) { thrownewRuntimeException("Unsupportedencodingtype."); } } publicvoiddecode(Stringencodestr) { StringBuffersb=newStringBuffer(); inti=0; while(i! =encodestr.length()) { sb.append((char)Integer.parseInt(encodestr.substring(i,i+2),16)); i+=2; } m_str=newuniString(sb.toString(),"iso-8859-1").cvt(m_enc); } 使用编码后,问题解决。 另外提一下,minij2ee最新版本中提供了一个uniString类,解决了在所有操作系统上的中文问题。 使用uniString对象,无需关心字符串本身编码,使用时只要调用函数来获得需要的编码即可,如在jsp里调用uniString.gb()即可以以gb2312输出字符串,在数据库存储时调用uniString.iso()即可以以iso-8859-1编码输出字符串,无论在中文内核还是英文内核的操作系统上均通用。 J2EE平台架构上开发CRM的技术过程控制 内容提要: 第一章: 概述 第二章CRM 2.1CRM概述 2.2CRM应用系统模块划分 2.3CRM应用系统模块内在关系 2.4CRM应用系统各模块的技术要求 第三章J2EE 3.1J2EE概述 3.2J2EE组成部分 3.3J2EE各组成部分在开发CRM应用系统中的脚色 3.4J2EE各技术实现CRM应用系统的特点 第四章: J2EE平台架构开发CRM的内容 第五章: 技术层面控制J2EE平台架构开发CRM的过程 第六章: CRM应用系统各个模块的具体技术实现 第七章: 国内CRM系统目前存在的问题以及采用J2EE技术进行的解决方案 第一章概述 本文阐述了关于在J2EE平台上开发CRM应用系统的各方面内容,包括高辉本人对于CRM系统的理解,利用J2EE平台开发过程中要注意的一些技术深层的问题,开发分析中要注意的原则等等。 这些都是作者在实际的工作中通过经验与教训所得来的。 在工作中,我深刻的体会到系统分析员的重要性,尤其是对于以组件为主要开发对象的工程项目,系统分析员的技术与业务素质对于整个项目的成功与否起着非常关键性的作用。 需要说明的是,这并非作者工作文档,而仅仅是一篇分享经验与教训的交流文档,因此,其中关于一些涉及到具体的系统设计问题,我仅仅写了标题,敬请谅解。 第二章CRM 2.1CRM概述 科学技术在不断的进步,市场竞争日益激烈,对于企业来说,越来越强烈的感觉到客户资源是他获胜的最重要的资源之一: 首先企业竞争的优势不仅仅是产品本身,先进的服务手段已成为关键;现代竞争其实就是客户的全面争夺而客户对企业的信任程度往往是从其消费过程中所得到的体验,如何做到最大程度的满足客户是非常重要的内容,因此,客户关系管理系统(CRM)应运而生,并成为近年来西方市场的热点和大买点。 实际上,CRM就是企业与客户的一种一对一的需求关系管理。 这样,对待客户的视角就从过去的部门级别提升到了企业的层次,各个部门共享客户资源,以一个统一的对外接口来与客户交流,因此,这就要求能够将与客户通过各种方式如传真、邮件、电话、网页等交流所获得的所有信息有机的整合。 在设计CRM应用系统的过程中,我们首先要注意数据结构的格式: CRM应用系统的实施关键是以客户为数据结构的核心,这其中包括客户的基本信息、客户所购买的商品列表、客户抱怨、客户建议、客户服务记录、客户潜在需求、客户对企业的忠诚度等等。 这样设计的原因一是使CRM应用系统有一个对于企业易于理解,易于操作的用户接口,二是对于CRM应用系统的设计开发可以比较轻易地拓展,具有良好的开发接口与开发弹性,对于项目负责人、系统分析员能够更加易于控制整个的开发过程,减少项目开发的风险。 另外,我们仔细研究过国内的数家公司的CRM应用系统的产品,从中学到了很多的东西,但同时也看到了这些产品的不足,在本文的后面部分我们将提到,我们发现,造成这种不足的原因在很大程度上是因为技术的原因,因此,经过反复的论证,我们最终还是选择了在我熟悉的J2EE平台上进行开发,这样就很大程度上克服了那些不足。 2.2CRM应用系统模块划分 CRM应用系统主要由市场管理(Marketing)、销售管理(Sales)、服务管理(Service)、呼叫中心(CallCenter)、电子商务(E_Business)五部分组成。 市场管理: 提供易于使用的界面与工具,使操作人员能够彻底的分析市场、客户,策划和跟踪市场策略,分析竞争对手的市场策略等等,以便更加有效的拓展市场。 在这个模块中,通过客户资料中的诸如地域、消费层次,消费习惯与方式、潜在需求、忠诚度、已购买产品列表等等有价值的信息来从不同的角度彻底的进行市场的策略分析,同时还可以评估和跟踪目前已经进行或者正在进行的营销策略,以及通过对自己和竞争对手的数据进行详细的分析,策划更加有效的销售策略。 销售管理: 管理用户信息、商业机会以及销售渠道等等各方面的内容,从而能够使销售人员可以不受地域限制及时掌握资源以及企业的最新的价格信息,并可以向客户提供最新的和最感兴趣的商品列表以及价格信息。 本模块包括机会、账户、合同等的管理,销售队伍组成、销售队伍成员以及资源重新调配的管理,有效跟踪销售业绩,同时提供个体的销售方式与过程参考,灵活进行产品配置、报价、打折、生成销售订单等。 另外,本模块还应该和电子商务模块整合,以便达到多方位、多层次的销售,同时减少销售成本。 服务管理: 本模块通过动态建立知识库,使客户服务代表能够有效的提高服务质量,增加客户的满意程度,并且捕捉和跟踪服务中出现的商业机会、产品质量信息、客户需求等等,并能够适时的向客户建议其他的产品和服务。 呼叫中心: 呼叫中心是实施CRM应用系统的重要的组成部分,他实际上是将销售模块和服务模块进行了一个高度的集成,使一般的业务代表就可以进行实时的销售和服务。 它通过管理账户、合同等等信息,并通过知识库的支持,就可以最大程度的满足客户的多方面的需求。 呼叫中心提供当今最全面的计算机电话集成技术(CTI),通过对已拨号码识别服务(DNIS),自动号吗识别(ANI),交互式语音应答系统(IVR)得全面支持,通过采用系统预制的计算机电话集成技术,可以在用户拨叫的过程中业务代表已经可以获得客户的资料,就灵活的进行业务处理。 电子商务: 电子商务模块是以上所有模块的一个逻辑集成,它提供了一个个性化、人性化、高度集成以及易于使用的用户界面,在这个用户界面上客户可以进行几乎所有的需求,诸如购买、付款、寻求服务支持、查询产品与服务目录、查询订单状态等等,甚至可以与呼叫中心联系在一起,最大程度的满足客户需求。 由于我们采用J2EE架构平台的开发方式,所以可以很容易的将我们在市场管理、销售管理、服务管理以及呼叫中心模块的内容集成到电子商务模块中,同时呼叫中心的大部分功能也可以并且也应该使用销售管理、服务管理模块中开发的组件。 因此,这就要求我们在开发过程中,要充分利用J2EE平台的优点,组件的高度可重用性,减少开发的成本,加快开发的进度,并同时可以控制开发的质量。 在实际的开发中,对于EJB、Servlet的质量要求非常严格,项目负责人、系统分析员必须把握好质量。 2.3CRM应用系统模块内在关系 在前面已经提到,在开发CRM应用系统的数据结构时一定要以客户信息为核心,一方面是为企业提供一个良好的易于操作的用户界面,另一方面是提高开发的可控性,减少开发成本与风险。 以客户信息为核心,所有的模块的内容都是围绕客户,这样也使得应用系统的可拓展性大为提高,维护性加强。 对于开发人员,尤其是系统分析员,所有的功能内容对于他来说都是一种“插件”,各个模块功能之间的耦合性大为降低,很显然会使整个的开发过程更加易于控制。 在各个模块的具体开发实施中,销售模块是基础,他负责管理账户、机会等信息,并且经过销售人员的销售活动的信息支持,对于客户的信息(如需求、购买行为等)的补充,就可以实时的给与市场人员以信息支持,从而随时把握销售策略,便于及时调整。 从某种意义上讲,应该说销售管理、服务管理、呼叫中心以及电子商务这四个模块都是作为市场模块的信息支持,同时反过来,市场管理策略也给与其余企业活动以策略支持。 要实现这一点,就必须在数据结构地设计上以客户信息为核心数据。 CRM应用系统各个模块之间的关系在企业业务上关系非常紧密,但是作为一个非常庞大和复杂的系统,我们不能按照一般传统的软件工程观念,在各个模块之间通过接口通信,这样会带来应用系统在开发、扩充以及维护方面等很多的问题。 正确合理的方案是将客户视做一个对象,将客户资源作为操作的核心。 2.4CRM应用系统各模块的技术要求 基于客户对于CRM应用系统的实际需求以及考虑到系统的未来拓展性、可维护性,CRM应用系统各个模块中除了呼叫中心可以做成客户/服务器(C/S)体系模式之外,其他模块都应该做成瘦客户端(浏览器)/服务器(B/S)模式。 经过了反复的论证并且通过与别的技术方式的比较,我们最终确定采用在J2EE平台上开发CRM应用系统的技术方案。 一方面是因为作为一种比较成熟的技术规范,相对于微软的.NET来说,它的开发要更加安全、成本更低,另一方面,我从很久就一直跟踪分布式开发的技术,对于J2EE的开发非常熟悉。 (当时还没有相关的中文版书籍)。 因此,比较了几种开发平台之后,我们决定采用J2EE。 在这种开发平台上,我们将业务逻辑抽象出来,写成组件,然后将其发布到服务器上,再通过前台程序的开发程序员开发前台界面,调用后台的商务逻辑。 市场管理、销售管理、服务管理之所以采用分布式的开发,一方面是满足业务人员的办公需要,可以不受地域的限制,随时随地地办公,另一方面也是为了降低开发的成本与维护成本。 因为我们看到,在呼叫中心模块中有销售管理、服务管理等内容,同时电子商务模块中又有其余模块的商务逻辑,我们将其抽象出来,一是组件复用,二是减少开发工作量同时减少风险。 第三章: J2EE 3.1J2EE概述 任何一个有经验的Java平台开发人员,都会知道这个平台具有非常强大的功能和非常高的综合程度,并且发展非常迅速。 Java平台的许多应用程序接口(API)为各种应用程序设计和系统级别程序设计提供了丰富的功能。 J2EE是一种技术规范,他给开发人员提供了一种工作平台,它定义了整个标准的应用开发体系结构和一个部署环境,在这个体系结构中,应用开发者的注意力集中在封装商业逻辑和商业规则上,一切与基础结构服务相关的问题以及底层分配问题都由应用程序容器或者服务器来处理。 甚至,从属于事务、持久化、安全等等方面的应用组件的运行时属性都可以使用高度灵活的声明方法在部署环境中定制(一般采用XML)。 这个平台提供了一个简化的开发模型,它具有工业强度的可拓展性,支持合理的集成和灵活的部署,与开发商和应用服务器无关。 3.2J2EE组成部分 对于开发人员来说,J2EE平台提供给他们的就是三种,Jsp、Servlet、EJB这三种开发方式。 Jsp Jsp其实是一种高层的Servlet。 他与以往的其他网页编写脚本有很大的相似性,但是只是在执行时有一些不同。 Jsp引擎将它和它所在的HTML文件一起合成Servlet的代码,然后它的执行就和Servlet的一样了: 先编译成.class文件,然后由支持java虚拟机的服务器来执行,然后输出结果。 我们在使用Jsp中可以使用JavaBean来进行更加灵活的处理。 Servlet Servlet可以被看作是服务器端的applet,它通过ServletResponse以及ServletRequest这两个对象来输出和接收用户传递的参数,然后在内部的方法中执行操作,如访问数据库、访问别的Servlet方法、调用EJB等等,然后将处理结果返回给客户端。 可以通过集成化的开发工具来进行开发。 在一般的工具中都已经构建好一个框架,程序员只需要熟悉html标签以及熟悉一般的java语言就可以进行开发了。 EJB EJB如果除去它的语言特点外,我想对于大多数有比较丰富编程经验的开发人员来说应该可以轻松理解,他非常类似于微软的DCOM。 他有一个自己要存活要活动的一个容器,为了可以让客户进行透明调用,而不必关心位置,他还必须有一个本地和远程接口,同时还应该有一个相关的配置文件,以便告诉容器她要怎样的活法。 对于开发人员来说,如果采用一种集成化的开发工具,如JBuilder,就可以大大减少工作量。 在JBuilder中通过配置相关的服务器路径、容器信息,我们可以通过它的模板来完成一个EJB组件的开发以及分发,非常方便也非常简单。 在开发过程中,建议的开发方式是在会话bean内部调用实体bean,因为实体bean没有状态但是对数据库的亲和,而会话bean中有我们为了控制程序而需要的上下
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JAVA 开发 中的 中文 处理 问题