I created a test method that simply had one IN parameter that was the HashMap. Inside the method, I logged the keys and values that were passed to me...
Java
@WebMethod
public void testMethod(
@WebParam(mode = WebParam.Mode.IN, name = "map")
@XmlElement(required = true) HashMap inputMap)
{
LOG.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
Set keys = inputMap.keySet();
for (Object key : keys) {
LOG.info(">> " + key + " = " + inputMap.get(key));
}
LOG.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
}
This was the kind of output being produced...
Debug Output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>> [key: null] = [value: null]
>> [key: null] = [value: null]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
When I looked into the XSDs associated with the WSDL generated for the web service, I noticed something strange, the key and value had xsd:anyType for its data type.
XSD
<xsd:element name="map">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="entry" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="key" type="xsd:anyType" minOccurs="0"/>
<xsd:element name="value" type="xsd:anyType" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
This made be look at my WebMethod again. I realised that the HashMap was defined as untyped. Once I changed the definition to specify <String,String> as the key/value types the whole thing started to behave as expected.
The output became...
Debug Output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>> key2 = value2
>> key1 = value1
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
The XSD also changed to...
XSD
<xsd:element name="map">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="entry" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="key" type="xsd:string" minOccurs="0"/>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
The type="xsd:string" is what's important here. Looks like JAX-WS cannot process HashMaps that are not typed. Once an explicit type is specified, everything works correctly.
So in a nutshell, if using a HashMap in your WebMethod, be sure to type it correctly. In the end I changed my WebMethod definition to this:
Java
@WebMethod
public void testMethod(
@WebParam(mode = WebParam.Mode.IN, name = "map")
@XmlElement(required = true) HashMap<String, String> inputMap)
{
...
}
-i