使用DBUnit框架数据库插入特殊字符失败的查错经历
本文记录的是使用DBUnit测试框架进行数据库数据插入时,插入特殊字符失败的查错经历。希望能对向我这样的小白同学们在遇到类似问题时,能够有一些启发。
背景:
在写跟数据库交互模块的单元测试,数据库表中的ext字段,需要先写入数据,然后再读取出来,进行处理。ext字段格式是key1CTRL^Dvalue1CTRL^CKey2CTRL^Dvalue2。使用DBUnit框架来做单元测试,DBUnit是一个基于junit扩展的数据库测试框架。此次项目里插入数据库的数据是以xml形式的文件来组织的。xml文件的部分内容如下
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<feed_item_0007
id="323723909"
biz_number="11223345"
ext="item_price\u0003498.00\u0002postage\u000310.00\u0002location\u0003广州深圳\u0002properties\u0003186026840:125200612;6939376:922305\u0002"
/>
</dataset>
在Java中,CTRL^D的值是(char)4,CTRL^C的值是(char)3。此处普及下Java代码中字符串\u0003的意思,就是说Unicode值(char)3转义之后的值。在单元测试中,发现数据库中读取出的数据,本来一个字符 CTRL^C 即 \u0003 变成了6个字符,分别是\,u,0,0,0,3.
排查问题的过程:
既然数据库里读取出的值不对,说明插入的值就是错的。首先不太了解Java,没有仔细看import到单元测试里的包,没有发现使用了junit框架和DBUnit。导致盲目找了一会儿同事开发的DBUnitBaseTest这个单元测试基类的问题,认为就是转码的问题。无果,后来看到了这个基类DBUniteBaseTest的源码,才知道有DBUnit这个东东,而且发现基类没做什么特殊处理,就是根据配置文件初始化DataSource,然后根据xml数据文件向数据库中对应表插入数据的过程。
后来在google里搜索,用的关键词就是dbunit \u0003 之类的,太具体了,导致没有查到太多相关的有用信息。一直苦于找不到解决问题的思路。
后来有同事提醒可以用CDATA,查了一下CDATA的用法,有了一些思路。
"CDATA是在XML文档里面使用的关键字,用来告诉XML解析器,这部分内容不用解析,是给其他程序用的,比如JAVASCRIPT等等。在XML文档中的所有文本都会被解析器解析,只有在CDATA部件之内的文本会被解析器忽略。"
后来又从上面的搜索结果的网页里看到了一个有用的东东:numeric character reference.
Because XML syntax uses some characters for tags and attributes it is not possible to directly use those characters inside XML tags or attribute values. To include special characters inside XM files you must use the numeric character reference instead of that character. The numeric character reference must be UTF-8 because the supported encoding for XML files is defined in the prolog as encoding=“UTF-8” and should not be changed.
The numeric character reference uses the format:
&#nn; decimal form
&#xhh; hexadeciaml form
于是就有了以下的方案:
1.尝试直接写 \u0004的 numeric character,就是  失败,报的错误是: Character reference "" is an invalid XML character
2.\u0004中,只把 \ 用numeric character代替了,即\ u0004 这个方式仍然是6个字符,跟直接写 \u0004 一样的效果
3. 使用 CDATA: ext=<![CDATA["postage\u000410.0\u0003"]]> 发现写法可能不对,报错是xml的格式出错。
这个时候,感觉自己快接近真相了,就是感觉每次搜索\u0004相关的东西,范围太小了,不太能找到问题的答案。后来跟同事聊这个问题,同事提到就是这些控制字符没有正确编码,一下子就把我点醒了。直接搜 does xml support control characters,有如下发现:
Specifically, 0x1-0x1F and 0x7F-0x9F must be encoded as escapes in XML 1.1. The former were forbidden and the latter were optionally not-escaped in 1.0.
所以可以看到,采用方案1时,由于XML1.0不支持这几个控制字符,所以仍然报错,而且是说这个字符是非法的XML字符。从上面的搜索结果里看,XML 1.1 支持这几个控制字符,于是很开心的把xml文件中的xml版本由1.0改成1.1,结果还是报错了:
org.dbunit.dataset.DataSetException: Line 1: XML version "1.1" is not supported, only XML 1.0 is supported.
最后使出了简单粗暴的解决办法:对于这张表的这个字段,直接使用DataSource, 然后用Statement执行sql语句来进行数据的更新,更新为我们想要的字段。
PS:后来又遇到了在java的properties文件里,如果有中文,程序中解析出来是乱码的问题。查看了一下同事写的单元测试的基类DBUnitTest的代码,发现properties文件是通过Properties类来加载的 prop.load(new FileInputStream(file))。搜索了一下Properties类的load函数的定义,发现是因为
The input stream is in a simple line-oriented
format as specified in
load(Reader)and is assumed to use
the ISO 8859-1 character encoding;
使用DBUnit框架数据库插入特殊字符失败的查错经历的更多相关文章
- 数据库 插入时 碰到NULL报错判断的一种方法(技巧)
//public static object ToDBNull(object value) 判断插入数据的时候个别参数不能为空的时候做的判断方法 //{ // if (value == null) / ...
- 数据库插入数据失败,log提示不能将值 NULL 插入列 'id'
已经记不住具体的log信息了,意思就是ID如果没有设置为自增长的情况下就不能插入数据,而建表时ID字段是设置为"not null",所以就不能顺利插入数据. 解决方法有两种: ①建 ...
- VS Code编写Python3 insert 数据库插入无效也不报错的坑~.~
标题最近在开发中需要用到web端开发工具.需要用python工具.偶然发现微软的良心之作:Visual Studio Code,这个大小才几十兆的轻量级代码编辑器,功能却是重量级的,通过插件的方法,, ...
- Mybatis 向MySql数据库插入带有日期类型字段的数据
我们的实体类里面一个字段的日期类型是util.Date,在向数据库插入该实体时会报错,说是 日期哪个字段 Data truncation.所以需要做些更改在mybatis的MAPPER映射文件中对插入 ...
- 十三、CI框架之数据库插入操作
一.CI的数据库插入代码如下: 二.数据库原数据如下: 三.访问网站之后,会显示相关输出 四.我们查看数据库,会增加一条数据 不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微信二维码打赏任意 ...
- uct框架数据库sql文件导入错误之 sql_mode
uct框架在导入sql文件时可能会出现一种错误 ERROR 1101 (42000): BLOB/TEXT column 'brief' can't have a default value 这是由于 ...
- AGS中通过FeatureServer插入数据失败、插入数据在WMTS请求中无法显示以及version概念的讨论
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 在多个项目中,当我方接口给其他部门人员使用时出现了插入数据失 ...
- Laravel框架数据库CURD操作、连贯操作使用方法
Laravel框架数据库CURD操作.连贯如何来操作了这个操作性是非常的方便简单了我们在这里来为各位介绍一篇相关的教程,具体的细节步骤如下文介绍. Laravel是一套简洁.优雅的PHP Web开 ...
- Laravel框架数据库CURD操作、连贯操作
这篇文章主要介绍了Laravel框架数据库CURD操作.连贯操作.链式操作总结,本文包含大量数据库操作常用方法,需要的朋友可以参考下 一.Selects 检索表中的所有行 $users = DB::t ...
随机推荐
- Jquery一般操作归纳
一.DOM操作分类 1.DOM Core getElement(s)获得元素 2.HTML-DOM document.对象/操作标签的属性 3.CSS-DOM ...
- Oracle直方图的详细解析
yuanwen:http://blog.csdn.net/javacoffe/article/details/5578206 Oracle直方图解析 一. 何谓直方图: 直方图是一种统计学上的工 ...
- 搭建maven环境
有两种方式可以配置maven的环境配置,本人推荐使用第二种,即使用本地的maven安装文件,个人感觉这样可以方便管理下载jar包的存放位置,错误信息的输出等,可以在dos窗口中可以清晰看到,虽然比较麻 ...
- ORA-01919
看到这个错误提示再明白不过了,Oracle中某个角色不存在. 不小心把Oracle中的几个重要角色删除掉了(dba,connect,resource),Plsql只能用DBA权限进去,普通权限进不去, ...
- jQuery-强大的jQuery选择器 (详解)[转]
1. 基础选择器 Basics 名称 说明 举例 #id 根据元素Id选择 $("divId") 选择ID为divId的元素 element 根据元素的名称选择, $(&quo ...
- 关于json解析中 解析多重json对象
JSONObject rst = {"AIS-RST":"AIS-00000001","AIS-STATUS":"AIS-0000 ...
- JS制作计算器(键盘版)
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 31.0px Consolas; color: #2b7ec3 } p.p2 { margin: 0.0px ...
- PHP导出大量数据到excel表格
/** * @creator Jimmy * @data 2016/8/22 * @desc 数据导出到excel(csv文件) * @param $filename 导出的csv文件名称 如date ...
- oracle DBMS_LOCK.SLEEP()的使用
create or replace procedure times isii positive:=1;beginloop dbms_lock.sleep(1);dbms_output.put_line ...
- hadoop搭建初步总结
1.安装JDK1.1上传运用软件FileZilla,将windows上的jdk压缩包放到linux的root目录下 1.2解压jdk #创建文件夹 mkdir /usr/java(不要挂在在" ...