A simple^W dumb Map wrapper to use with JAXB
I sometimes need to use java.util.Map objects in WebServices. As I’m building all my WebServices with the JAX-WS RI (using the Metro bundle). The block responsible for XML (un)marshalling of POJO, named JAXB, does not allows to directly use Maps as a soap operation parameter. For this purpose I’ve written the following simple class that allows me to wrap Maps in a POJO that JAXB is able to (un)marshall :
public class JAXBMapWrapper<KT, VT> {
private Map<KT, VT> wrappedMap;
public JAXBMapWrapper() {
wrappedMap = new HashMap<KT, VT>();
}
public Map<KT, VT> getWrappedMap() {
return wrappedMap;
}
public void setWrappedMap(final Map<KT, VT> givenMap) {
wrappedMap = givenMap;
}
}
ATTENTION: I posted this some days ago and removed the post after understanding that this is simpler on the service side but that the client side gets cumbersome generated classes.. but google cache indexed the post in less than half a day.
Just don’t use this ! :) If you need to transmit Maps over JAX-WS webservices, do it the XmlAdapter way as advertised in the official Unofficial JAXB Guide instead.

Hi,
Thanks for the tip. I found the suggestion at jaxb.dev.java.net to be a bit inelegant, specially on the service side since I would like to utilize the fact that a Map is type generic.
Here is a version using generics instead (instead of Object as suggested in the guide):
/**
* A HashMap understandable for JAXB, see https://jaxb.dev.java.net/issues/show_bug.cgi?id=223.
* @author Martin Lansler
*/
public class WSMap {
public List<WSMapEntry> entries = new ArrayList<WSMapEntry>();
public WSMap(Map map) {
for (Map.Entry e : map.entrySet()) {
entries.add(new WSMapEntry(e));
}
}
public WSMap() {
}
public Map getMap() {
Map map = new HashMap();
for (WSMapEntry e : entries) {
map.put(e.getKey(), e.getValue());
}
return map;
}
}
/**
* An entry for {@link WSMap}.
* @author Martin Lansler
*/
public class WSMapEntry {
private K key;
private V value;
public WSMapEntry(Entry e) {
this.key = e.getKey();
this.value = e.getValue();
}
public WSMapEntry() {
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
}
Works fine.
Cheers,
Martin Lansler.
Martin Lansler
October 10, 2008 at 8:37 pm
Hi again,
To get a better name (i.e in singular) for the WSMapEntry in the WSDL file the following JAXB annotation can be added:
...
@XmlElement(name = "entry")
public List<WSMapEntry> entries = new ArrayList<WSMapEntry>();
...
/Martin
Martin Lansler
October 10, 2008 at 8:59 pm
Hi Martin,
Thanks for providing some code, I will try this as soon as possible.
Have you managed to use an XmlAdapter on the client side in order to get standard Map in the client stubs ? (Thinking about custom binding).
Paul
eskatos
October 11, 2008 at 3:46 pm
hello
i read ur blog after some googling… i having some prob realted to serialzation using JAxB in spring WS…
i post it on spring forum but till now not got any response i posting my prob there http://forum.springframework.org/showthread.php?t=64170
please can u check it and guide me
my e-mail is: mnomansadiq@hotmail.com m.noman@systemresearchltd.com(my Gmail)
that seem to very bad to refer u another area.. but i hope u take it serious and little bit guide me on my E-mail or on ur blog …. i waiting fr ur response
thanx
Nommi
December 1, 2008 at 9:25 am
Hi Nommi,
According to the thread on the spring forum, you found a solution :)
See ya
eskatos
December 1, 2008 at 11:15 am