Blog Archive

Convert Java objects to / from XML using JAXB

How to serialize and deserialize a Java object to and from an XML document using JAXB

  • JAXB Marshalling 
    • Converts Java Object into an XML document 
  • JAXB Unmarshalling 
    • Converts XML document into a Java Object 
JAXB short for Java Architecture for XML Binding helps transform Java objects into XML and vice versa using Java Annotations. This is done with the help of the Marshaller class which is responsible for the process of serializing Java content trees into XML data and back. In this example we will explore how to convert a sample Order data with some details and convert that into an XML order information with the help of JAXB and then convert that back into a Java Object using JAXB Unmarshaller. Also provided in the sample is how to override the namespace prefixes with your own custom tags by extending the NamespacePrefixMapper class.

Order Header Java Object source

package com.as400samplecode.util;

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

//the root-element of our order XML file
@XmlRootElement(namespace="http://www.mysamplecode.com/ws/v10")
public class OrderHeader {
 
 String customerId = null;
 String orderId = null;
 Double orderTotal = null;
 ArrayList<OrderDetail> orderDetailList;
 
 public String getCustomerId() {
  return customerId;
 }
 
 //defines the XML element name and it's namespace
 @XmlElement(name = "CustomerId", namespace="http://www.mysamplecode.com/ws/v10")
 public void setCustomerId(String customerId) {
  this.customerId = customerId;
 }
 
 public String getOrderId() {
  return orderId;
 }
 
 //this makes it an attribute for the parent node
 @XmlAttribute
 public void setOrderId(String orderId) {
  this.orderId = orderId;
 }
 public Double getOrderTotal() {
  return orderTotal;
 }
 
 //rename the given element
 @XmlElement(name = "OrderTotal")
 public void setOrderTotal(Double orderTotal) {
  this.orderTotal = orderTotal;
 }
 
 public ArrayList<OrderDetail> getOrderDetailList() {
  return orderDetailList;
 }
 
 //adds a wrapper element around the XML representation
 @XmlElementWrapper(name = "OrderDetails")
 
 //override the name for the XML element
 @XmlElement(name = "OrderDetail")
 public void setOrderDetailList(ArrayList<OrderDetail> orderDetailList) {
  this.orderDetailList = orderDetailList;
 }

}

Order Detail Java Object source

package com.as400samplecode.util;

import javax.xml.bind.annotation.XmlAttribute;

public class OrderDetail {
 
 String lineId = null;
 String itemNumber = null;
 int quantity = 0;
 Double price = null;
 
 public String getLineId() {
  return lineId;
 }
 
 //this makes it an attribute for the parent node
 @XmlAttribute
 public void setLineId(String lineId) {
  this.lineId = lineId;
 }
 public String getItemNumber() {
  return itemNumber;
 }
 public void setItemNumber(String itemNumber) {
  this.itemNumber = itemNumber;
 }
 public int getQuantity() {
  return quantity;
 }
 public void setQuantity(int quantity) {
  this.quantity = quantity;
 }
 public Double getPrice() {
  return price;
 }
 public void setPrice(Double price) {
  this.price = price;
 }

}

Custom Namespace Prefix Mapper

package com.as400samplecode;
 
import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
 
public class MyNamespaceMapper extends NamespacePrefixMapper {
 
    private static final String FOO_PREFIX = "q0"; // DEFAULT NAMESPACE
    private static final String FOO_URI = "http://www.mysamplecode.com/ws/v10";
 
    private static final String BAR_PREFIX = "xsi";
    private static final String BAR_URI = "http://www.w3.org/2001/XMLSchema-instance";
 
    @Override
    public String getPreferredPrefix(String namespaceUri, String suggestion, 
      boolean requirePrefix) {
        if(FOO_URI.equals(namespaceUri)) {
            return FOO_PREFIX;
        } else if(BAR_URI.equals(namespaceUri)) {
            return BAR_PREFIX;
        }
        return suggestion;
    }
 
    @Override
    public String[] getPreDeclaredNamespaceUris() {
        return new String[] { FOO_URI, BAR_URI };
    }
 
}

Generate XML from our Java Object

package com.as400samplecode;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;

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

