使用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 ...
随机推荐
- ActionBarSherlock环境搭建
1.在官网http://actionbarsherlock.com/下载ActionBarSherlock包解压到. 2.创建自己的Android工程: 3.File -> New -> ...
- 使用 VisualCode + iTerm2 提交github的Pull Request
VisualCode集成github功能,是程序猿参与开源项目的利器.相比Sublime简单了很多(插件安装繁琐,比如你试试在Sublime2 安装gosublime,这里有坑; Sublime 3修 ...
- lua string的自定义分割字符串接口
-------------------------------------------------------------------- -- Create By SunC 2014/7/1 -- ...
- PHP的运行机制与原理(底层) [转]
说到php的运行机制还要先给大家介绍php的模块,PHP总共有三个模块:内核.Zend引擎.以及扩展层:PHP内核用来处理请求.文件流.错误处理等相关操作:Zend引擎(ZE)用以将源文件转换成机器语 ...
- 由React学习到Yeoman安装以及遇到的问题
离职闲下来之后想着学一些新知识,本来是想从react入手,结果延伸出去的内容就像一棵树的树枝,不断增加. 学习计划是从这里开始的(6周学习计划,攻克javascript难关 https://zhuan ...
- 在centos上配置IP
当我们安装好系统后,最先做的应该就是配置IP了,因为无论是要下载工具软件.还是远程链接,网络必不可少,所以我们要先来配置IP! 一.查看IP 如何在centos上查看IP呢,使用 ifconfig 命 ...
- 学习codeIgniter的一点小感受
用CI好几天了,最终还是放弃用CI做完整的项目,感觉CI在前后端的交互上还比较差,比如说用户表单验证,仍然是需要把数据提交给服务器之后才能显示逻辑判断的结果.而这一点明显是相对落后了. 但不可否认CI ...
- install mysql using binary and configure manu
(1)下载,解压 (2)初始化数据库 ./scripts/mysql_install_db --defaults-file=../my.cnf --user=guofeng (3)启动命令 ./bin ...
- bond配置
Bonding的模式一共有7种: #defineBOND_MODE_ROUNDROBIN 0 (balance-rr模式)网卡的负载均衡模式 #defineBOND_MODE_ACTI ...
- [UCSD白板题] Sorting: 3-Way Partition
Problem Introduction The goal in this problem is to redesign a given implementation of the randomize ...