当前位置: 首页 > 工具软件 > JiBX > 使用案例 >

JiBX初步

申屠鹏
2023-12-01

摘要

JiBX是一款非常优秀的XML(Extensible Markup Language)数据绑定框架。它提供灵活的绑定映射文件实现数据对象与XML文件之间的转换;并不需要你修改既有的Java类。另外,另外,它的转换效率是目前很多开源项目都无法比拟的。

 

正文

XML已经成为目前程序开发配置的重要组成部分了,而可以用来操作XML文件的开源项目也逐渐成长起来,比如说流行的:Digester、XStream、Castor、JDOM、dom4j、xalan等等,当然也少不了专门为Java语言设计的xml数据绑定框架JiBX。它的主要有转换效率高、配置绑定文件简单、不需要操作xpath文件、不需要写属性的get/set方法、对象属性名与xml文件element名不要相同等优点。由于JiBX项目有比较完整的文档和例子;所以在下面的文章中,我主要会介绍使用JiBX需要注意的细节问题。

   

内容

l         JiBX工作机制

l         为何JiBX如此高效

l         JiBX绑定文件

l         在ant中运行绑定

l         基本类型与默认值

l         使用char时要小心

l         使用接口时需给出工厂方法

l         如何使用Map

l         中文问题又来了

l         概要

 

JiBX工作机制

使用JiBX绑定xml文档与java对象需要分两步走,第一步是绑定xml文件,也就是映射xml文件与java对象之间的对应关系;第二步是在运行时,实现xml文件与java实例之间的互相转换;这时,它已经与绑定文件无关了,可以说是完全脱耦了。

在运行程序之前,需要先配置绑定文件并进行绑定,在绑定过程中它将会动态的修改你程序中相应的class文件,主要是生成对应对象实例的方法和添加被绑定标记的属性JiBX_bindingList等。它使用的技术是BCEL(Byte Code Engineering Library),BCEL是Apache Software Foundation 的Jakarta 项目的一部分。也是目前 Java classworking 最广泛使用的一种框架,它可以让您深入 JVM 汇编语言进行类操作的细节。在JiBX运行时转换时,它使用了目前比较流行的一个技术XPP(Xml Pull Parsing),这也正是我下面一个item要将到的为何JiBX如此高效。

 

为何JiBX如此高效

在说明这个之前,先给大家介绍数据绑定转换中两个通用概念:Unmarshal(数据分解)和Marshal(数据编排);从字面意思也很容易理解,Unmarshal是将xml文件转换成java对象,而Marshal则是将java对象编排成规范的xml文件。JiBX在Unmarshal/Marshal上如此高效,这要归功于使用了XPP技术,而不是使用基于树型(tree-based)方式,将整个文档写入内存,然后进行操作的DOM(Document Object Model);也不是使用基于事件流(event stream)的SAX(Simple API for Xml)。XPP使用的是不断增加的数据流处理方式,同时允许在解析xml文件时中断。JiBX在Unmarshal/Marshal的性能测试数据可以参考下面这篇文章《Java 中的 XML: 数据绑定,第 2 部分:性能》。

   

在ant中运行绑定

JiBX提供了一个ant tasks来支持绑定操作;当然,你也可以直接在cmd line下执行绑定操作,绑定时用的包是jibx-bind.jar和bcel.jar;

在命令行下执行绑定操作: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。

这样讲解后,你应该得出一个结论,如果让基本类型为可选项时,是无法输出默认值的。在解决这个问题上,我们不使用基本类型就行了,JDK5.0也支持自动装箱和拆箱了,再某些属性声明时不是用基本类型对我们的影响并不是很大;或者寄希望于JiBX以后的版本实现装箱和拆箱操作。

 

使用char时要小心

上面提到了在要绑定的字段里不推荐使用基本类型,如果你一定要使用基本类型,就得小心使用char类型,因为char类型比较特殊,你可以把它看作是只有一个字符的String,也可以看成是0-65535之间的一个数字,所以在JiBX使用时,你需要明确该类型字段在转换时的序列化和反序列化操作。幸运的是,JiBX提供了这样的序列化和反序列化类,在绑定文件里应加上如下可选属性:

<value name="stringValue" field="stringValue"

serializer="org.jibx.runtime.Utility.serializeCharString" deserializer="org.jibx.runtime.Utility.deserializeCharString"/>

   

使用接口时需给出工厂方法

从xml文件转换到java对象时,是先要创建该类的实例的,如果转换的是一个实体类,创建实例就不会有什么问题,但是如果我们要使用接口编程,转换的对象就是一个接口,则会出现错误,因为JiBX并不清楚你需要创建这个接口的那个实例,这将会导致错误;所以我们需要在绑定文件中指明该接口的创建工厂方法。例如:我们声明一个List的属性listValue,想要它指向一个ArrayList的实例,我们则需要写一个返回ArrayList实例的工厂方法getArrayListInstance;并在绑定文件中添加factory可选属性,如下:

<collection field="listValue"

factory="com.gelc.JiBXInterfaceFactory.getArrayListInstance" />

    另外值得一提的就是,JiBX例子里的工厂方法的modifier是private,我用JUint对代码进行测试不会有问题,但是用ant运行同样的测试,就会有IllegalAccessError,这是JiBX存在的一个Bug;对于该问题,我建议将modifier改为public,这样就不会出现问题。

   

如何使用Map

    在JiBX的核心包里是不支持Map类型的转换的,不过你不用担心,在JiBX的jibx-extras.jar附加包里提供了对Map的支持。你想使用Map还需要为它重写marshal/ummarshal方法,你不要被这个给吓倒了,因为JiBX已经为你提供了这个实现框架,你只需要作相应的修改就ok了。如果你想了解更多,可以参考JiBX提供的定制JiBX绑定方法指南。

   

中文问题又来了

    说到java项目中的中文问题,我相信很多开发者都遇到过,JiBX对中文的支持也不太让人满意,因为JiBX只支持Java标准的字符集,也就是说我们常用的GB2312和GBK不在支持行列之内,如果你用的是UTF-8来处理中文,则没有任何问题,但是你想用GB2312或GBK编码来实现转换的话,则需要你自己实现GB2312和GBK的Escaper类,重写writeAttribute(String, Writer)、writeCData(String, Writer)和writeContent(String, Writer)方法,由于GB2312和GBK的编码规则是相同的,只是字符集大小不一样,所以你可以让同一个Escaper来处理这两种编码。

   

概要

JiBX 是一款高性能的数据绑定框架。如果xml文件格式比较固定,同时数据转换比较频繁时,可以考虑让它来助你一臂之力。

 类似资料: