Welcome to JiBX tutorial. JiBX is a very powerful framework for converting XML data to java object and vice versa. It is very useful in applications integration where XML is the format for data transfer. For example, Web Services and Legacy Systems Integration based on Message Oriented Model.
JiBX
Converting Java Object to XML is called Marshalling and creating java object from XML is called unmarshalling.
There are many frameworks available for XML transformation such as JAXB and XMLBeans but JiBX differs in the approach for XML binding and transformation process.
JiBX performs these tasks via utility classes generated at compile time via ant scripts. This approach reduces the processing time by moving away from the traditional two-step process with other parsers to a single step.
Benchmarks done on various XML binding tools have shown JiBX as the fastest and the most memory efficient parsing framework till date.
Here in JiBX tutorial, I am providing a sample application for XML transformation using JiBX parser.
System Information:
- Mac OS X Version 10.6.4
- Java 1.5
- Ant 1.7.0
- Eclipse IDE for project setup
- JiBX jars – bcel.jar, jibx-bind.jar and jibx-run.jar
bcel.jar and jibx-bind.jar are used for creating utility classes for XML transformation and jibx-run.jar is required for runtime environment.
You can download these jars or use maven pom.xml to download it and then rename it.
<dependency>
<groupId>org.jibx</groupId>
<artifactId>jibx-bind</artifactId>
<version>1.3.1</version>
</dependency>
JiBX Binding Example
Let’s say we have an Employee class with three parameters – id, name, and hire date.
package com.journaldev.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;
}
}
We need to convert this object to XML like this:
<?xml version="1.0" encoding="UTF-8"?>
<Employee id="237871">
<name>Cisco</name>
<hiredate>Jan 03, 2011</hiredate>
</Employee>
For working with JiBX, we need to set up four things.
- Mapping definition file (
binding.xml
) that is used by the JiBX binding compiler to generate the binding definition in byte code i.e. class files - JiBX Compiler that is present in the
jibx-bind.jar
andbcel.jar
, which are present in the distribution package. - Ant build file (
build.xml
) that is used to run the JiBX compiler and generate binding classes. - JiBX runtime that is present in the
jibx-run.jar
and should be present in the classpath at runtime.
JiBX Example Eclipse Project
Below image shows the final eclipse project that we will have after everything is set up properly.
JiBX binding file
For above transformation binding.xml
file will look like:
<binding>
<mapping name="Employee" class="com.journaldev.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>
The mappings are present in the root binding tag. All mappings for a particular class will be contained in a mapping tag.
JiBX binding attributes
The name attribute in the mapping specifies the name of the node in the XML. In our case, it’s “Employee” and is linked to the Employee class by the class attribute.
The optional attribute ordered=”false” removes the strict check in the XML for following the order as appearing in the binding.xml file. This means that the name tag can appear above or below hiredate
tag.
JiBX binding fields
The elements of employee object are contained in value tags. The style=”attribute” specifies that the employee id should be an attribute of the employee tag.
The field attribute is used to map the id element to the java variable id. An optional attribute usage=”optional” can be used to specify that the id attribute is not a mandatory one and may be skipped if not present in the XML, or is null in the Java object.
Similarly other elements can be kept in normal value tags. The name attribute in the value tags specifies the name of the tag in the XML.
For simplicity purpose and ease of understanding, the example is restricted to only these simple tags. Nested tags like structures, collections exist. More info on these can be found in the JiBX documentation.
JiBX ant build file
Once the mapping is done, we need to create the ant build file. For our example, it will look like this:
<?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>
Copy binding file and build file in the root of JiBXTest project and do a build with the “bind” target specified. This will run the JiBX binding compiler that in turn takes the binding.xml mapping file and compiles it to the binding definition classes. These classes will be used by the JiBX runtime for working with XML.
Pankaj:JIBXTest Pankaj$ pwd
/Users/Pankaj/EclipseWorkspace/JIBXTest
Pankaj:JIBXTest Pankaj$ ant bind
Buildfile: build.xml
check-runtime:
check-binding:
bind:
[echo] Running JiBX binding compiler
BUILD SUCCESSFUL
Total time: 0 seconds
Pankaj:JIBXTest Pankaj$ ls -ltr bin/com/journaldev/jibx/bean/
total 32
-rw-r--r-- 1 Pankaj staff 2507 Dec 14 18:10 JiBX_bindingEmployee_access2.class
-rw-r--r-- 1 Pankaj staff 3860 Dec 16 10:14 Employee.class
-rw-r--r-- 1 Pankaj staff 1663 Dec 16 10:56 JiBX_bindingFactory.class
-rw-r--r-- 1 Pankaj staff 2505 Dec 16 10:56 JiBX_bindingEmployee_access.class
Now we will test our binding. For this, we will use a sample program for marshalling an Employee java object to XML and un-marshalling XML string to the Employee object.
package com.journaldev.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.journaldev.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));
}
}
Now we will run this test program from command line and check the output.
Pankaj:JIBXTest Pankaj$ cd bin
Pankaj:bin Pankaj$ java -cp .:../lib/jibx-run.jar com/journaldev/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>
Pankaj:bin Pankaj$
As you can see that we need to put only jibx runtime jar in the classpath to execute our test program.
I hope that the JiBX example given here is good for getting started with JiBX parser. You can download the JiBX tutorial project from below link.
Reference: Official Website