Java Quick Start – Marshalling a class to XML with JAXB

Want to use JAXB to convert a plain Java class to and from XML without an associated XSD? In this quick start we work through how to do it.

Most of my brushes with JAXB, the Java standard for binding Java classes to XML, have been of the XSD first variety – feed my XML schema into JAXB and get a nice set of freshly minted Java classes to play with.

Doing it the other way round is as easy as pie too; though I had to pop into the Google cave more than I’d like to find enough information to work with.

Here then, as I’ll have forgotten it all again the next time I need to do it, are the simplest possible steps to use JAXB to convert a Java class into XML and back again.

Step one: Assemble the ingredients

For this recipe all you need is the JDK – or at least the JDK is all you need if you’re using anything vaguely recent as JAXB 2.x has been bundled with it since Java 6. If you’re running an up-to-date JDK 1.6 or anything later, you’ll be fine.

For this quick start I’m using Java 8 but this code sample is far from rocket science and should work with older versions okay.

Step two: Prepare your value object

Let’s start with a simple Java value-object class which has three plain string properties:-

@XmlRootElement
public class MyValueObject {

    private String field1;
    private String field2;
    private String field3;

    public MyValueObject() {
    }

    // Getters and Setters
}

There are pitfalls to watch out for when marshalling more complex Java objects to XML, such as properties referencing interfaces or non-simple collections, but for this basic example there are really only two things to note.

First of all we have to annotate our class with @XmlRootElement or JAXB won’t touch it. This is only required for top-level classes though; if our value object contains references to other classes we’ve written they don’t need to be annotated at all unless we want to change how they’re represented.

Secondly we’ve got a no-argument default constructor. Whether our code will use it or not JAXB will certainly use it and won’t be able to create instances of our class without one.

Step three: Marshal to XML

There are three steps to converting an instance of our class into XML:-

  • Create a JAXBContext that knows about our class.
  • Create a Marshaller instance to use.
  • Call one of its marshal methods to create the XML.

Here’s a simple marshaller class that will convert our object to XML either as a returned String or in a file:-

public class MyValueObjectXMLMarshaller {

    public String marshalToString(MyValueObject obj) 
            throws JAXBException {
        JAXBContext jaxbContext = 
                JAXBContext.newInstance(MyValueObject.class);
        Marshaller marshaller = jaxbContext.createMarshaller();
        StringWriter stringWriter = new StringWriter();
        marshaller.marshal(obj, stringWriter);
        return stringWriter.toString();
    }

    public void marshalToFile(MyValueObject obj, File targetFile) 
            throws JAXBException {
        JAXBContext jaxbContext = 
                JAXBContext.newInstance(MyValueObject.class);
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.marshal(obj, targetFile);
    }
}

The only difference between these two methods is the marshal method we’re calling; the other steps are identical. While we haven’t bothered here it’s worth noting that the JAXBContext is thread-safe and it’s very wasteful to create them on-demand like this; far better to manage a single instance in a static field or singleton class somewhere and create one that handles all the classes we want to marshal and unmarshal.

Step four: Unmarshal back from XML

Coming the other way the steps are conveniently similar:-

  • Create a JAXBContext that knows about our class.
  • Create an Unmarshaller instance to use.
  • Call one of its unmarshal methods to create our object from the XML.

So the only difference is that we’re creating an Unmarshaller rather than a Marshaller and calling one of its unmarshal methods.

Here’s an unmarshaller for our MyValueObject class, which will re-create it from XML either read from a file or passed in as a string:-

public class MyValueObjectXMLUnmarshaller {

    public MyValueObject unmarshalFromFile(File file) 
            throws JAXBException {
        JAXBContext jaxbContext = 
                JAXBContext.newInstance(MyValueObject.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        return (MyValueObject)(unmarshaller.unmarshal(file));
    }

    public MyValueObject unmarshalFromString(String xml) 
            throws JAXBException {
        JAXBContext jaxbContext = 
                JAXBContext.newInstance(MyValueObject.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        return (MyValueObject)(unmarshaller.unmarshal(
                new StringReader(xml)));
    }
}

Comments are closed.