When invoking a web service I get a dynamic response in XML format.
So response could be :
<response>
<test1>test1</test1>
<test2>test1</test2>
<test3>test1</test3>
<test4>test1</test4>
</response>
or :
<response>
<test1>test1</test1>
<test2>test1</test2>
</response>
But I think the response should be static in order for the Java class to be unmarshalled correctly from the XML.
So instead of
<response>
<test1>test1</test1>
<test2>test1</test2>
</response>
This should be :
<response>
<test1>test1</test1>
<test2>test1</test2>
<test3></test3>
<test4></test4>
</response>
This means I can now handle the response and check for missing data.
Am I correct in my thinking?
Default Null Representation
By default a JAXB (JSR-222) implementation will treat a property as an optional element. As such null values are represented as the element being absent from the document.
Alternate Representation of Null
Alternatively you have null represented by including the xsi:nil="true"
attribute on it. This is achieved by annotating your property with @XmlElement(nillable=true)
.
<date xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
Invalid Null Representation
An empty element is not a valid representation for null. It will be treated as an empty String which will be invalid for all non-String types.
<date/>
For More Information
- http://blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html
Update
SO test1 test1 is
a valid response but the fields test3 & test4 will be set to null ?
What happens is that nothing is done for the fields/properties that correspond to absent nodes. They will keep there default values, which are by default initialized to null
.
Java Model (Root)
In the model class below I have initialed the fields to have values that are not null
.
import javax.xml.bind.annotation.*;
@XmlRootElement
public class Root {
@XmlElement
String foo = "Hello";
String bar = "World";
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
Demo
The document being marshalled <root/>
does not have any elements corresponding to the mapped fields/properties in the model class.
import java.io.StringReader;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StringReader xml = new StringReader("<root/>");
Root root = (Root) unmarshaller.unmarshal(xml);
System.out.println(root.foo);
System.out.println(root.bar);
}
}
Output
We see that the default values were output. This shows that a set operation was not performed for the absent nodes.
Hello
World
Refer to JAXB Marshalling with null fields
and also What's the purpose of minOccurs, nillable and restriction?
Use @XmlElement(nillable = true)
for those null/blank value fields to display; but pay particular attention to your date fields.