JAXB: binding java with xml
JAXB allow binding between java objects and xml instance.
Basically with JAXB you can do 'marshall' and 'unmarshall' operations.
Marshall means the process of conversion from java objects to xml instance. With unmarshall means the opposite.
Marshall example
To start with marshalling we need at least our domain class. Suppose we have a city with many person and i want to have an xml file with a root element city wich contains more element of kind people. To do that we need one object of type city wich contains a collection of person objects
City.java
public class City {
private List<Person> list = new ArrayList<Person>();
// get and set
}
Person.java
public class Person {
private String name;
private String surname;
private int age;
// get and set
}
Now, since we want to use JAXB we need to annotate these classes so JAXB can bind them to the xml file. Basically these annotations tell JAXB how we want this binding.
So these are our classes annotated
City.java
package jaxb6;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class City {
private List<Person> list = new ArrayList<Person>();
public List<Person> getList() {
return list;
}
@XmlElement(name="person")
public void setList(List<Person> list) {
this.list = list;
}
}
Person.java
package jaxb6;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Person {
private String name;
private String surname;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
as you can see i have used only two annotations
@XmlRootElement
public class City {
this tell JAXB we want that city is a root element in xml file
@XmlElement(name="person")
public void setList(List list) {
this.list = list;
}
and this tell JAXB we want bind out list propertie with person element in the xml file.
Now we can write our program.
TestMarshall.java
package jaxb6;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class TestMarshall {
public static void main(String[] args) {
try {
JAXBContext context1 = JAXBContext.newInstance(Person.class, City.class);
Person p1 = new Person();
p1.setName("Mario");
p1.setSurname("Rossi");
p1.setAge(30);
Person p2 = new Person();
p2.setName("Valeria");
p2.setSurname("Morandi");
p2.setAge(40);
List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
City city = new City();
city.setList(list);
Marshaller m = context1.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal( city, new File("src/jaxb6/myfile.xml"));
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- first of all we need an object of type JAXBContext to perform a JAXB operations
- then we create some object of Person, add them to a list and add this list to city object
- now we can marshall
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<city>
<person>
<age>30</age>
<name>Mario</name>
<surname>Rossi</surname>
</person>
<person>
<age>40</age>
<name>Valeria</name>
<surname>Morandi</surname>
</person>
</city>
Unmarshall example
To start with unmarshall with JAXB we need at least an xml schema and one instance
Suppose we have this xsd file
city.xsd
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="city" type="city"/>
<xs:element name="person" type="person"/>
<xs:complexType name="city">
<xs:sequence>
<xs:element ref="person" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="person">
<xs:sequence>
<xs:element name="age" type="xs:int"/>
<xs:element name="name" type="xs:string" minOccurs="0"/>
<xs:element name="surname" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
and this xml instance
city.xml
<?xml version="1.0" encoding="UTF-8"?>
<city xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="city.xsd">
<person>
<age>25</age>
<name>Michele</name>
<surname>Pazzi</surname>
</person>
<person>>
<age>48</age>
<name>Elisa</name>
<surname>Manfredi</surname>
</person>
</city>
To unmarshal this xml file with JAXB we also need the java classes with some annotation. JAXB provides a xjc compiler to generate this classes from xml schema. This tool is a command line tool included in JDK
All we need to do is to run this tool
xjc city.xsd
parsing a schema...
compiling a schema...
generated/City.java
generated/ObjectFactory.java
generated/Person.java
Now we can write a program
TestUnmarshall.java
package jaxb7;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import generated2.City;
import generated2.Person;
public class TestUnmarshall {
public static void main(String[] args) {
try {
JAXBContext context = JAXBContext.newInstance("generated2");
Unmarshaller u = context.createUnmarshaller();
JAXBElement element = (JAXBElement) u.unmarshal(new FileInputStream("src/jaxb7/city.xml"));
City city = (City) element.getValue();
List<Person> persons = city.getPerson();
for(Person person:persons){
System.out.println(person);
}
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- as in marshall, we need a JAXBContext object. This was generated setting 'generated2' package which contains all our java classes
- then we unmarshall and create a JAXBElement that allow us to obtain a City object from a root element of the xml file.
- from City we can access to the Person object, iterate and print it
Note that to print person object i have override toString() method
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + ", surname=" + surname + "]";
}
when i run the program the output is like this
Person [age=25, name=Michele, surname=Pazzi]
Person [age=48, name=Elisa, surname=Manfredi]
Comments
Post a Comment