import com.as400samplecode.util.OrderDetail;
import com.as400samplecode.util.OrderHeader;

public class JAXBGenerateXML {

 public static void main(String[] args) {

  OrderHeader orderHeader = new OrderHeader();
  orderHeader.setCustomerId("CUST01");
  orderHeader.setOrderId("101010");
  orderHeader.setOrderTotal(99.99);

  ArrayList<OrderDetail> orderDetailList = new ArrayList<OrderDetail>();

  OrderDetail orderDetail = new OrderDetail();
  orderDetail.setLineId("1");
  orderDetail.setItemNumber("ABC");
  orderDetail.setQuantity(9);
  orderDetail.setPrice(10.00);
  orderDetailList.add(orderDetail);

  orderDetail = new OrderDetail();
  orderDetail.setLineId("2");
  orderDetail.setItemNumber("XYZ");
  orderDetail.setQuantity(1);
  orderDetail.setPrice(9.99);
  orderDetailList.add(orderDetail);

  orderHeader.setOrderDetailList(orderDetailList);

  try {

   JAXBContext jaxbContext = JAXBContext.newInstance(OrderHeader.class);
   //class responsible for the process of 
   //serializing Java object into XML data
   Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

   //marshalled XML data is formatted with linefeeds and indentation
   jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
   //specify the xsi:schemaLocation attribute value 
   //to place in the marshalled XML output
   jaxbMarshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, 
    "http://www.mysamplecode.com/ws/v10 OrderService_v10.xsd");
   try {
   //override for custom namespace prefix
   jaxbMarshaller
    .setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", 
     new MyNamespaceMapper());
   } catch(PropertyException e) {
    System.out.println(e);
   }

   //send to console
   jaxbMarshaller.marshal(orderHeader, System.out);
   //send to file system
   OutputStream os = new FileOutputStream("data/MyOrder.xml" );
   jaxbMarshaller.marshal(orderHeader, os );

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

 }

}

Program Result - MyOrder.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<q0:orderHeader xmlns:q0="http://www.mysamplecode.com/ws/v10" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    orderId="101010" 
    xsi:schemaLocation="http://www.mysamplecode.com/ws/v10 OrderService_v10.xsd">
    <q0:CustomerId>CUST01</q0:CustomerId>
    <OrderDetails>
        <OrderDetail lineId="1">
            <itemNumber>ABC</itemNumber>
            <price>10.0</price>
            <quantity>9</quantity>
        </OrderDetail>
        <OrderDetail lineId="2">
            <itemNumber>XYZ</itemNumber>
            <price>9.99</price>
            <quantity>1</quantity>
        </OrderDetail>
    </OrderDetails>
    <OrderTotal>99.99</OrderTotal>
</q0:orderHeader>

Parse XML using JAXB into Java Objects

package com.as400samplecode;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;

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

import com.as400samplecode.util.OrderDetail;
import com.as400samplecode.util.OrderHeader;

public class JAXBGenerateObject {

 public static void main(String[] args) {

 try {

  //create file input stream
  InputStream is = new FileInputStream( "data/MyOrder.xml" );
  //XML and Java binding 
  JAXBContext jaxbContext = JAXBContext.newInstance(OrderHeader.class);

  //class responsible for the process of deserializing 
  //XML data into Java object
  Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
  OrderHeader orderHeader = (OrderHeader) jaxbUnmarshaller.unmarshal(is);

  //print the response for debugging
  System.out.println("Order Information --->");
  System.out.println("Customer Id: " + orderHeader.getCustomerId());
  System.out.println("Order Id: " + orderHeader.getOrderId());
  System.out.println("Order Total: " + orderHeader.getOrderTotal());

  ArrayList<OrderDetail> orderDetailList = orderHeader.getOrderDetailList();
  for (int i=0; i<orderDetailList.size(); i++){
   System.out.println("Order Detail --->");
   OrderDetail orderDetail = orderDetailList.get(i);
   System.out.println("Line Id: " + orderDetail.getLineId());
   System.out.println("Item Number: " + orderDetail.getItemNumber());
   System.out.println("Quantity: " + orderDetail.getQuantity());
   System.out.println("Price: " + orderDetail.getPrice());

  }

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



 }

}

References


3 comments :