This post demonstrates JAXB2 Code generation example using maven-jaxb2-plugin, adding generated code to source with build-helper-maven-plugin. Sometimes, while integrating with third party software, we only get XSD’s as input. In such situations, we are responsible to generate the actual JAXB2 compliant Java code which can then be used on client side to perform integration with third party.
There are numerous plugins available to perform Code-Generation using XSD as input. One that often used in industry and became matured over time is maven-jaxb2-plugin.
This post will go through Code generation process and then using the generated code in our sample application.
Following are the steps :
1) Create Project Directory Structure
This is the initial directory structure of our project.
The files which interest us are in src/main/resources/workflow folder, namely .xsd (schema file) and .xjb( binding file).
2) Configure the maven-jaxb2-plugin in pom.xml
Add the following plugin in build/plugins section in pom.xml
<plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <version>0.12.3</version> <executions> <execution> <id>add-source-for-demoapp</id> <goals> <goal>generate</goal> </goals> <configuration> <schemaDirectory>src/main/resources/workflow</schemaDirectory> <schemaIncludes> <include>edu.xsd</include> </schemaIncludes> <bindingDirectory>src/main/resources/workflow</bindingDirectory> <bindingIncludes> <include>edu.xjb</include> </bindingIncludes> <generateDirectory>target/generated-sources/xjc/workflow</generateDirectory> <generatePackage>com.websystique.xml.workflow</generatePackage> <!-- Other configuration options--> </configuration> </execution> </executions> </plugin>
Please note that only minimal configuraion is shown above. For full options, please visit maven-jaxb2-plugin page.
Plugin declaration is straight-forward. We define the goal to be run and the plugin configuration being used.
: specifies that generate[to generate the actual code] goal needs to be run.
Configuration
: Configuration section governs the way the code will be generated.
schemaDirectory
: Directory where XSD files can be found. In our case, the XSD are found in src/main/resources folder.
schemaIncludes
: provides a way to specify which specific XSD will be consulted while code generation.
bindingDirectory
: Directory where binding files can be found. Binding files are used to provide binding between java type and XML types. In our case, the binding files(.xjb) are found in src/main/resources folder.
bindingIncludes
: provides a way to specify which specific bidning files will be consulted while code generation.
generateDirectory
: Directory where actual generated code will be placed.
generatePackage
: Actual package the generated code will be placed in.
Additionally, inside Configuration section, a sub plugin can be declared to get additional support. For example, In our case, we want our generated code to include toString, equals and hashcode methods
. For that, we can use the jaxb2-basics
plugin (as shown below) inside configuration section shown above.
<plugins> <plugin> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics</artifactId> <version>0.9.4</version> </plugin> </plugins> <args> <arg>-Xequals</arg> <arg>-XhashCode</arg> <arg>-XtoString</arg> </args>
3) Perform mvn clean compile
Execute mvn clean compile. you should see that code-generation plugin gets executed.
E:\workspace7\JaxbAdvancedDemo>mvn clean compile [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building JaxbAdvancedDemo 1.0.0 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ JaxbAdvancedDemo --- [INFO] Deleting E:\workspace7\JaxbAdvancedDemo\target [INFO] [INFO] --- maven-jaxb2-plugin:0.12.3:generate (add-source-for-demoapp) @ JaxbAdvancedDemo --- [INFO] Up-to-date check for source resources [[file:/E:/workspace7/JaxbAdvancedDemo/src/main/resources/w orkflow/edu.xsd, file:/E:/workspace7/JaxbAdvancedDemo/src/main/resources/workflow/edu.xjb, file:/E:/work space7/JaxbAdvancedDemo/pom.xml]] and taret resources [[]]. [INFO] Sources are not up-to-date, XJC will be executed. [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ JaxbAdvancedDemo --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform d ependent! [INFO] Copying 2 resources [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ JaxbAdvancedDemo --- [WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform depende nt! [INFO] Compiling 8 source files to E:\workspace7\JaxbAdvancedDemo\target\classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
This will generate the code inside target folder, under package name mentioned during Configuration.
Refresh your workspace in eclipse. you should see something similar as shown below. Target folder contains the generated code.
4) Add generated code directory as Source Folder
In order to actually use the generated code in your application, you should add the /target/generated-sources/xjc/workflow folder as ‘Source Folder’.
Adding a source folder can be done via
– Eclipse : goto project properties-> java build path -> source -> Add Folder.
– Using build-helper-maven-plugin : Add the plugin in pom.xml as shown below.
Using build-helper-maven-plugin
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.9</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${basedir}/target/generated-sources/xjc/workflow</source> </sources> </configuration> </execution> </executions> </plugin>
We just need to add the goal add-source
and provide the generated code directory under sources
to add as source in our project.
Add above plugin in your pom.xml, re-execute mvn clean compile, and you should see something similar as shown below:
[INFO] [INFO] --- build-helper-maven-plugin:1.9:add-source (add-source) @ JaxbAdvancedDemo --- [INFO] Source directory: E:\workspace7\JaxbAdvancedDemo\target\generated-sources\xjc\workflow added.
Now refresh your workspace[maven update] in eclipse.You should have following structure:
That’s it. You can now use the classes from this generated code, into your application code.These generated class are POJO’s with JAXB annotations.
Below is the complete code example:
Complete Code Example
Following technologies being used:
- Maven 3
- JDK 1.6.0_45
- Joda Time 2.7
- Eclipse JUNO Service Release 2
Let’s begin.
Step 1: Create Project Directory Structure
Following is the initial project directory structure for this example:
Now let’s add the content mentioned in above structure explaining each in detail.
Step 2: Provide Dependencies in Maven pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.websystique.xml</groupId> <artifactId>JaxbAdvancedDemo</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>JaxbAdvancedDemo</name> <properties> <joda-time.version>2.7</joda-time.version> <commons-lang3.version>3.2.1</commons-lang3.version> </properties> <dependencies> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>${joda-time.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang3.version}</version> </dependency> <dependency> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics</artifactId> <version>0.6.5</version> </dependency> </dependencies> <build> <plugins> <!-- For Code Generation --> <plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <version>0.12.3</version> <executions> <execution> <id>add-source-for-demoapp</id> <goals> <goal>generate</goal> </goals> <configuration> <schemaDirectory>src/main/resources/workflow</schemaDirectory> <schemaIncludes> <include>edu.xsd</include> </schemaIncludes> <bindingDirectory>src/main/resources/workflow</bindingDirectory> <bindingIncludes> <include>edu.xjb</include> </bindingIncludes> <generateDirectory>target/generated-sources/xjc/workflow</generateDirectory> <generatePackage>com.websystique.xml.workflow</generatePackage> <!-- For including equals,hashcode and toString methods in generated code --> <plugins> <plugin> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics</artifactId> <version>0.9.4</version> </plugin> </plugins> <args> <arg>-Xequals</arg> <arg>-XhashCode</arg> <arg>-XtoString</arg> </args> </configuration> </execution> </executions> </plugin> <!-- For Adding Generated code directory as source folder --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.9</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${basedir}/target/generated-sources/xjc/workflow</source> </sources> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Step 3: Create Schema [.xsd] and binding [.xjb] files
src/main/resources/workflow/edu.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Student"> <xs:complexType> <xs:sequence> <xs:element name="firstName" type="xs:string" /> <xs:element name="lastName" type="xs:string" /> <xs:element name="birthDate" type="xs:date" /> <xs:element name="section"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="4" /> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> <xs:attribute name="id" type="xs:int" /> </xs:complexType> </xs:element> <xs:element name="University"> <xs:annotation> <xs:documentation>University Details</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string" /> <xs:element name="address" type="xs:string" /> <xs:element name="Students"> <xs:complexType> <xs:sequence> <xs:element ref="Student" minOccurs="1" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
src/main/resources/workflow/edu.xjb
<?xml version="1.0" encoding="UTF-8"?> <jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"> <jxb:bindings schemaLocation="edu.xsd"> <jxb:globalBindings> <jxb:javaType name="org.joda.time.LocalDate" xmlType="xs:date" parseMethod="com.websystique.xml.model.DateConverter.parse" printMethod="com.websystique.xml.model.DateConverter.print" /> </jxb:globalBindings> </jxb:bindings> </jxb:bindings>
JAXB looks into binding files when it might need help in XML to Java type conversion and vice versa. For example, we are using JodaTime LocalDate, but JAXB does not know how to convert JodaTime LocalDate into XML date. It’s up to us, to provide this information (through .xjb files). In practice, we as developer provide java classes which contains print
[converts XML to java type] and parse
methods [convert Java type to XML] (used by JAXB), and declare these classes in binding file(.xjb) under javaType.
Below is the converter class we are using in our example:
package com.websystique.xml.model; import org.apache.commons.lang3.StringUtils; import org.joda.time.LocalDate; public class DateConverter { public static LocalDate parse(String rawValue){ if(StringUtils.isBlank(rawValue)){ return null; } try{ return new LocalDate(rawValue); }catch(IllegalArgumentException ex){ throw new ConverterException("Unable to parse date: " + rawValue, ex); } } public static String print(LocalDate date){ if(date == null){ return null; } return date.toString(); } }
Corresponding Exception handler class:
package com.websystique.xml.model; @SuppressWarnings("serial") public class ConverterException extends RuntimeException{ public ConverterException(){ super(); } public ConverterException(String message, Throwable cause){ super(message,cause); } public ConverterException(String message){ super(message); } public ConverterException(Throwable cause){ super(cause); } }
Step 4: Generate Code : Perform mvn clean compile
Below is the output for the same:
E:\workspace7\JaxbAdvancedDemo>mvn clean compile [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building JaxbAdvancedDemo 1.0.0 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ JaxbAdvancedDemo --- [INFO] Deleting E:\workspace7\JaxbAdvancedDemo\target [INFO] [INFO] --- maven-jaxb2-plugin:0.12.3:generate (add-source-for-demoapp) @ JaxbAdvancedDemo --- [INFO] Up-to-date check for source resources [[file:/E:/workspace7/JaxbAdvancedDemo/src/main/resources/w orkflow/edu.xsd, file:/E:/workspace7/JaxbAdvancedDemo/src/main/resources/workflow/edu.xjb, file:/E:/work space7/JaxbAdvancedDemo/pom.xml]] and taret resources [[]]. [INFO] Sources are not up-to-date, XJC will be executed. [INFO] [INFO] --- build-helper-maven-plugin:1.9:add-source (add-source) @ JaxbAdvancedDemo --- [INFO] Source directory: E:\workspace7\JaxbAdvancedDemo\target\generated-sources\xjc\workflow added. [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ JaxbAdvancedDemo --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform d ependent! [INFO] Copying 2 resources [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ JaxbAdvancedDemo --- [WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform depende nt! [INFO] Compiling 8 source files to E:\workspace7\JaxbAdvancedDemo\target\classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
Below is one of the generated class[Student.java];
// // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2015.05.16 at 09:58:10 PM CEST // package com.websystique.xml.workflow; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.joda.time.LocalDate; import org.jvnet.jaxb2_commons.lang.Equals; import org.jvnet.jaxb2_commons.lang.EqualsStrategy; import org.jvnet.jaxb2_commons.lang.HashCode; import org.jvnet.jaxb2_commons.lang.HashCodeStrategy; import org.jvnet.jaxb2_commons.lang.JAXBEqualsStrategy; import org.jvnet.jaxb2_commons.lang.JAXBHashCodeStrategy; import org.jvnet.jaxb2_commons.lang.JAXBToStringStrategy; import org.jvnet.jaxb2_commons.lang.ToString; import org.jvnet.jaxb2_commons.lang.ToStringStrategy; import org.jvnet.jaxb2_commons.locator.ObjectLocator; import org.jvnet.jaxb2_commons.locator.util.LocatorUtils; /** * <p>Java class for anonymous complex type. * * <p>The following schema fragment specifies the expected content contained within this class. * * <pre> * <complexType> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <sequence> * <element name="firstName" type="{http://www.w3.org/2001/XMLSchema}string"/> * <element name="lastName" type="{http://www.w3.org/2001/XMLSchema}string"/> * <element name="birthDate" type="{http://www.w3.org/2001/XMLSchema}date"/> * <element name="section"> * <simpleType> * <restriction base="{http://www.w3.org/2001/XMLSchema}string"> * <minLength value="4"/> * </restriction> * </simpleType> * </element> * </sequence> * <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}int" /> * </restriction> * </complexContent> * </complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "firstName", "lastName", "birthDate", "section" }) @XmlRootElement(name = "Student") public class Student implements Equals, HashCode, ToString { @XmlElement(required = true) protected String firstName; @XmlElement(required = true) protected String lastName; @XmlElement(required = true, type = String.class) @XmlJavaTypeAdapter(Adapter1 .class) @XmlSchemaType(name = "date") protected LocalDate birthDate; @XmlElement(required = true) protected String section; @XmlAttribute(name = "id") protected Integer id; /** * Gets the value of the firstName property. * * @return * possible object is * {@link String } * */ public String getFirstName() { return firstName; } /** * Sets the value of the firstName property. * * @param value * allowed object is * {@link String } * */ public void setFirstName(String value) { this.firstName = value; } /** * Gets the value of the lastName property. * * @return * possible object is * {@link String } * */ public String getLastName() { return lastName; } /** * Sets the value of the lastName property. * * @param value * allowed object is * {@link String } * */ public void setLastName(String value) { this.lastName = value; } /** * Gets the value of the birthDate property. * * @return * possible object is * {@link String } * */ public LocalDate getBirthDate() { return birthDate; } /** * Sets the value of the birthDate property. * * @param value * allowed object is * {@link String } * */ public void setBirthDate(LocalDate value) { this.birthDate = value; } /** * Gets the value of the section property. * * @return * possible object is * {@link String } * */ public String getSection() { return section; } /** * Sets the value of the section property. * * @param value * allowed object is * {@link String } * */ public void setSection(String value) { this.section = value; } /** * Gets the value of the id property. * * @return * possible object is * {@link Integer } * */ public Integer getId() { return id; } /** * Sets the value of the id property. * * @param value * allowed object is * {@link Integer } * */ public void setId(Integer value) { this.id = value; } public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy strategy) { if (!(object instanceof Student)) { return false; } if (this == object) { return true; } final Student that = ((Student) object); { String lhsFirstName; lhsFirstName = this.getFirstName(); String rhsFirstName; rhsFirstName = that.getFirstName(); if (!strategy.equals(LocatorUtils.property(thisLocator, "firstName", lhsFirstName), LocatorUtils.property(thatLocator, "firstName", rhsFirstName), lhsFirstName, rhsFirstName)) { return false; } } { String lhsLastName; lhsLastName = this.getLastName(); String rhsLastName; rhsLastName = that.getLastName(); if (!strategy.equals(LocatorUtils.property(thisLocator, "lastName", lhsLastName), LocatorUtils.property(thatLocator, "lastName", rhsLastName), lhsLastName, rhsLastName)) { return false; } } { LocalDate lhsBirthDate; lhsBirthDate = this.getBirthDate(); LocalDate rhsBirthDate; rhsBirthDate = that.getBirthDate(); if (!strategy.equals(LocatorUtils.property(thisLocator, "birthDate", lhsBirthDate), LocatorUtils.property(thatLocator, "birthDate", rhsBirthDate), lhsBirthDate, rhsBirthDate)) { return false; } } { String lhsSection; lhsSection = this.getSection(); String rhsSection; rhsSection = that.getSection(); if (!strategy.equals(LocatorUtils.property(thisLocator, "section", lhsSection), LocatorUtils.property(thatLocator, "section", rhsSection), lhsSection, rhsSection)) { return false; } } { Integer lhsId; lhsId = this.getId(); Integer rhsId; rhsId = that.getId(); if (!strategy.equals(LocatorUtils.property(thisLocator, "id", lhsId), LocatorUtils.property(thatLocator, "id", rhsId), lhsId, rhsId)) { return false; } } return true; } public boolean equals(Object object) { final EqualsStrategy strategy = JAXBEqualsStrategy.INSTANCE; return equals(null, null, object, strategy); } public int hashCode(ObjectLocator locator, HashCodeStrategy strategy) { int currentHashCode = 1; { String theFirstName; theFirstName = this.getFirstName(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "firstName", theFirstName), currentHashCode, theFirstName); } { String theLastName; theLastName = this.getLastName(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "lastName", theLastName), currentHashCode, theLastName); } { LocalDate theBirthDate; theBirthDate = this.getBirthDate(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "birthDate", theBirthDate), currentHashCode, theBirthDate); } { String theSection; theSection = this.getSection(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "section", theSection), currentHashCode, theSection); } { Integer theId; theId = this.getId(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "id", theId), currentHashCode, theId); } return currentHashCode; } public int hashCode() { final HashCodeStrategy strategy = JAXBHashCodeStrategy.INSTANCE; return this.hashCode(null, strategy); } public String toString() { final ToStringStrategy strategy = JAXBToStringStrategy.INSTANCE; final StringBuilder buffer = new StringBuilder(); append(null, buffer, strategy); return buffer.toString(); } public StringBuilder append(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) { strategy.appendStart(locator, this, buffer); appendFields(locator, buffer, strategy); strategy.appendEnd(locator, this, buffer); return buffer; } public StringBuilder appendFields(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) { { String theFirstName; theFirstName = this.getFirstName(); strategy.appendField(locator, this, "firstName", buffer, theFirstName); } { String theLastName; theLastName = this.getLastName(); strategy.appendField(locator, this, "lastName", buffer, theLastName); } { LocalDate theBirthDate; theBirthDate = this.getBirthDate(); strategy.appendField(locator, this, "birthDate", buffer, theBirthDate); } { String theSection; theSection = this.getSection(); strategy.appendField(locator, this, "section", buffer, theSection); } { Integer theId; theId = this.getId(); strategy.appendField(locator, this, "id", buffer, theId); } return buffer; } }
Step 5: Create Main, use Generated code and Run it
Use the generated code in sample application, marshal and unmarshal.
package com.websystique.xml; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import org.joda.time.LocalDate; import com.websystique.xml.workflow.Student; import com.websystique.xml.workflow.University; public class JaxbCodeGenerationDemo { private static final String XML_FILE = "education_centers.xml"; public static void main(String[] args) throws JAXBException, FileNotFoundException { List<Student> students = new ArrayList<Student>(); Student s1 = new Student(); s1.setFirstName("Alan"); s1.setLastName("Turing"); s1.setSection("Computer Science"); s1.setBirthDate(new LocalDate(1956, 10, 1)); s1.setId(1); students.add(s1); Student s2 = new Student(); s2.setFirstName("Thomas"); s2.setLastName("Edison"); s2.setSection("Physics"); s2.setBirthDate(new LocalDate(1916, 3, 3)); s2.setId(2); students.add(s2); Student s3 = new Student(); s3.setFirstName("Linus"); s3.setLastName("Torvald"); s3.setSection("Computer Science"); s3.setBirthDate(new LocalDate(1958, 11, 4)); s3.setId(3); students.add(s3); University university = new University(); university.setName("Cambridge"); university.setAddress("England"); University.Students stds = new University.Students(); stds.getStudent().addAll(students); university.setStudents(stds); // create JAXB context JAXBContext context = JAXBContext.newInstance(University.class); System.out.println("<!----------Generating the XML Output-------------->"); // Marshalling [Generate XML from JAVA] // create Marshaller using JAXB context Marshaller m = context.createMarshaller(); // To format the [to be]generated XML output m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Marshall it and write output to System.out or to a file m.marshal(university, System.out); m.marshal(university, new File(XML_FILE)); System.out.println("<!---------------Generating the Java objects from XML Input-------------->"); // UnMarshalling [Generate JAVA from XML] // Instantiate Unmarshaller via context Unmarshaller um = context.createUnmarshaller(); // Unmarshall the provided XML into an object University unif = (University) um.unmarshal(new FileReader(XML_FILE)); List<Student> studentsList = unif.getStudents().getStudent(); for (Student s : studentsList) { System.out.println("Student : " + s); } } }
Run above main class. Below is the output.
<!----------Generating the XML Output--------------> <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <University> <name>Cambridge</name> <address>England</address> <Students> <Student id="1"> <firstName>Alan</firstName> <lastName>Turing</lastName> <birthDate>1956-10-01</birthDate> <section>Computer Science</section> </Student> <Student id="2"> <firstName>Thomas</firstName> <lastName>Edison</lastName> <birthDate>1916-03-03</birthDate> <section>Physics</section> </Student> <Student id="3"> <firstName>Linus</firstName> <lastName>Torvald</lastName> <birthDate>1958-11-04</birthDate> <section>Computer Science</section> </Student> </Students> </University> <!---------------Generating the Java objects from XML Input--------------> Student : com.websystique.xml.workflow.Student@111a3a4[firstName=Alan, lastName=Turing, birthDate=1956-10-01, section=Computer Science, id=1] Student : com.websystique.xml.workflow.Student@12d263f[firstName=Thomas, lastName=Edison, birthDate=1916-03-03, section=Physics, id=2] Student : com.websystique.xml.workflow.Student@12a0f6c[firstName=Linus, lastName=Torvald, birthDate=1958-11-04, section=Computer Science, id=3]
Following is the final project directory structure for this example:
That’s it. In the next post, we will learn about frequently used Jaxb annotations.
Download Source Code
References
If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help improve further our learning process.