本文记录的是使用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 inload(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 插入列 &#39;id&#39;
已经记不住具体的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 ...
随机推荐
-
js和php对bool值的判断区别
一.将一种数据类型转换为bool值时,PHP和JS的转换规则不同 PHP中 当转换为 boolean 时,以下值被认为是 FALSE : 布尔值 FALSE 本身 整型值 0(零) 浮点型值 0.0( ...
-
css样式设置图片半透明度,兼容IE8,火狐
关于背景颜色透明的兼容浏览器的问题,一直是个问题,我所写的兼容IE8,和火狐,说是兼容所有浏览器我就没有测试,有兴趣的朋友可以自己测试下吧. background-color:white;filter ...
-
怎样在excel中添加下拉列表框
用excel2013打开要编辑的工作表,例子是一个班级名单,可以看到政治面貌目前还没有填写 接着我们找一个空白处,依次写入政治面貌的可能选项: 群众.共青团员 然后选中“政治面貌”这一列,点击 ...
-
C语言 串 顺序结构 实现
一个能够自动扩容的顺序结构的串 ArrString (GCC编译). /** * @brief C语言 串 顺序结构 实现 * @author wid * @date 2013-11-01 * * @ ...
-
ReactiveCocoa之UI篇
前言: 上一篇讲ReactiveCocoa是函数响应式编程,并将多种事件响应的方式统一起来,使得不同的事件响应方式高度统一.同时也讲了ReactiveCocoa框架里面常见的几个概念.接下来基于那几个 ...
-
CentOS 5.8 x64 源码安装 samba-3.6.9
环境 CentOS 5.8 X64 wget http://www.samba.org/samba/ftp/stable/samba-3.6.9.tar.gz tar zxvf samb ...
-
Windows10 ubuntu子系统的启用即基础配置
Windows 10 在一周年更新后,本身集成一个不带有图形界面的ubuntu 14.04系统了,大大方便了Linux开发,并且本身使用很方便,像我这种Windows死忠,只会在Linux下跑一下一定 ...
-
Git 基础 —— 常见使用场景
Git 基础学习系列 Git 基础 -- 安装 配置 别名 对象 Git 基础 -- 常用命令 Git 基础 -- 常见使用场景 Git基础 -- Github 的使用 突然插入 Bugifx 工作, ...
-
bootstrap6 关于bs的使用总结
在同一行中也可以有多个过了行的 "行", 即列的"总宽度"超宽度12. 即实现堆叠display:block和水平排列float的自动控制, 在div的clas ...
-
想ACCESS数据库插入新的用户
public string AddUserN = ""; //定义用户名字符串 public string paswrd1 = ""; //密码1 public ...