@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "healthCheck",
propOrder = { "healthy", "id" })
public class HealthCheck {
@XmlElement(nillable = true)
protected Boolean healthy;
@XmlElement(nillable = true)
protected String id;
}
HealthCheck healthCheck = new HealthCheck(); healthCheck.setHealthy(true); healthCheck.setId("123");
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:healthCheck xmlns:ns2="">
<healthy xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<id>123</id>
</ns2:healthCheck>
When unmarshalling it on server, I need the information that is set to nil. How can I do this? In general I need the information about nil fields. I dont know what is the better approach to unmarshal. I have to set these fields to null.
JAXB provides two settings that may help you: generateElementProperty
and generateIsSetMethod
.
From the JAXB Spec, the generateElementProperty="true"
will generate properties that return JAXBElement
, unless overriden by <jaxb:property generateElementProperty="false"/>
on individual properties.
And when generateIsSetMethod="true"
then additional methods such as isSetFoo()
are generated.
By setting generateElementProperty="true"
, each "getter" returns a JAXBElement
type that 1) wraps the actual value in a JAXBElement
method named value()
and 2) provides a JAXBElement
method named isNil()
that returns true
when the XML instance declares an "xsi:nil" attribute on the element. The downside is that you need to use getFoo().value()
to reference the actual value.
Alternatively, you can set generateIsSetMethod="true"
to tell the XJC engine to generate methods like isSetFoo()
that return true
when the field is not set during unmarshaling. One thing to be aware of is that the XJC engine may produce a "getter" that returns a default value when the field is not set. The 'isSetFoo()
method tests the field and not "getter".
Note: One other approach, shown in Nothing, uses a
DocumentBuilderFactory
fromjavax.xml.parsers
to parse the XML into aDocument
instance that can be passed intojaxbContext.createBinder().unmarshal(doc, Nothings.class)
to unmarshal the XML. The difference, is the use of a JAXBBinder
instance to do the unmarshalling. This provides a method to get the XML element associated with any of your generated objects. You can loop over the element's children to get the actualxsi:nil
attribute associated with each property usingchildElement.getAttributeNS(W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil")
Here's the schema and XML I used for my experimenting, see also HiSrc HigherJAXB Text Nothing that uses these settings:
nothing.xjb
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings jaxb:version="3.0"
xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>
<!-- Global Bindings -->
<jaxb:globalBindings generateElementProperty="true" generateIsSetMethod="true" >
<jaxb:serializable uid="20250501" />
</jaxb:globalBindings>
</jaxb:bindings>
And here is the XML schema that tghe binding file references:
nothing.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="unqualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
jaxb:version="3.0"
xmlns:tns="urn:example.org:nothing"
targetNamespace="urn:example.org:nothing"
>
<xs:element name="Nothing">
<xs:complexType>
<xs:sequence>
<xs:element name="optionalNillableString" type="xs:string" minOccurs="0" nillable="true"/>
<xs:element name="requiredNillableString" type="xs:string" minOccurs="1" nillable="true"/>
<xs:element name="optionalNillableStrings" type="xs:string" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
<xs:element name="requiredNillableStrings" type="xs:string" minOccurs="1" maxOccurs="unbounded" nillable="true"/>
</xs:sequence>
<xs:attribute name="id" type="xs:int" />
</xs:complexType>
</xs:element>
<xs:element name="Nothings">
<xs:complexType>
<xs:sequence>
<xs:element ref="tns:Nothing" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
And here is an XML sample file that can be unmarshaled and marshaled to see the effects of changing the global settings:
<?xml version="1.0" encoding="UTF-8"?>
<no:Nothings
xmlns:no="urn:example.org:nothing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:example.org:nothing ../../main/resources/nothing.xsd"
>
<no:Nothing id="101">
<optionalNillableString xsi:nil="true"/>
<requiredNillableString xsi:nil="true"/>
<optionalNillableStrings xsi:nil="true"/>
<optionalNillableStrings xsi:nil="true"/>
<requiredNillableStrings xsi:nil="true"/>
<requiredNillableStrings xsi:nil="true"/>
</no:Nothing>
<no:Nothing id="102">
<optionalNillableString xsi:nil="false"/>
<requiredNillableString xsi:nil="false"/>
<optionalNillableStrings xsi:nil="false"/>
<optionalNillableStrings xsi:nil="false"/>
<requiredNillableStrings xsi:nil="false"/>
<requiredNillableStrings xsi:nil="false"/>
</no:Nothing>
<no:Nothing id="103">
<optionalNillableString/>
<requiredNillableString/>
<optionalNillableStrings/>
<optionalNillableStrings/>
<requiredNillableStrings/>
<requiredNillableStrings/>
</no:Nothing>
<no:Nothing id="104">
<requiredNillableString/>
<requiredNillableStrings/>
</no:Nothing>
<no:Nothing id="105">
<optionalNillableString>ONS01</optionalNillableString>
<requiredNillableString>RNS01</requiredNillableString>
<optionalNillableStrings>ONSS01</optionalNillableStrings>
<optionalNillableStrings>ONSS02</optionalNillableStrings>
<optionalNillableStrings xsi:nil="true"/>
<optionalNillableStrings xsi:nil="false"/>
<requiredNillableStrings>RNSS01</requiredNillableStrings>
<requiredNillableStrings>RNSS02</requiredNillableStrings>
<requiredNillableStrings xsi:nil="true"/>
<requiredNillableStrings xsi:nil="false"/>
</no:Nothing>
</no:Nothings>