HashMap JAXB mapping using @XmlAnyElement

Viewed 2993

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.

1 Answers
Related