JiBX教程

时间:2020-02-23 14:35:20  来源:igfitidea点击:

JiBX是一个非常强大的框架,可以将XML数据转换为Java对象,反之亦然。
在XML是数据传输格式的应用程序集成中,它非常有用。
例如,基于消息模型的Web服务和旧式系统集成。

JiBX

将Java对象转换为XML称为编组,从XML创建Java对象称为反编组。

有许多可用于XML转换的框架,例如JAXB和XMLBeans,但是JiBX在XML绑定和转换过程的方法上有所不同。

JiBX通过在编译时通过ant脚本生成的实用程序类来执行这些任务。
这种方法通过将与其他解析器一起使用的传统的两步处理转移到一个步骤,从而减少了处理时间。

迄今为止,在各种XML绑定工具上进行的基准测试表明,JiBX是最快,内存效率最高的解析框架。

在JiBX教程的此处,我提供了使用JiBX解析器进行XML转换的示例应用程序。

系统信息:

  • 用于项目设置的Eclipse IDE
  • Mac OS X Version 10.6.4
  • Java 1.5
  • Ant 1.7.0
  • JiBX jars – bcel.jar, jibx-bind.jar and jibx-run.jar

bcel.jar和jibx-bind.jar用于创建XML转换的实用程序类,运行时环境需要jibx-run.jar。

您可以下载这些jar或者使用maven pom.xml进行下载,然后重命名。

<dependency>
	<groupId>org.jibx</groupId>
	<artifactId>jibx-bind</artifactId>
	<version>1.3.1</version>
</dependency>

JiBX绑定示例

假设我们有一个Employee类,带有三个参数-id,name和雇用日期。

package com.theitroad.jibx.bean;

public class Employee {
	private String id;
	private String name;
	private String hireDate;

	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getHireDate() {
		return hireDate;
	}
	public void setHireDate(String hireDate) {
		this.hireDate = hireDate;
	}
}

我们需要像下面这样将对象转换为XML:

<?xml version="1.0" encoding="UTF-8"?>
<Employee id="237871">
<name>Cisco</name>
<hiredate>Jan 03, 2011</hiredate>
</Employee>

为了使用JiBX,我们需要设置四件事。

  • JiBX绑定编译器用于以字节码(即类文件)生成绑定定义的映射定义文件(binding.xml)。

  • 分发包中包含的Jibx-bind.jar和bcel.jar中包含的JiBX编译器。

  • 用来运行JiBX编译器并生成绑定类的Ant构建文件(build.xml)。

  • JiBx-run.jar中存在的JiBX运行时,应在运行时出现在类路径中。

JiBX示例Eclipse项目

下图显示了在正确设置所有内容后我们将拥有的最终Eclipse项目。

JiBX绑定文件

对于上述转换," binding.xml"文件将如下所示:

<binding>
	<mapping name="Employee" class="com.theitroad.jibx.bean.Employee" ordered="false">
		<value style="attribute" name="id" field="id" usage="optional" 
		<value name="name" field="name" 
		<value name="hiredate" field="hireDate" usage="optional" 
	</mapping>
</binding>

映射存在于根绑定标记中。
特定类的所有映射将包含在映射标记中。

JiBX绑定属性

映射中的name属性指定XML中节点的名称。
在我们的例子中,它是" Employee",并通过class属性链接到Employee类。

可选属性ordered =" false"将删除XML中严格检查以遵循在binding.xml文件中出现的顺序。
这意味着名称标签可以出现在" hiredate"标签上方或者下方。

JiBX绑定字段

雇员对象的元素包含在值标签中。
style =" attribute"指定职员ID应该是职员标签的属性。

field属性用于将id元素映射到java变量id。
可选属性用法="可选"可用于指定id属性不是强制性属性,如果XML中不存在id属性,或者Java对象中为null,则可以跳过。

同样,其他元素也可以保留在正常值标签中。
值标签中的name属性指定XML中标签的名称。

为了简单起见和易于理解,该示例仅限于这些简单标签。
存在嵌套标记,例如结构,集合。
有关这些的更多信息,请参见JiBX文档。

JiBX ant构建文件

映射完成后,我们需要创建ant构建文件。
对于我们的示例,它将如下所示:

<?xml version="1.0"?>

<!-- ===================================================================

Ant build file for JiBX data binding starter example.

=================================================================== -->

<project basedir="." default="bind">

<!-- The following block is intended to set the jibx-home location. It first
 checks the relative location of the JiBX libraries when this starter example
 is run directly from the JiBX distribution, then (if that fails), looks for
 an environmental variable JIBX_HOME with the installation path. If you prefer
 to just set the path directly in this file, uncomment the following line and
 set the value to the appropriate directory, then delete the rest of the Ant
 commands down to the end of this block. -->
 <property name="jibx-home" value="${basedir}"

<!-- End of jibx-home location setting block. -->

<!-- make sure required jars are present -->
<condition property="runtime-jars-found">
  <available file="${basedir}/lib/jibx-run.jar"
