作者:曾巧(numenzq) 等級:初級
摘要 JiBX是一款非常優(yōu)秀的XML(Extensible Markup Language)數(shù)據(jù)綁定框架。它提供靈活的綁定映射文件實現(xiàn)數(shù)據(jù)對象與XML文件之間的轉(zhuǎn)換;并不需要你修改既有的Java類。另外,另外,它的轉(zhuǎn)換效率是目前很多開源項目都無法比擬的。
正文 XML已經(jīng)成為目前程序開發(fā)配置的重要組成部分了,而可以用來操作XML文件的開源項目也逐漸成長起來,比如說流行的:Digester、XStream、Castor、JDOM、dom4j、xalan等等,當然也少不了專門為Java語言設計的xml數(shù)據(jù)綁定框架JiBX。它的主要有轉(zhuǎn)換效率高、配置綁定文件簡單、不需要操作xpath文件、不需要寫屬性的get/set方法、對象屬性名與xml文件element名不要相同等優(yōu)點。由于JiBX項目有比較完整的文檔和例子;所以在下面的文章中,我主要會介紹使用JiBX需要注意的細節(jié)問題。
內(nèi)容 l JiBX工作機制 l 為何JiBX如此高效 l JiBX綁定文件 l 在ant中運行綁定 l 基本類型與默認值 l 使用char時要小心 l 使用接口時需給出工廠方法 l 如何使用Map l 中文問題又來了 l 概要
JiBX工作機制 使用JiBX綁定xml文檔與java對象需要分兩步走,第一步是綁定xml文件,也就是映射xml文件與java對象之間的對應關系;第二步是在運行時,實現(xiàn)xml文件與java實例之間的互相轉(zhuǎn)換;這時,它已經(jīng)與綁定文件無關了,可以說是完全脫耦了。 在運行程序之前,需要先配置綁定文件并進行綁定,在綁定過程中它將會動態(tài)的修改你程序中相應的class文件,主要是生成對應對象實例的方法和添加被綁定標記的屬性JiBX_bindingList等。它使用的技術(shù)是BCEL(Byte Code Engineering Library),BCEL是Apache Software Foundation 的Jakarta 項目的一部分。也是目前 Java classworking 最廣泛使用的一種框架,它可以讓您深入 JVM 匯編語言進行類操作的細節(jié)。在JiBX運行時轉(zhuǎn)換時,它使用了目前比較流行的一個技術(shù)XPP(Xml Pull Parsing),這也正是我下面一個item要將到的為何JiBX如此高效。
為何JiBX如此高效 在說明這個之前,先給大家介紹數(shù)據(jù)綁定轉(zhuǎn)換中兩個通用概念:Unmarshal(數(shù)據(jù)分解)和Marshal(數(shù)據(jù)編排);從字面意思也很容易理解,Unmarshal是將xml文件轉(zhuǎn)換成java對象,而Marshal則是將java對象編排成規(guī)范的xml文件。JiBX在Unmarshal/Marshal上如此高效,這要歸功于使用了XPP技術(shù),而不是使用基于樹型(tree-based)方式,將整個文檔寫入內(nèi)存,然后進行操作的DOM(Document Object Model);也不是使用基于事件流(event stream)的SAX(Simple API for Xml)。XPP使用的是不斷增加的數(shù)據(jù)流處理方式,同時允許在解析xml文件時中斷。JiBX在Unmarshal/Marshal的性能測試數(shù)據(jù)可以參考下面這篇文章《Java 中的 XML: 數(shù)據(jù)綁定,第 2 部分:性能》。
在ant中運行綁定 JiBX提供了一個ant tasks來支持綁定操作;當然,你也可以直接在cmd line下執(zhí)行綁定操作,綁定時用的包是jibx-bind.jar和bcel.jar; 在命令行下執(zhí)行綁定操作:java -jar jibx-bind.jar binding.xml。 如果要在ant下使用則可參考如下代碼: <target name="bind" depends="compile"> <echo message="Running JiBX binding compiler" /> <taskdef name="bind" classname="org.jibx.binding.ant.CompileTask"> <classpath> <pathelement location="${basedir}/lib/jibx/jibx-bind.jar" /> </classpath> </taskdef> <bind verbose="true" load="true"> <bindingfileset dir="${bind.dir}"> <include name="binding(001).xml" /> <include name="binding(002).xml" /> …… </bindingfileset> <classpath refid="common-classpath" /> </bind> </target>
基本類型與默認值 在JiBX綁定java對象時,如果你使用了基本類型,又使用了字段為可選值時,你得檢查實際值與你的期望值是否相等。這樣說起有點模糊,舉個例子說明吧。如果java類里有一個名為intValue 的int類型的字段和一個名為stringValue的String類型的字段,同時又在綁定文件中為這兩個字段配置為usage="optional",如: <value name="intValue" field="intValue" usage="optional"/> <value name="stringValue" field="stringValue" usage="optional" /> 也就是說這兩個字段為可選值,可有可無。我們在編排xml文件時,我們可以通過判斷stringValue是否等于null來確認是否要在xml文件里顯示該element;而該字段是基本類型,比如說之前說的intValue,就不能通過null來判斷了,JiBX的做法是判斷基本類型是否等于默認值,也就是說判斷intValue是否等于0;如果是0,就不顯示該element,為非0值時,才能顯示該element。 這樣講解后,你應該得出一個結(jié)論,如果讓基本類型為可選項時,是無法輸出默認值的。在解決這個問題上,我們不使用基本類型就行了,JDK5.0也支持自動裝箱和拆箱了,再某些屬性聲明時不是用基本類型對我們的影響并不是很大;或者寄希望于JiBX以后的版本實現(xiàn)裝箱和拆箱操作。
使用char時要小心 上面提到了在要綁定的字段里不推薦使用基本類型,如果你一定要使用基本類型,就得小心使用char類型,因為char類型比較特殊,你可以把它看作是只有一個字符的String,也可以看成是0-65535之間的一個數(shù)字,所以在JiBX使用時,你需要明確該類型字段在轉(zhuǎn)換時的序列化和反序列化操作。幸運的是,JiBX提供了這樣的序列化和反序列化類,在綁定文件里應加上如下可選屬性: <value name="stringValue" field="stringValue" serializer="org.jibx.runtime.Utility.serializeCharString" deserializer="org.jibx.runtime.Utility.deserializeCharString"/>
使用接口時需給出工廠方法 從xml文件轉(zhuǎn)換到java對象時,是先要創(chuàng)建該類的實例的,如果轉(zhuǎn)換的是一個實體類,創(chuàng)建實例就不會有什么問題,但是如果我們要使用接口編程,轉(zhuǎn)換的對象就是一個接口,則會出現(xiàn)錯誤,因為JiBX并不清楚你需要創(chuàng)建這個接口的那個實例,這將會導致錯誤;所以我們需要在綁定文件中指明該接口的創(chuàng)建工廠方法。例如:我們聲明一個List的屬性listValue,想要它指向一個ArrayList的實例,我們則需要寫一個返回ArrayList實例的工廠方法getArrayListInstance;并在綁定文件中添加factory可選屬性,如下: <collection field="listValue" factory="com.gelc.JiBXInterfaceFactory.getArrayListInstance" /> 另外值得一提的就是,JiBX例子里的工廠方法的modifier是private,我用JUint對代碼進行測試不會有問題,但是用ant運行同樣的測試,就會有IllegalAccessError,這是JiBX存在的一個Bug;對于該問題,我建議將modifier改為public,這樣就不會出現(xiàn)問題。
如何使用Map 在JiBX的核心包里是不支持Map類型的轉(zhuǎn)換的,不過你不用擔心,在JiBX的jibx-extras.jar附加包里提供了對Map的支持。你想使用Map還需要為它重寫marshal/ummarshal方法,你不要被這個給嚇倒了,因為JiBX已經(jīng)為你提供了這個實現(xiàn)框架,你只需要作相應的修改就ok了。如果你想了解更多,可以參考JiBX提供的定制JiBX綁定方法指南。
中文問題又來了 說到java項目中的中文問題,我相信很多開發(fā)者都遇到過,JiBX對中文的支持也不太讓人滿意,因為JiBX只支持Java標準的字符集,也就是說我們常用的GB2312和GBK不在支持行列之內(nèi),如果你用的是UTF-8來處理中文,則沒有任何問題,但是你想用GB2312或GBK編碼來實現(xiàn)轉(zhuǎn)換的話,則需要你自己實現(xiàn)GB2312和GBK的Escaper類,重寫writeAttribute(String, Writer)、writeCData(String, Writer)和writeContent(String, Writer)方法,由于GB2312和GBK的編碼規(guī)則是相同的,只是字符集大小不一樣,所以你可以讓同一個Escaper來處理這兩種編碼。
概要 JiBX 是一款高性能的數(shù)據(jù)綁定框架。如果xml文件格式比較固定,同時數(shù)據(jù)轉(zhuǎn)換比較頻繁時,可以考慮讓它來助你一臂之力。
更多信息 ·JiBX Project index ·Extensible Markup Language ·BCEL ·Xml Pull Parsing |
|
來自: jadar > 《WebService》