I’m building a series of linked classes whose instances I want to be able to marshall to XML so I can save them to a file and read them in again later.
At present I’m using the following code as a test case:
import javax.xml.bind.annotation.*; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import java.time.LocalDate; public class LocalDateExample { @XmlRootElement private static class WrapperTest { public LocalDate startDate; } public static void main(String[] args) throws JAXBException { WrapperTest wt = new WrapperTest(); LocalDate ld = LocalDate.of(2016, 3, 1); wt.startDate = ld; marshall(wt); } public static void marshall(Object jaxbObject) throws JAXBException { JAXBContext context = JAXBContext.newInstance(jaxbObject.getClass()); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(jaxbObject, System.out); } }
The XML output is:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <wrapperTest> <startDate/> </wrapperTest>
Is there a reason why the startDate
element is empty? I would like it to contain the string representation of the date (i.e. toString()
). Do I need to write some code of my own in order to do this?
The output of java -version
is:
openjdk version "1.8.0_66-internal" OpenJDK Runtime Environment (build 1.8.0_66-internal-b17) OpenJDK 64-Bit Server VM (build 25.66-b17, mixed mode)
Advertisement
Answer
You will have to create an XmlAdapter
like this:
public class LocalDateAdapter extends XmlAdapter<String, LocalDate> { public LocalDate unmarshal(String v) throws Exception { return LocalDate.parse(v); } public String marshal(LocalDate v) throws Exception { return v.toString(); } }
And annotate your field using
@XmlJavaTypeAdapter(value = LocalDateAdapter.class)
See also javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters
if you want to define your adapters on a package level.