</condition>
<condition property="binding-jars-found">
  <and>
    <available file="${basedir}/lib/bcel.jar"
    <available file="${basedir}/lib/jibx-bind.jar"
    <available file="${basedir}/lib/jibx-run.jar"
  </and>
</condition>

<!-- set classpath for compiling and running application with JiBX -->
<path id="classpath">
  <fileset dir="${basedir}/lib" includes="*.jar"
  <pathelement location="${basedir}/bin"
</path>

<!-- make sure runtime jars are present -->
<target name="check-runtime">
  <fail unless="jibx-home">JiBX home directory not found - define JIBX_HOME system property or set path directly in build.xml file.</fail>
  <fail unless="runtime-jars-found">Required JiBX runtime jar jibx-run.jar was not found in JiBX home lib directory (${jibx-home}/lib)</fail>
</target>

<!-- make sure binding jars are present -->
<target name="check-binding" depends="check-runtime">
  <fail unless="binding-jars-found">Required JiBX binding jar jibx-bind.jar or bcel.jar was not found in JiBX home lib directory (${jibx-home}/lib)</fail>
</target>

<!-- bind as a separate step -->
<target name="bind" depends="check-binding">

  <echo message="Running JiBX binding compiler"
  <taskdef name="bind" classname="org.jibx.binding.ant.CompileTask">
    <classpath>
      <fileset dir="${jibx-home}/lib" includes="*.jar"
    </classpath>
  </taskdef>
  <bind binding="${basedir}/binding.xml">
    <classpath refid="classpath"
  </bind>
</target>
</project>

在JiBXTest项目的根目录中复制绑定文件和构建文件,并使用指定的" bind"目标进行构建。
这将运行JiBX绑定编译器,该编译器反过来使用binding.xml映射文件并将其编译为绑定定义类。
JiBX运行时将使用这些类来处理XML。

hyman:JIBXTest hyman$pwd
/Users/hyman/EclipseWorkspace/JIBXTest
hyman:JIBXTest hyman$ant bind
Buildfile: build.xml

check-runtime:

check-binding:

bind:
   [echo] Running JiBX binding compiler

BUILD SUCCESSFUL
Total time: 0 seconds
hyman:JIBXTest hyman$ls -ltr bin/com/theitroad/jibx/bean/
total 32
-rw-r--r--  1 hyman  staff  2507 Dec 14 18:10 JiBX_bindingEmployee_access2.class
-rw-r--r--  1 hyman  staff  3860 Dec 16 10:14 Employee.class
-rw-r--r--  1 hyman  staff  1663 Dec 16 10:56 JiBX_bindingFactory.class
-rw-r--r--  1 hyman  staff  2505 Dec 16 10:56 JiBX_bindingEmployee_access.class

现在,我们将测试绑定。
为此,我们将使用一个示例程序将Employee java对象编组为XML,并将XML字符串解编为Employee对象。

package com.theitroad.jibx.test;

import java.io.StringReader;
import java.io.StringWriter;

import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IMarshallingContext;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;

import com.theitroad.jibx.bean.Employee;

public class JibxTest {
	public String marshalEmployee(Employee employee){
		try {
			IBindingFactory bfact = BindingDirectory.getFactory(Employee.class);
			IMarshallingContext mctx = bfact.createMarshallingContext();
			mctx.setIndent(2);
			StringWriter stringWriter = new StringWriter();
			mctx.setOutput(stringWriter);
			mctx.marshalDocument(employee, "UTF-8", null);
			String output = stringWriter.toString();
			return output;
		} catch (JiBXException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void unMarshalEmployee(String inputXml){
		try {
			IBindingFactory bfact = BindingDirectory.getFactory(Employee.class);
			IUnmarshallingContext uctx = bfact.createUnmarshallingContext();
			StringReader stringReader = new StringReader(inputXml);
			Employee employee  = (Employee) uctx.unmarshalDocument(stringReader, null);
			System.out.println("Employee ID:"+employee.getId());
		} catch (JiBXException e) {
			e.printStackTrace();
		}
	}

	public static void main(String args[]){
		String inputXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Employee id=\"237871\"><name>Cisco</name><hiredate>Jan 03, 2011</hiredate></Employee>";
		JibxTest jibxTest = new JibxTest();
		jibxTest.unMarshalEmployee(inputXml);

		Employee employee = new Employee();
		employee.setId("237871");
		employee.setName("Cisco");
		employee.setHireDate("Jan 03, 2011");

		System.out.println("Employee as XML String:"+jibxTest.marshalEmployee(employee));
	}
}

现在,我们将从命令行运行此测试程序并检查输出。

hyman:JIBXTest hyman$cd bin
hyman:bin hyman$java -cp .:../lib/jibx-run.jar com/theitroad/jibx/test/JibxTest
Employee ID:12345
Employee as XML String:<?xml version="1.0" encoding="UTF-8"?>
<Employee id="237871">
<name>Cisco</name>
<hiredate>Jan 03, 2011</hiredate>
</Employee>
hyman:bin hyman$

如您所见,我们只需要在类路径中放入jibx运行时jar即可执行我们的测试程序。