日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

使用DBUnit框架数据库插入特殊字符失败的查错经历

發(fā)布時間:2025/3/15 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用DBUnit框架数据库插入特殊字符失败的查错经历 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文記錄的是使用DBUnit測試框架進(jìn)行數(shù)據(jù)庫數(shù)據(jù)插入時,插入特殊字符失敗的查錯經(jīng)歷。希望能對向我這樣的小白同學(xué)們在遇到類似問題時,能夠有一些啟發(fā)。
背景:
在寫跟數(shù)據(jù)庫交互模塊的單元測試,數(shù)據(jù)庫表中的ext字段,需要先寫入數(shù)據(jù),然后再讀取出來,進(jìn)行處理。ext字段格式是key1CTRL^Dvalue1CTRL^CKey2CTRL^Dvalue2。使用DBUnit框架來做單元測試,DBUnit是一個基于junit擴展的數(shù)據(jù)庫測試框架。此次項目里插入數(shù)據(jù)庫的數(shù)據(jù)是以xml形式的文件來組織的。xml文件的部分內(nèi)容如下

<?xml version="1.0" encoding="utf-8"?> <dataset> <feed_item_0007id="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轉(zhuǎn)義之后的值。在單元測試中,發(fā)現(xiàn)數(shù)據(jù)庫中讀取出的數(shù)據(jù),本來一個字符 CTRL^C 即 \u0003 變成了6個字符,分別是\,u,0,0,0,3.

排查問題的過程

既然數(shù)據(jù)庫里讀取出的值不對,說明插入的值就是錯的。首先不太了解Java,沒有仔細(xì)看import到單元測試?yán)锏陌?#xff0c;沒有發(fā)現(xiàn)使用了junit框架和DBUnit。導(dǎo)致盲目找了一會兒同事開發(fā)的DBUnitBaseTest這個單元測試基類的問題,認(rèn)為就是轉(zhuǎn)碼的問題。無果,后來看到了這個基類DBUniteBaseTest的源碼,才知道有DBUnit這個東東,而且發(fā)現(xiàn)基類沒做什么特殊處理,就是根據(jù)配置文件初始化DataSource,然后根據(jù)xml數(shù)據(jù)文件向數(shù)據(jù)庫中對應(yīng)表插入數(shù)據(jù)的過程。

后來在google里搜索,用的關(guān)鍵詞就是dbunit \u0003 之類的,太具體了,導(dǎo)致沒有查到太多相關(guān)的有用信息。一直苦于找不到解決問題的思路。
后來有同事提醒可以用CDATA,查了一下CDATA的用法,有了一些思路。

"CDATA是在XML文檔里面使用的關(guān)鍵字,用來告訴XML解析器,這部分內(nèi)容不用解析,是給其他程序用的,比如JAVASCRIPT等等。在XML文檔中的所有文本都會被解析器解析,只有在CDATA部件之內(nèi)的文本會被解析器忽略。"

后來又從上面的搜索結(jié)果的網(wǎng)頁里看到了一個有用的東東: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,就是 &#4; 失敗,報的錯誤是: Character reference "&#4" is an invalid XML character
2.\u0004中,只把 \ 用numeric character代替了,即&#92; u0004 這個方式仍然是6個字符,跟直接寫 \u0004 一樣的效果
3. 使用 CDATA: ext=<![CDATA["postage\u000410.0\u0003"]]> 發(fā)現(xiàn)寫法可能不對,報錯是xml的格式出錯。

這個時候,感覺自己快接近真相了,就是感覺每次搜索\u0004相關(guān)的東西,范圍太小了,不太能找到問題的答案。后來跟同事聊這個問題,同事提到就是這些控制字符沒有正確編碼,一下子就把我點醒了。直接搜 does xml support control characters,有如下發(fā)現(xiàn):

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不支持這幾個控制字符,所以仍然報錯,而且是說&#4這個字符是非法的XML字符。從上面的搜索結(jié)果里看,XML 1.1 支持這幾個控制字符,于是很開心的把xml文件中的xml版本由1.0改成1.1,結(jié)果還是報錯了:

org.dbunit.dataset.DataSetException: Line 1: XML version "1.1" is not supported, only XML 1.0 is supported.

最后使出了簡單粗暴的解決辦法:對于這張表的這個字段,直接使用DataSource, 然后用Statement執(zhí)行sql語句來進(jìn)行數(shù)據(jù)的更新,更新為我們想要的字段。

PS:后來又遇到了在java的properties文件里,如果有中文,程序中解析出來是亂碼的問題。查看了一下同事寫的單元測試的基類DBUnitTest的代碼,發(fā)現(xiàn)properties文件是通過Properties類來加載的 prop.load(new FileInputStream(file))。搜索了一下Properties類的load函數(shù)的定義,發(fā)現(xiàn)是因為

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;

?

轉(zhuǎn)載于:https://www.cnblogs.com/Jack47/p/control-characters-in-dbunit-xml.html

總結(jié)

以上是生活随笔為你收集整理的使用DBUnit框架数据库插入特殊字符失败的查错经历的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。