By default EclipseLink JAXB (MOXy) will not marshal a mapped field/property with a null
value. You can tell MOXy to marshal a null
value by mapping it with @XmlElement(nillable=true)
. I go into more detail about this here:
If you want to differentitate between a default null
value and one that is explicitly set to null
then you are going to need to track it. Once you are tracking it you can map it with MOXy's @XmlIsSetNullPolicy
.
Java Model
import javax.xml.bind.annotation.XmlElement;
import org.eclipse.persistence.oxm.annotations.XmlIsSetNullPolicy;
import org.eclipse.persistence.oxm.annotations.XmlMarshalNullRepresentation;
public class Root {
@XmlElement
private String foo;
@XmlElement(nillable = true)
private String bar;
private String baz;
private boolean bazSet;
@XmlIsSetNullPolicy(isSetMethodName="isBazSet", nullRepresentationForXml=XmlMarshalNullRepresentation.XSI_NIL)
public String getBaz() {
return baz;
}
public void setBaz(String baz) {
this.baz = baz;
this.bazSet = true;
}
public boolean isBazSet() {
return bazSet;
}
}
Demo Code
Demo
import java.util.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String, Object>(2);
properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Root.class}, properties);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Root root = new Root();
marshaller.marshal(root, System.out);
root.setBaz(null);
marshaller.marshal(root, System.out);
}
}
Output
In the output below we see:
foo
is not marshalled out.bar
is marshalled.baz
is not marshalled when it is unset, and is marshalled when it is set even though the value both times isnull
.
{
"bar" : null
}
{
"bar" : null,
"baz" : null
}