项目简介:
项目是基于spring+Hessian+ibatis构建的一个类webservice服务系统,供客户端如delphi,donet等调用。
问题描述:
有个sqlmap文件(该xml文件encoding=”gbk”)中有一sql语句:Select * from table1 where status=’有效’,该sql语句在windows下和其中一台Linux(简称ServerA,操作系统版本为:Red Hat Enterprise Linux Server release 5)下运行正常,能查出数据来;而在另一台Linux(简称ServerB,操作系统版本为:Red Hat Linux release 9)上却怎么也查不出数据,ServerA和ServerB的JDK和Tomcat版本一致,分别是1.5和6.0.
将日志级别设置成debug,查看日志信息获悉,在Red Hat Linux release 9上,执行Select * from table1 where status=’有效’时,debug出来的信息是Select * from table1 where status=’????’,难怪查不出来数据。
解决方案:
第一反应肯定是linux操作系统默认字符集问题惹的祸,于是先找出ServerA机器的字符集信息,然后将ServerB机器的字符集设置成跟ServerA一样,重启服务器即可。查看ServerA的i18n(more /etc/sysconfig/i18n)信息为:
LANG="zh_CN.gbk"
LANGUAGE="zh_CN.gbk:zh_CN.GB2312:zh_CN"
SUPPORTED="zh_CN.gbk:zh_CN:zh:en_US.UTF-8:en_US:en"
SYSFONT="lat0-sun16"
修改ServerB的i18n信息,并重启ServerB,重启tomcat,心想这次在ServerB下,上述Sql语句肯定能正常执行了。让我悲伤的事情再次发生,在ServerB下,debug出来的信息还是Select * from table1 where status=’????’,我无语。。。
后调式ibatis源代码发现,ibatis在初始化sqlmapclient的时候,会调用Resources.java类文件的getResourceAs*方法,该系列方法里很多都会先判断charset是否为空,如果charset不为空,在用指定的charset来读取sqlmap文件。于是在web.xml文件里,我新增一个Listener,在该Listener里设置charset,代码如下:
com.ibatis.common.resources.Resources.setCharset(Charset.forName("gbk"));
最好将gbk作为参数配置到context-param里,这样就不需要gbk硬编码死,可增加程序灵活性,切记新增的Listener,其在web.xml文件里的顺序一定要在Spring的ContextLoaderListener之前。
重新部署ServerB的应用,并启动Tomcat,执行上述sql语句,终于可以查出结果来了,debug信息显示也是:Select * from table1 where status=’有效’。