Google

Jul 25, 2014

Java and JAXB tutorial to map and convert XML to Java object and vice versa in a nested scenario

Q. What is JAXB, and where is it used?
A. JAXB is an Object o XML Mapping (i.e. OXM) library for Java. Hibernate is an Object to Relational Mapping (i.e. ORM) tool for relational databases, likewise JAXB is an ORM for XML documents. Most often used alongside of web services (JAX-WS and JAX-RS ) when XML is used as a payload to convert XML to Java objects and vice versa. Web services predominantly use XML or JSON (JavaScript Object Notation) as the payloads.

Step 1: The XML document

<Employee>
   <name type="first">Peter</name>
   <age>25</age>
</Employee>


Step 2: The Java object with the relevant JAXB annotations to map fields to XML. Some elements are not annotated with @XmlElement and they are implicitly mapped. Employee and Name are nested objects.

package com.xml;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "Employee")
@XmlType(propOrder = { "name", "age" })
public class Employee {

 private int id;
 private Name name;
 private int age;

 @XmlTransient
 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 @XmlElement
 public Name getName() {
  return this.name;
 }

 public void setName(Name name) {
  this.name = name;
 }

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 @Override
 public String toString() {
  StringBuilder sb = new StringBuilder();
  sb.append(name);
  sb.append("\n");
  sb.append("age=" + age);
  return sb.toString();
 }
}


Name is a nested class as the "type" attribute belongs to name XML element and not "Employee" element.

package com.xml;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlValue;

public class Name {

 private String name;
 private String type;

 @XmlValue
 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 @XmlAttribute
 public String getType() {
  return type;
 }

 public void setType(String type) {
  this.type = type;
 }

 @Override
 public String toString() {
  StringBuilder sb = new StringBuilder();
  sb.append("name=" + this.name);
  if (type != null) {
   sb.append("\ntype=" + type);
  }
  return sb.toString();
 }
}


Step 3: The conversion from and and to object.

package com.xml;

import java.io.ByteArrayInputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class JaxbMarshallUnMarshall {

 public static void main(String[] args) {

  String xml = "<Employee><name type=\"first\">Peter</name><age>25</age></Employee>";

  try {

   JAXBContext context = JAXBContext.newInstance(Employee.class);

   // unmarshalling - XML to Java object
   Unmarshaller un = context.createUnmarshaller();
   Employee emp = (Employee) un.unmarshal(new ByteArrayInputStream(xml.getBytes()));

   System.out.println("Object: " + emp);

   // Marshalling - Java object to XML
   Marshaller m = context.createMarshaller();
   // for pretty-print XML in JAXB
   m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
   m.marshal(emp, System.out);

  } catch (JAXBException e) {
   e.printStackTrace();
  }

 }
}


Output:

Object: name=Peter
type=first
age=25
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Employee>
    <name type="first">Peter</name>
    <age>25</age>
</Employee>


JAXB is a specification like JDBC, JNDI, JPA, etc, and the above example uses the default JDK implementation of JAXB. In the next post, I will  cover MOXy implementation, which has @XmlPath annotation to simplify your Object to XML mapping.

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home