经常在web开发中碰到中文乱码的问题,一般都是局部性的解决了问题之后就不了了之了。前些天在开发一个小程序,又碰到了中文乱码的问题,于是下定决心彻底解决这个问题。经过了2天的时间,在网上搜索了一些信息,但大都不具权威性。后来无意中发现万方数据库中有关于这方面的论文,下载了三篇看了,受益匪浅。本来是昨天晚上写心得的,遗憾网速太慢,博客上不了,问题解决后兴奋的感觉害得我晚上失眠了。囧!下面总结一下我的收获,希望可以帮助大家从整体上考虑乱码问题,从而解决它。
首先我们要了解web开发的整个流程。如下:
总体框架:客服端(一般指浏览器)<————>服务器端(Tomcat等)<————>数据库系统
服务器处理 数据库驱动
页面转换:html静态页面 <————————> jsp/servlet等 <———————> 数据库
中文乱码主要出现在页面转换之间,静态页面经过服务器转码,提交到逻辑处理部分,然后逻辑处理部分通过数据库驱动与数据库交换信息。我们要注意5个会影响到编码的部分。
1、html静态页面:这个部分的乱码比较好解决,直接在<head>标签中添加页面设置标签<meta http-equiv="content-type" content="text/html;charset=GBK"> ,这个标签的作用是静态页面告诉服务器,"我的页面类型是text/html,编码是GBK,请你按照GBK编码方式来解析我的请求"。
2、服务器默认的编码方式是ISO8859-1。首先服务器会获取请求编码,request.getCharacterEncoding(), 如果请求页面没有如上面的设置,则获取结果为NULL;则服务器使用默认的编码解析请求。此时请求信息已经经过了从GBK——>ISO8859-1的转码。
3、逻辑处理部分,通常为jsp/servlet。jsp页面编码的设置也很简单,
<%@ page contentType="text/html;charset=GBK" %> ,通过服务器处理后的请求信息要正常显示,必须转换编码,ISO8859-1——>GBK,通常的方法是:new String(str.getBytes("ISO8859-1"),"GBK"),即将请求信息转为jsp页面编码。至于servlet,我还没有找到如何设置其编码的方法,它默认是操作系统的编码,可以通过codeName= System.getProperty(file.encoding)获取。然后转换编码new String(str.getBytes(codeName),"GBK")即可。对于返回页面的处理,通过response.setContentType("text/html;charset=GBK")设置返回内容的类型和编码,应该和返回页面的内容和编码相同。
4、数据库驱动,数据库连接的默认方式是ISO8859-1。所以在逻辑处理部分的sql语句中如果包含中文,应该先将中文转码为ISO8859-1编码方式,再填入sql语句中执行操作。对于查询返回的结果就要执行相反的转码操作,从ISO8859-1转到逻辑处理页面的编码。
5、数据库系统,必须支持中文。对于MySQL数据库,默认编码是ISO8859-1,可以设置编码方式。编辑%MySQL%/conf 目录下的my.ini文件,在[mysqld]区域修改default-character-set = utf8,在 [client] 区域添加
default-character-set = utf8,重新启动服务器,在客服端输入show variables like 'character_set_%';结果显示如下:
character_set_client = latin1
character_set_connection = latin1
character_set_database = utf8
character_set_filesystem = binary
character_set_results = latin1
character_set_server = utf8
character_set_system = utf8
然后输入show variables like 'collation_%';显示结果如下:
collation_database = latin1_swedish_ci
collation_connection = utf8_general_ci
collation_server = utf8_general_ci
说明配置文件已经修改成功,数据库已经支持中文啦!