I'm trying to realize an XML mapping involving an HashMap. Here is my use case : I want to get this :
<userParameters>
<KEY_1>VALUE_1</KEY_1>
<KEY_2>VALUE_2</KEY_2>
<KEY_3>VALUE_3</KEY_3>
</userParameters>
My UserParameters class looks like this :
@XmlRootElement
public class UserParameters {
private final Map<QName, String> params = new HashMap<>();
@XmlAnyElement
public Map<QName, String> getParams() {
return params;
}
}
I get the following error while marshalling :
Caused by: javax.xml.bind.JAXBException: class java.util.HashMap nor any of its super class is known to this context.
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:593)
at com.sun.xml.bind.v2.runtime.property.SingleReferenceNodeProperty.serializeBody(SingleReferenceNodeProperty.java:109)
... 54 more
It works fine with @XmlAnyAttribute
and I get : <userParameters KEY_1="VALUE_1" ... />
From the answers I saw, it seems like I have to make my own XmlAdapter
but it feels like overkill for such a simple and common need.
--- UPDATE ---
I found a promising solution here : JAXB HashMap unmappable
The only inconvenient is that it seems to mess up the namespaces.
Here is my new UserParameters class :
@XmlAnyElement
public List<JAXBElement> getParams() {
return params;
}
public void addParam(String key, String value) {
JAXBElement<String> element = new JAXBElement<>(new QName(key), String.class, value);
this.params.add(element);
}
And here is what I get in my XML output :
<params:userParameters>
<KEY_1 xmlns="" xmlns:ns5="http://url.com/wsdl">
VALUE_1
</KEY_1>
</params:userParameters>
I have no idea why JAXB is declaring a namespace in the KEY_1 element.
@XmlAnyAttribute
vs @XmlAnyElement
With attributes it is clear that the map key is the attribute name and that the map value is the attribute value. With elements it is not so clear, the map key could be the element name, but what is the value the entire element? What happens if the key and the value don't match.
You need to use an XmlAdapter
for this use case. Below is an example of how it can be done using EclipseLink JAXB (MOXy), I'm the MOXy lead:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With