A quick and dirty way to convert Java objects to and from XML

The process to marshal or serialize an object to XML can differ greatly from language to language and implementation to implementation. Even within a single language, like Java, there are multiple ways to go about it. I happened to stumble upon this one the other day and thought it was pretty straight forward.

This example contains two classes XMLExample.java and Example.java. We will use the functions in XMLExample.java to convert Example.java to and from XML.

Note: the source files are available for download below.

// File Example.java

import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Example {

    @XmlElement
    private int someInternalValue = 0;

    private int anotherInternalValue = 123;

    private int _age = 0;

    public Map<Integer, String> myMap = new HashMap<Integer, String>();

    public void setInternalValue(int value)
    {
        someInternalValue = value;
    }

    public int getAge()
    {
        return _age;
    }

    public void setAge(int age)
    {
        _age = age;
    }
}

As you can see Example.java just contains a couple of random getter and setters as well as some internal variables and a public Map.

// File XMLExample.java

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class XMLExample
{
    public static void main(String[] args)
    {
        try
        {
            Example exmp = new Example();
            exmp.setInternalValue(4);
            exmp.setAge(10);
            exmp.myMap.put(5, "The value for key 5");

            String xml = marshallToXML(exmp);
            System.out.println(xml);

            // Null the variable so we can actualy see if we unmarshalled it correctly
            exmp = null;

            exmp = (Example)unmarshallFromXML(Example.class, xml);
            System.out.println("Age = " + exmp.getAge());
            System.out.println("Map value for key '5' = '" + exmp.myMap.get(5) + "'");

        }
        catch (JAXBException ex)
        {
            Logger.getLogger(XMLExample.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Converts an object to its XML representation
     * @param fromObject the object to create the XML based on
     * @return the XML string
     * @throws JAXBException
     */
    public static String marshallToXML(Object fromObject) throws JAXBException
    {
        JAXBContext context = JAXBContext.newInstance(fromObject.getClass());
        Marshaller marshaller = context.createMarshaller();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        marshaller.marshal(fromObject, baos);

        return baos.toString();
    }

    /**
     * Converts XML representation to an object
     * @param toClass the class to create from the XML
     * @param XML the XML containing the object data
     * @return the object
     * @throws JAXBException
     */
    public static Object unmarshallFromXML(Class toClass, String XML) throws JAXBException
    {
        JAXBContext context = JAXBContext.newInstance(toClass);
        Unmarshaller unmarshaller = context.createUnmarshaller();

        ByteArrayInputStream bais = new ByteArrayInputStream(XML.getBytes());

        return unmarshaller.unmarshal(bais);
    }
}

The magic happens in the two functions marshallToXML and unmarshallFromXML. These take annotated variables and functions as well as anything conforming to Java bean conventions (get/set and public) and convert them to XML. So what is the output of the above program?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><example><someInternalValue>4</someInternalValue><myMap><entry><key>5</key><value>The value for key 5</value></entry></myMap><age>10</age></example>
Age = 10
Map value for key '5' = 'The value for key 5'

You’ll notice that it skipped the private variable anotherInternalValue. It did this because it is private in scope and because we did not annotate it.

For a full explanation of how to use this I would highly recommend the excellent JAXB Users Guide over at Java.net. You can download the above source files here.