随笔-124  评论-194  文章-0  trackbacks-0

SOAP::Lite的Lite是说其好用,其实它的实现并不“轻量”,功能也非常强大,所以我们要用好它。

在调用服务时,有时遇到有复杂结构或者数组时,还是有点小麻烦,下面以调用以下三个函数为例分别写出SOAP::Lite如何组合它们的参数,其它情况也应该能迎刃而解。

public class DeviceValue {
    
private String devName;
    
private String devIp;
    
    
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;
    }


}

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


SOAP::Lite调用及处理返回参数的代码如下,对照相应函数及PERL中的处理来看:
use SOAP::Lite ( +trace => all, maptype => {} );

my $soap = SOAP::Lite
       
-> uri('http://magic.nms.exchangebit.com/')
       
-> on_action( subjoin '/', 'http://www.alfredbr.com', $_[1] })
       
-> proxy('http://127.0.0.1:8080/ebnms/NotifyService');

my $header = SOAP::Header->name(MyHeader => {
     MyName 
=> "Alfred"
})
->uri('http://www.alfredbr.com/')->prefix('');


{
# call send alarm
    my @params = (
    
#   $header,
       SOAP::Data->name(x1 => goodhehe) 
    );
    
    
my $method = SOAP::Data->name('sendAlarmString');
    
#   ->attr({xmlns => 'http://www.alfredbr.com/'});
    
    
my $result = $soap->call($method => @params);
    
    
print "\nsend string alarm result:\n";
    
if ($result->fault)
    {
       
print $result->faultstring;
    }
    
else
    {
       
print $result->result;
    }
    
print "\nn";
}

{
# call send dev alarm
    my @params = (
       SOAP
::Data->name(x1 => {devName=>"hehe", devIp=>"ip1"})
    );
    
    
my $method = SOAP::Data->name('sendAlarm');
    
    
my $result = $soap->call($method => @params);
    
    
print "\nsend string alarm result:\n";
    
if ($result->fault)
    {
       
print $result->faultstring;
    }
    
else
    {
       
print $result->result;
    }
    
print "\n\n";
}


{
# call send arr alarm
    my @params = (
       SOAP
::Data->name(x1 => [
       {devName
=>"hehe1", devIp=>"ip1"}, 
       {devName
=>"hehe2", devIp=>"ip2"}])
    );
    
    
my $method = SOAP::Data->name('sendAlarmArr');
    
    
my $result = $soap->call($method => @params);
    
    
print "\nsend string alarm result:\n";
    
if ($result->fault)
    {
       
print $result->faultstring;
    }
    
else
    {
       
my @a = @{$result->result->{item}};
       
foreach $i (@a) {
               
print "ele: $i->{devName}, $i->{devIp}\n";
       }
    }
    
print "\n\n";
}



其中,尤其PERL会将HASHMAP“翻译”成结构,其中的KEY和VALUE就是结构的成员及值;另外,处理参数为结构数组及返回值也是数组的情况。组装时要用“[]”括起来,返回值要转换成数组指针再处理,下面是打印出来的请求、回应及函数输出:

请求:

<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:xsi="http://www.w3.or
g/2001/XMLSchema-instance"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encodi
ng/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://sch
emas.xmlsoap.org/soap/encoding/"
 xmlns:soap="http://schemas.xmlsoap.org/soap/env
elope/"
><soap:Body><sendAlarmArr><x1 soapenc:arrayType="xsd:anyType[2]" xsi:type
="soapenc:Array"><item><devName xsi:type="xsd:string">hehe1</devName><devIp xsi:
type
="xsd:string">ip1</devIp></item><item><devName xsi:type="xsd:string">hehe2</
devName
><devIp xsi:type="xsd:string">ip2</devIp></item></x1></sendAlarmArr></soa
p:Body
></soap:Envelope>



应答:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body
><sendAlarmArrResponse xmlns="http://magic.nms.exchangebit.com/"><ns2:return xml
ns:ns2
="http://magic.nms.exchangebit.com/"><item><devIp>ip0</devIp><devName>name
0
</devName></item><item><devIp>ip1</devIp><devName>name1</devName></item><item><
devIp
>ip2</devIp><devName>name2</devName></item><item><devIp>ip3</devIp><devName
>name3</devName></item><item><devIp>ip4</devIp><devName>name4</devName></item><i
tem><devIp>ip5</devIp><devName>name5</devName></item><item><devIp>ip6</devIp><de
vName>name6</devName></item><item><devIp>ip7</devIp><devName>name7</devName></it
em
><item><devIp>ip8</devIp><devName>name8</devName></item><item><devIp>ip9</devI
p
><devName>name9</devName></item></ns2:return></sendAlarmArrResponse></soap:Body
></soap:Envelope>


函数输出:
send string alarm result:
ele: name0, ip0
ele: name1, ip1
ele: name2, ip2
ele: name3, ip3
ele: name4, ip4
ele: name5, ip5
ele: name6, ip6
ele: name7, ip7
ele: name8, ip8
ele: name9, ip9
 
参考:
How to Call a .NET-based Web Service Using the SOAP::Lite Perl Library



补充于2007.10.15:
另一法:

Consume a remote procedure returning arrays with SOAP::Lite

A little more difficult now, how to parse arrays returned by web service with SOAP::Lite. We will have to use a technique similar to XPath to read the value returned in the SOAP message. The remote procedure consumed here are collInt() (returning an array of int) and collPos() (returning an array of PosCol object). The PosCol class contain just two simple int variable XPos and YPos. Let's see how to handle these cases:


# Again, no param here so we make the call
my $resultci = $client->collInt();
my $resultcp = $client->collPos();

print "<p><b>Method collInt():</b> return an array of int<br>";

# To understand this code we have to know the structure of
# the SOAP message (the response) returned by the web service
# If you take a look at the wsdl, you will find for the operation
# collInt the complex type collIntResponse, composed with an array
# of result (int) element.
# Another way is to build a classic client with your preferred language
# and catch the SOAP message returned by the web service, see
# TcpTunnelGui tool. So you know
# exactly the structure of the values.

my @intarr = $resultci->valueof('//collIntResponse/result');

# A simple foreach read the array
foreach my $intval (@intarr) {
  
print "elem: $intval<br>";
}

# Use the same method to parse the array of PosCol object
print "<p><b>Method collPos():</b> return an array of object <u>PosCol</u><table>";

my @poscolarr = $resultcp->valueof('//collPosResponse/result');
foreach my $pcval (@poscolarr) {
  
print "<tr><td>object -> </td>";

  
# Here, for each object you can list the key/value elements
  # using usual Perl code

  foreach my $keyval (keys %{$pcval}) {
    
print "<td>$keyval: </td><td>" . $pcval->{$keyval. "  </td>";
  }
  
print "</tr>";
}
print "</table>";

参考了:这里
posted on 2007-08-03 22:37 我爱佳娃 阅读(2843) 评论(0)  编辑  收藏 所属分类: Perl

只有注册用户登录后才能发表评论。


网站导航: