JAXB Tutorial: How to Marshal and Unmarshal XML
The samples below are using XML strings instead of files, but could easily be adapted to files if needed.
Spring’s Jaxb2Marshaller
Configuration
To use Spring’s Jaxb2Marshaller, you will need the spring-oxm dependency, which you may already have, since it is used by other major spring components.
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>4.2.4.RELEASE</version> </dependency>
To configure the Jaxb2Marshaller in your Spring context, add the config XML below. Be sure to add all root packages that contain the JAXB classes.
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="packagesToScan"> <list> <!-- List of java packages that contain the jaxb generated classes --> <value>com.Black Slate.consulting</value> <value>org.w3._2000._09.xmldsig_</value> <value>org.w3._2003._05.soap_envelope</value> <value>org.xmlsoap.schemas.ws</value> </list> </property> </bean>
Unmarshalling
To unmarshal an XML string into a JAXB object, just inject the Jaxb2Marshaller and call the unmarshal() method.
public class DoSomethingService { @Autowired private Jaxb2Marshaller marshaller; public JAXBElement<?> unmarshal(String xmlString) { return (JAXBElement<?>) marshaller.unmarshal(new StringSource(xmlString)); } }
Marshalling
To marshal a JAXB object into an XML string, you will need to create a StringResult and pass that to the marshal() method.
public class DoSomethingService { @Autowired private Jaxb2Marshaller marshaller; public String marshal(JAXBElement<?> jaxbElement) { try { StringResult result = new StringResult(); marshaller.marshal(jaxbElement, result); return result.toString(); } catch (Exception e) { throw new IllegalStateException(e); } } }
Java’s XML Packages
Java 6 and later have the standard JAXB interfaces and factories for processing xml available in the java.xml.bind package. You can find more info about JAXB on the JAXB project web site.
UNMARSHALLING
To unmarshal an xml string into a JAXB object, you will need to create an Unmarshaller from the JAXBContext, then call the unmarshal() method with a source/reader and the expected root object.
import javax.xml.bind.*; import javax.xml.stream.*; import java.io.*; public class DoSomethingService { // JAXBContext is thread safe and can be created once private JAXBContext jaxbContext; public DoSomethingService() { try { // create context with ":" separated list of packages that // contain your JAXB ObjectFactory classes jaxbContext = JAXBContext.newInstance( "com.Black Slate.consulting" + ":org.w3._2003._05.soap_envelope"); } catch (Exception e) { throw new IllegalStateException(e); } } public JAXBElement<?> unmarshal(String xmlString) { try { // Unmarshallers are not thread-safe. Create a new one every time. Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(xmlString)); return unmarshaller.unmarshal(reader, YourRootObject.class); } catch (Exception e) { throw new IllegalStateException(e); } } }
Marshalling
To marshal a JAXB object into an XML string, you will need to create a a Marshaller from the JAXBContext and pass a Writer target to the marshal() method.
import javax.xml.bind.*; import javax.xml.stream.*; import java.io.*; public class DoSomethingService { // JAXBContext is thread safe and can be created once private JAXBContext jaxbContext; public DoSomethingService() { try { // create context with ":" separated list of packages that // contain your JAXB ObjectFactory classes jaxbContext = JAXBContext.newInstance( "com.Black Slate.consulting" + ":org.w3._2003._05.soap_envelope"); } catch (Exception e) { throw new IllegalStateException(e); } } public String marshal(JAXBElement<?> jaxbElement) { try { // Marshallers are not thread-safe. Create a new one every time. Marshaller marshaller = jaxbContext.createMarshaller(); StringWriter stringWriter = new StringWriter(); marshaller.marshal(jaxbElement, stringWriter); return stringWriter.toString(); } catch (Exception e) { throw new IllegalStateException(e); } } }
As you can see, the Spring mechanisms are pretty clean, but if you are not using Spring, the Java mechanisms are easy to work with as well.
Next up in this JAXB tutorial series we’ll see how to configure the namespace prefixes.
JAXB Tutorial Side Note
If you’ve ever wondered about the correct spelling of marshalling (vs marshaling), there’s a brief summary on Stack Overflow… (2 l’s is acceptable)
How to use java config for packagesToScan?