现在的位置: 首页 > 综合 > 正文

测试过程中遇到字符集问题小结

2013年12月03日 ⁄ 综合 ⁄ 共 1890字 ⁄ 字号 评论关闭

 作者:赵璨

 这两天我们在用dbunitIM数据库时碰到了乱码问题,初步做了研究,分享一下,可能对其他测试同学也会有点帮助。有错误的地方大家尽管指出。

 

一:理论

       编程过程中涉及到的字符集编码问题通常涉及到这样几个因素:

1.      文件编码格式

例如XML文件通过第一行的声明指定了文件的编码格式。Java中可以通过InputStream读取文件,用InputStreamReader来对读取后的字节解码。这些在陈教兽的blog中也有(http://blog.csdn.net/linkyou/archive/2009/03/14/3990547.aspx),例如:

InputStream is = new FileInputStream("z.xml");   
InputStreamReader streamReader = new InputStreamReader(is, "GBK");

当然也有用其他方式解码的,例如Dom4j等等。

2.      JVM编码格式

默认的Java都是使用Unicode字符集已做到更好的国际化。因此当需要解析其他字符集的时候,我们需要进行相应的解码。例如:

       String s = "abc";

       byte[] b = s.getBytes("UTF-8");

 

又或者有另一种方式:

String sql = "abc";

String s2 = new String(sql.getBytes("GBK"), "ISO8859-1");

这个如何解释?不能直接理解为将GBK转为ISO8859-1。而是应该理解为字符串sqlGBK解码还原为原始字节数组,再用ISO8859-1解码成正确的字符串。

 

3.      数据库编码格式

这个又复杂了一点,就谈Oracle的字符集,分成服务端和客户端。

服务端上,us7asciiOracle最早支持的编码方案,是单字节编码的。现在为了支持国际化,一般都采用unicode编码了。

客户端上,是通过NLS_LANG指定编码方式的,任何发自或发往客户端的数据都是用客户端定义的字符集编码。

 

二:实战

       好,现在回到我们的问题:

1.    为什么数据库编码为us7ascii时,我们用dbunit插数据会出现乱码?

因为:1. 我们的xml数据文件编码是UTF-8       <?xml version="1.0" encoding="UTF-8"?>

2.    JVM编码默认是GBK,可能大家不同的系统会略有区别,不过应该都是Unicode双字节编码:可以通过Charset.defaultCharset()查看默认编码

3.    IM数据库服务端编码是us7ascii,客户端也要用us7ascii

首先dbunit读取utf-8的文件,默认情况下却用双字节的gbk解码,然后插入到单字节编码规范的数据库中,肯定出现乱码。

2.      如何解决?

最好是编码格式统一,当然数据库的编码格式我们不能改。我们能够改的是xml文件: <?xml version="1.0" encoding="GBK"?>

Ok,现在前两步统一编码了,现在要做的是在插入数据库之前在java代码中用对应us7ascii的编码格式做一次解码,对应的编码规范是“ISO8859-1。这里我们Dbunit的代码要做一下改进,陈洪看看,更新一下代码。

具体代码如下:

       DbUnit db = new DbUnit("oracle.jdbc.driver.OracleDriver",

              "jdbc:oracle:thin:@10.2.225.81:1521:asoft", "aliim",

              "aliim");

       db.setSchema("ALIIM");

       String path = "util//z.xml";

       FileInputStream stream = new FileInputStream(path);

 

         //InputStreamReader的构造函数对读取的字节流做ISO8859-1的解码

       InputStreamReader reader = new InputStreamReader(stream, "ISO8859-1");

 

       FlatXmlDataSet dataSet = new FlatXmlDataSet(reader);

       DatabaseOperation.INSERT.execute(db.getConnection(), dataSet);

抱歉!评论已关闭.