SSH框架下中文字符乱码问题的研究

1 Java中文乱码问题的产生原因
  在Java Web的应用中,中文字符乱码问题是个由来已久和让人头疼的问题,尤其是刚刚接触Java Web编程的人员,往往在解决中文字符乱码问题上花费了大量的时间和精力。
  要了解Java中文乱码问题的产生原因,先要从Java的字符编码说起,常用的Java字符编码集有以下几种:
  ASCII(American Standard Code for Information Interchange,美国信息互换标准代码),是基于常用的英文字符的一套电脑编码系统。我们知道英文经常使用的字符、数字符号被计算机处理时都是以二进制码的形式出现的。这种二进制码的形式就是所谓的ASCII码。每个ASCII与一个8位二进制数对应。其最高位是0,相应的十进制数是0-127。另有128个扩展的ASCII码,最高位都是1,由一些制表符和其它符号组成。ASCII是现今最通用的单字节编码系统。
  GB2312:GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集-基本集》。主要用于给每个中文字符指定相应的数字,也就是通行编码。一个中文字符用两个字节的数字来表示,为了与ASCII码有所区别,将中文字符每一个字节的最高位置都用1来表示。
  GBK:为了对更多的字符进行编码,国家又发布了新的编码系统GBK(GBK的K是“扩展”的汉语拼音的第一个字母)。在新的编码系统里,除了兼容GB2312外,还对繁体中文、一些不常用的汉字和许多符号进行了编码。
  ISO-8859-1:ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。 ISO-8859-1收录的字符除ASCII收录的字符外,还包括西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。欧元符号出现的比较晚,没有被收录在ISO-8859-1当中。
  Unicode:这是一种通用的字符集,对所有语言的文字进行了统一编码,对每一个字符都用2个字节来表示,对于英文字符前面加“0”字节的策略实现等长兼容。如“a”的ASCII码为0x61,Unicode就为0x00,0x61。
  UTF-8:Unicode Transformation Format-8bit。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如,如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。
  Java使用Unicode来存储字符数据,处理字符时通常有3个步骤:
  1)按给定的字符编码形式,从源输入流中读取字符数据;
  2)以Unicode编码形式将字符数据存储在内存中;
  3)按指定的字符编码形式,将字符数据编码并写入目的输入流中。
  所以Java处理字符时总是经过了两次编码转换,一次是从指定编码转换为Unicode编码,一次是从Unicode编码转换为指定编码。如果读入时用错误的形式解码字符,则内存存储的是错误的Unicode字符。而从最初文件中读出的字符数据,到最终在屏幕终端显示这些字符,期间经过了应用程序的多次转换。如果中间某次字符处理,用错误的编码方式解码了从输入流读取的字符数据,或用错误的编码方式将字符写入输出流,则下一个字符数据的接收者就会编解码出错,从而导致最终显示乱码。
  2 中文字符乱码问题的分类和解决方法
  SSH框架即strut+hibernate+spring,是目前比较流行的开源框架,提出了一种开发J2EE Web应用的轻量级解决方案,以帮助开发人员在短期内搭建结构清晰、可复用性好、维护方便的Web应用程序。本文分析了在开发工具为Eclipse,数据库为oracle,开发框架为SSH,应用服务器为tomcat的环境下中文字符乱码问题的分类和解决方法。
  2.1 数据库写入和读出乱码
  一旦数据库创建后,数据库的字符集是不能改变的。因此,在设计和安装之初考虑使用哪一种字符集是十分重要的。数据库字符集应该是操作系统本地字符集的一个超集。存取数据库的客户使用的字符集将决定选择哪一个超集,即数据库字符集应该是所有客户字符集的超集。
  在oracle中,我们关心的是三个地方的字符集:oracle服务器内部的字符集;ns_lang变量里保存的字符集,客户端应用的字符集。在Java编程中,需要统一Java应用中的字符集,oracle服务器内部的字符集,ns_lang变量里保存的字符集。通常,在Java开发中, oracle10g在创建数据库实例时需要指定SIMPLIFIED CHINESE_CHINA.ZHS16GBK字符集。有时,在安装oracle过程中自动创建数据库实例时使用AMERICAN_AMERICA.WE8ISO8859P1字符集或者一些与Java字符集不兼容的字符集,就会出现乱码问题,这时需要先安装数据库,不自动生成数据库实例,在安装完数据库之后,再通过oracle→配置和移植工具→DataBase Configuration Assistance创建数据库,在图1的界面中选择ZHS16GBK字符集。
  2.2 JSP页面显示和传递中文参数乱码
  要解决这类乱码问题,涉及到几个方面的设置:
  1)在struts的配置文件struts.properties中设置struts.i18n.encoding=gbk,struts.i18n.encoding用在了请求和返回两个阶段中流的编码方式,该参数为gbk时,相当于调用HttpServletRequest的setCharacterEncoding()方法。
  2)在web.xml中添加下面的程序代码,指定字符过滤器对字符的编码方式为gbk。
  
  encodingFilter
  
  org.springframework.web.filter.CharacterEncodingFilter
  
  
  encoding
  gbk
  
  
  
  encodingFilter
  /*
  
  3)在编辑器中用gbk编码保存JSP文件,并设置JSP文件开头的<%@ page language="java" contentType="text/html; charset=gbk" pageEncoding="gbk"%>,其中pageEncoding用来告诉tomcat此文件所用的字符编码。Tomcat以此编码来读取JSP文件并编译。还要设置,当JSP页面用post方法提交数据时,用此处指定的编码方式编码。
  4)设置Tomcat的URIEncoding,如果URIEncoding不加以设置,则默认使用ISO-8859-1来解码URL,设置后便用设置的编码方式来解码。这个解码同时包括Path部分和查询字符串部分。即在Tomcat配置端口的语句中加入URIEncoding="GBK"。
  进行完这些设置之后,基本上就不会出现JSP页面乱码问题了。
  2.3 Action中redirect传递中文参数乱码
  在开发中有时需要用response.sendRedirect做转向,它其实是向浏览器发送一个特别的Header,然后由浏览器来做转向,转到指定的页面,所以用sendRedirect时,浏览器的地址栏上能够看到地址的变化。通常sendRedirect需要把参数挂在地址后面以&分隔传递,传递中文字符时,有时会需要乱码,这时就需要用到Java的URLEncoder类了,这个类有个encode方法,形式为public static String encode(String s, String encoding),在encoding参数中,可以指定字符编码的方式,通常我们传递中文字符时,需要这样写http://ceshi.jsp?param1=java.net.URLEncoder.encode(“你好”,”gbk”)。这样就能防止传递的中文参数乱码了。
  2.4 Ajax传递中文参数乱码
  Ajax即“Asynchronous &#106avascript and XML”(异步&#106avascript和XML)。Ajax提供与服务器异步通信的能力,从而使用户从请求/响应的循环中解脱出来。借助于Ajax,可以在用户单击按钮时,使用&#106avascript和DHTML立即更新UI,并向服务器发出异步请求,以执行更新或查询数据库。当请求返回时,就可以使用&#106avascript和CSS来相应地更新UI,而不是刷新整个页面。最重要的是,用户甚至不知道浏览器正在与服务器通信:Web站点看起来是即时响应的。
  Ajax默认中文提交以UTF-8格式,解决Ajax中文参数乱码问题有两种方式,一种是提交中文后,在服务端用UTF-8编码提取参数:request.setCharsetEncoding(“UTF-8”);String str=request.getParameter(“param”);另一种是在Jsp页面用encodeURI编码两次,即encodeURI(encodeURI(”str”)),然后在服务端用String str=request.getParameter(“param”); java.net.URIDecoder.decode(str, “UTF-8”)。
  3 结束语
  本文介绍了在开发工具为Eclipse,数据库选用oracle,开发框架选用SSH,应用服务器选择tomcat的环境下中文字符乱码问题的分类和解决。根据环境的不同,可将文中编码为GBK的部分替换为其它编码来解决中文乱码问题。
  参考文献:
  [1] 李刚.轻量级J2EE企业应用实战[M].北京:电子工业出版社,2007.
  [2] 秦学礼,孙伟.Java 程序设计使用教程[M].北京:中国铁道出版社,2006.
  注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文
(作者:张进猛,苏健,赵耀)

你可能感兴趣的:(SSH框架下中文字符乱码问题的研究)