SOAP中不支持HashMap,但可以通過(guò)適配器將數(shù)組轉(zhuǎn)換成HashMap的方式來(lái)支持。
這是通過(guò)JAXB2.0中一個(gè)適配器類(lèi)來(lái)轉(zhuǎn)換的,先看下這個(gè)類(lèi)的說(shuō)明:
javax.xml.bind.annotation.adapters
類(lèi) XmlAdapter<ValueType,BoundType>
javax.xml.bind.annotation.adapters.XmlAdapter<ValueType,BoundType>
- 類(lèi)型參數(shù):
BoundType
- JAXB 不知道如何處理的一些類(lèi)型。編寫(xiě)一個(gè)適配器,以便允許通過(guò) ValueType 將此類(lèi)型用作內(nèi)存表示形式。
ValueType
- JAXB 無(wú)需其他操作便知道如何處理的類(lèi)型。
這樣,我們先定義一個(gè)用來(lái)傳送數(shù)據(jù)的通用數(shù)組,包含了KEY和VALUE兩個(gè)成員用來(lái)存MAP的項(xiàng):

public class OtherValues
{

public OtherValues ()
{};

public OtherValues (String key, String value)
{
this.key = key;
this.value = value;
};
public String key;
public String value;
}

再定義一個(gè)轉(zhuǎn)換類(lèi):(數(shù)組到HashMap的轉(zhuǎn)換)
import java.util.HashMap;
import java.util.Map.Entry;
import org.apache.log4j.Logger;

import javax.xml.bind.annotation.adapters.XmlAdapter;


public class OtherValuesAdapter extends XmlAdapter<OtherValues[], HashMap<String,String>>
{
static Logger logger = Logger.getLogger (OtherValuesAdapter.class.getName());

public HashMap<String, String> unmarshal(OtherValues[] value )
{
logger.error("unmarshal begin");
HashMap<String, String> r = new HashMap<String,String>();
for( OtherValues c : value )
r.put(c.key, c.value);
return r;
}

public OtherValues[] marshal( HashMap<String,String> value )
{
logger.error("marshal begin");
OtherValues[] pairs = new OtherValues[value.size ()];
int i = 0;

for(Entry<String,String> entry : value.entrySet())
{
pairs[i++] = new OtherValues (entry.getKey(), entry.getValue());
}
return pairs;
}
}
我們需要在一個(gè)結(jié)構(gòu)中來(lái)包含使用HashMap的變量,因?yàn)楸仨殲檫@個(gè)變量再聲明一個(gè)
@XmlJavaTypeAdapter,這樣JAXB才會(huì)在收到相應(yīng)消息時(shí)調(diào)用我們的轉(zhuǎn)換類(lèi)。這是結(jié)構(gòu)定義:
import java.util.HashMap;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;


public class MapValue
{
private String devName;
private String devIp;

@XmlJavaTypeAdapter(OtherValuesAdapter.class)
public HashMap <String, String> otherValues;

public String getDevIp()
{
return devIp;
}

public void setDevIp(String devIp)
{
this.devIp = devIp;
}

public String getDevName()
{
return devName;
}

public void setDevName(String devName)
{
this.devName = devName;
}

}
最后,在SOAP服務(wù)的聲明中,使用這個(gè)結(jié)構(gòu):(注意是sendAlarmMap方法)
import java.util.List;

import javax.jws.*;
import javax.jws.soap.*;
import javax.jws.soap.SOAPBinding.*;

import java.util.HashMap;
import java.util.Map;

@WebService

public interface NotifyService
{
public int sendAlarm (DeviceValue alarm);
public String sendAlarmString (String stralarm);
public List<DeviceValue> sendAlarmArr (List<DeviceValue> arr);

public int sendAlarmMap (MapValue m);
}

下面,我們來(lái)看如何通過(guò)JAVA及PERL的方式調(diào)用這個(gè)服務(wù):
JAVA的方式:
NotifyService s = (NotifyService) getBean ("notifyClient");

MapValue mv = new MapValue ();
mv.otherValues = new HashMap<String, String> ();
mv.otherValues.put ("hehe2", "a");
mv.otherValues.put ("2", "b");

mv.setDevIp ("he");
mv.setDevName ("hehe2");
int r = s.sendAlarmMap(mv);
logger.info("recv: " + r);

PERL的方式:
{# call send map alarm
my @params = (SOAP::Data->name(arg0=>{
devName=>"hehe",
devIp=>"ip1",
otherValues=>[{
item => [
{key=>"hehe1", value=>"ip1"},
{key=>"hehe1", value=>"ip1"},
{key=>"hehe1", value=>"ip1"},
{key=>"hehe1", value=>"ip1"},
{key=>"hehe1", value=>"ip1"},
{key=>"hehe1", value=>"ip1"},
{key=>"hehe1", value=>"ip1"},
{key=>"hehe1", value=>"ip1"},
{key=>"hehe1", value=>"ip1"},
{key=>"hehe1", value=>"ip1"},
{key=>"hehe2", value=>"ip2"}]
}]
}));
my $method = SOAP::Data->name('sendAlarmMap');
my $result = $soap->call($method => @params);
print "\nsend map alarm result:\n";
if ($result->fault)
{
print $result->faultstring;
}
else
{
print $result->result;
}
print "\n\n";
}

產(chǎn)生的SOAP消息如下:
請(qǐng)求:
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><sendAlarmMap><arg0><devName>hehe</devName><otherValues><item><value>ip1</value><key>hehe1</key></item><item><value>ip1</value><key>hehe1</key></item><item><value>ip1</value><key>hehe1</key></item><item><value>ip1</value><key>hehe1</key></item><item><value>ip1</value><key>hehe1</key></item><item><value>ip1</value><key>hehe1</key></item><item><value>ip1</value><key>hehe1</key></item><item><value>ip1</value><key>hehe1</key></item><item><value>ip1</value><key>hehe1</key></item><item><value>ip1</value><key>hehe1</key></item><item><value>ip2</value><key>hehe2</key></item></otherValues><devIp>ip1</devIp></arg0></sendAlarmMap></soap:Body></soap:Envelope>


回應(yīng):
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:sendAlarmMapResponse xmlns:ns1="http://magic.nms.exchangebit.com/"><return>99</return></ns1:sendAlarmMapResponse></soap:Body></soap:Envelope>
總結(jié):
有了轉(zhuǎn)換器這個(gè)工具,我們可以在SOAP的JAXB綁定里支持各種JAVA的COLLECTION類(lèi)型,以及自定義類(lèi)型,打破了SOAP原始支持類(lèi)型的限制。
posted on 2007-10-29 16:41
我愛(ài)佳娃 閱讀(7226)
評(píng)論(5) 編輯 收藏 所屬分類(lèi):
web技術(shù)