1
Jax-B(Java
API for XML Binding)
Jax-B
provides to convert java class to xml file(marshal) and xml to java objects (un-marshal).
Jax-B comes
with JRE6 as a default. No need to install extra software’s to work with xml
files.
We have
provider and consumer programs consumer needs to interact with consumer and
provider and consumer is written on java so he can send serializable object to
provider but we are not sure which technology provider was. So here we have
only one option to communicate with provider that is through xml files. To
achieve this process we have jax-B API.
As part of
xml we need to pass the security as well as application binding protocols.
2
Features
of JAX-B 2.0
·
Annotations
·
Supports
w3c xml schema features
·
Supports
JAX-P validations
3
Creating
schema
To generate java classes first we need to have
the schema file. Schema is also xml file which contains the definitions of all
data types as well as all related classes. Following are the normal java
classes and we need to generate schemas for those
Employee(id, name, salary);
Address( street,
city, state, pincode)
Phone(country code,
number)
Account(id, number,
name, balance, last 10 transactions)
|
3.1
Creating schema:
Mapping between schema and java
schema
type
|
Java
type
|
Simple type
|
Property
|
Attribute
|
Property
|
Complex type
|
Class
|
Following is the Employee normal
java class and related Employee schema.
Public class Employee {
Private Integer id;
Private String name;
}
|
<?xml version="1.0"
encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:complexType
name=”Employee”>
<xs:sequence>
<xs:element
name=”id” type=”xs:integer”>
<xs:element
name=”name” type=”xs:string”
</xs:sequence>
</xs:complexType>
</xs:schema>
|
4 Binding
architecture
In general we have java class and
object. Java class can be called as blue print of object and object fallows the
structure of class and can be called as instance.
Similar we have schema and xml
file. Xml will be created with the help of schema.
So java class is similar to
schema and object is similar to xml file. Schema is equals to java class and
object is equals to xml file. Following the details diagram for the mappings
between java class, object and schema, xml file
Converting object to xml is
called as marshal and xml to java class is called as un-marshal. In this
process we can perform the schema validation that is called as in memory
validation.
To deal with JAX-B we need
following components.
·
Schema
·
Xml
·
JAX-B classes
·
Java object
JAX-B supports the two
operations. Those are
·
One time operation
·
Run time operation
5 one
time operation
This can be performed in two
directions
1.
generating jax-b classes from schema
2.
generating schema from jax-b classes
5.1
Generating jax-b classes from schema
To generate jax-b classes we need
schema first. Following is the schema file based on that file we need to
generate jax-b classes
<?xml version="1.0"
encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.chandra.com/schemas"
xmlns:employee="http://www.chandra.com/schemas"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="employee"
type="employee:employee" />
<xs:complexType name="employee">
<xs:sequence>
<xs:element name="employeeId" type="xs:integer" minOccurs="1"
maxOccurs="1" />
<xs:element name="employeeName" type="xs:string"
minOccurs="0" maxOccurs="1"
/>
<xs:element name="address" type="employee:address"
minOccurs="0" maxOccurs="unbounded"
/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="address">
<xs:sequence>
<xs:element name="addressId" type="xs:int" minOccurs="1"
maxOccurs="1" />
<xs:element name="street" type="xs:string"
minOccurs="0"
maxOccurs="1" />
<xs:element name="city" type="xs:string"
minOccurs="0"
maxOccurs="1" />
<xs:element name="state" type="xs:string"
minOccurs="0"
maxOccurs="1" />
<xs:element name="pin" type="xs:integer"
minOccurs="0"
maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:schema>
|
With the help of above file we
need to generate jax-b classes. This is possible multiple ways.
·
With xjc command
·
With eclipse
5.1.1
With xjc
command
H:\xjc -d . EmployeeSchema.xsd
parsing a schema...
compiling a schema...
com\chandra\schemas\Address.java
com\chandra\schemas\Employee.java
com\chandra\schemas\ObjectFactory.java
com\chandra\schemas\package-info.java
|
Here dot represent where to save
the generated jax-b classes
5.1.2
With eclipse
1.
To work with eclipse first we need to set the
jdk path to eclipse instead of jre
2.
Create schema definition file
3.
Right click on schema definition file and select
the generate java files
4.
It will open the popup screen and select the
package when we need to save the java classes
5.1.3
Generated classes:
1
|
package com.chandra.jaxb;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import
javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "employee", propOrder = {
"employeeId",
"employeeName",
"address"
})
public class Employee {
@XmlElement(required = true)
protected BigInteger employeeId;
protected String employeeName;
protected List<Address> address;
//setter and getter methods
public List<Address> getAddress() {
if (address == null) {
address = new ArrayList<Address>();
}
return this.address;
}
}
|
2
|
package com.chandra.jaxb;
import java.math.BigInteger;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "address", propOrder = {
"addressId",
"street",
"city",
"state",
"pin"
})
public class Address {
protected int addressId;
protected String street;
protected String city;
protected String state;
protected BigInteger pin;
/setter and
getter methods
}
|
3
|
package com.chandra.jaxb;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
@XmlRegistry
public class ObjectFactory {
private final static QName _Employee_QNAME = new QName("http://www.chandra.com/jaxb", "employee");
public
ObjectFactory() {
}
public Employee createEmployee() {
return new Employee();
}
public Address createAddress() {
return new Address();
}
@XmlElementDecl(namespace = "http://www.chandra.com/jaxb", name = "employee")
public JAXBElement<Employee>
createEmployee(Employee value) {
return new JAXBElement<Employee>(_Employee_QNAME, Employee.class, null, value);
}
}
|
4
|
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.chandra.com/jaxb", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.chandra.jaxb;
|
5.2
Generating schema from javax b classes:
Schema also can generate from
eclipse as well as command prompt. To do this first we need to create jaxb
classes
5.2.1
From command prompt:
H:\WebServices\JaxBToschema\src\com\chandra\jaxb>schemagen -cp .
*.java
warning: The apt tool and its associated API are planned to be
removed in the next major JDK release. These features have been
superseded by javac and the standardized annotation processing API,
javax.annotation.processing and javax.lang.model. Users are
recommended to migrate to the annotation processing features of
javac; see the javac man page for more information.
Note: Writing
H:\WebServices\JaxBToschema\src\com\chandra\jaxb\schema1.xsd
|
5.2.2
From eclipse:
·
Select File > New > Other > Schema from
JAXB Classes
·
Click on next
·
Select the source folder or project to generate
the schema and write the schema name on file name box
·
Click on next and select the project name on
next popup
·
Click on finish button it will generate schema
5.2.3
Generated schema:
<?xml version="1.0"
encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://www.chandra.com.schema"
xmlns:tns="http://www.chandra.com.schema"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="employee"
type="tns:employee" />
<xs:complexType name="employee">
<xs:sequence>
<xs:element name="id" type="xs:int"
minOccurs="0" />
<xs:element name="name" type="xs:string"
minOccurs="0" />
<xs:element name="address" type="tns:address"
minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="address">
<xs:sequence>
<xs:element name="id" type="xs:int"
minOccurs="0" />
<xs:element name="city" type="xs:string"
minOccurs="0" />
<xs:element name="state" type="xs:string"
minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:schema>
|
6 Run
time operation
Run time operations are
converting from jaxb to xml file and xml file to jaxb classes
6.1
marshaller
Converting object to xml is
called as marshal. To do this following are the steps
·
Create domain object
·
Create JAXBContext object
·
Get Marshaller class object
·
Set property to formatted out put
·
Call marshl on domain object
Product prod = new
Product();
prod.setId(1);
prod.setName("Chadnra");
prod.setPrice(10.12D);
JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
Marshaller mar = context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
mar.marshal(prod, System.out);
|
6.2
Un-marshaller
Converting xml to object is
called as un-marshal
Procedure to create object from
xml file:
·
Create xml file
·
Get JAXBContext object
·
Get Unmarshaller object
·
Get JAXBElement by calling the unmarshal method.
which can have the object
·
Get domain object from jaxb element
·
Display data
<?xml version="1.0"
encoding="UTF-8"?>
<prod:product xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com/schemas
file:///H:/XML/Product.xsd"
xmlns:prod="http://www.ibm.com/schemas">
<prod:id>1</prod:id>
<prod:name>Lux</prod:name>
<prod:price>10.0</prod:price>
</prod:product>
|
JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
Unmarshaller unMarshaller = context.createUnmarshaller();
JAXBElement<Product> jp = (JAXBElement<Product>)
unMarshaller.unmarshal(new File(CLASS_PATH + "/com/ibm/pdc/ephs/jaxb/resources/ProductSchema.xml"));
Product p = jp.getValue();
System.out.println(p);
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getPrice());
|
6.3
schema validation on marshaller
public class InMemoryValidationMarshaller
{
private static final String CLASS_PATH = System.getProperty("java.class.path");
public static void
main(String[] args) throws
SAXException, JAXBException
{
SchemaFactory factory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema =
factory.newSchema(new File(CLASS_PATH + "/com/ibm/pdc/ephs/jaxb/resources/Product.xsd"));
JAXBContext context =
JAXBContext.newInstance(ObjectFactory.class);
Marshaller marshaller =
context.createMarshaller();
marshaller.setSchema(schema);
Product prod = new Product();
prod.setId(1);
prod.setName("Chadnra");
prod.setPrice(10.12D);
marshaller.marshal(prod,
System.out);
}
}
|
6.4
schema validation on un-marshaller
public class InMemoryalidationUnMarshaller
{
private static final String CLASS_PATH = System.getProperty("java.class.path");
public static void
main(String[] args) throws
SAXException, JAXBException
{
SchemaFactory factory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema =
factory.newSchema(new File(CLASS_PATH + "/com/ibm/pdc/ephs/jaxb/resources/Product.xsd"));
JAXBContext context =
JAXBContext.newInstance(ObjectFactory.class);
Unmarshaller unMarshaller =
context.createUnmarshaller();
unMarshaller.setSchema(schema);
JAXBElement<Product>
jp = (JAXBElement<Product>) unMarshaller.unmarshal(new File(CLASS_PATH + "/com/ibm/pdc/ephs/jaxb/resources/ProductSchema.xml"));
Product p = jp.getValue();
System.out.println(p);
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getPrice());
}
}
|