我试图通过Perl使用SOAP访问Web服务,并且在调用需要参数的服务函数时遇到问题。决定SOAP调用的XSD说,
<xs:complexType name="getVersion">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="getVersionResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
...
<xs:complexType name="enumerateEntities">
<xs:sequence>
<xs:element name="entityId" type="xs:int"/>
<xs:element minOccurs="0" name="entityType" type="tns:entityType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="enumerateEntitiesResponse">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return" nillable="true" type="xs:int"/>
</xs:sequence>
</xs:complexType>
根据服务的文档,这两个函数的签名是:
String getVersion ()
int[] enumerateEntities (int entityId, EntityType entityType)
我能够使用:
调用第一个函数,该函数不需要输入参数#!/usr/bin/perl
use SOAP::Lite;
my $uri = 'http://wsdl.mydomain.com/';
my $service = SOAP::Lite
-> uri($uri)
-> on_action(sub { sprintf '"Call by on_action: %s"',shift})
-> proxy('http://192.168.1.100:8688/MyService/services/MyService.MyServicePort/');
$method = SOAP::Data->name("MyService")->attr({xmlns => $uri});
$getVersion = SOAP::Data->name("getVersion")->attr({xmlns=>$uri});#line 11
my $theResult = $service->getVersion;
unless ($theResult->fault){ print "Version: "; print $theResult->result;}
else {print $theResult->faultstring;}
...但是我通过更改第11行来调用带参数的函数的尝试(下面)是徒劳的。
...
@entityId = SOAP::Data->type('int')->name('entityId')->value(0);
@entityType = SOAP::Data->type('EntityType')->name('entityType')->value(NODE);
$enumerateEntities = SOAP::Data->name("enumerateEntities",@entityId,@entityType)->attr({xmlns=>$uri});
my $result2 = $service->enumerateEntities;
print $result2->result;
我做错了什么阻止我用参数调用服务的功能?
修改 这是使用SOAP :: WSDL
的更新示例代码#!/usr/bin/perl
use SOAP::WSDL;
use Data::Dumper;
my $service = SOAP::WSDL->new(
wsdl => 'http://192.168.1.100:8688/MyService/services/MyService.MyServicePort?wsdl',
outputhash => 1
);
答案 0 :(得分:5)
使用SOAP::WSDL来使用服务wsdl,它也可以为您提供和(可选)到普通perl数据结构的编组。强烈推荐的模块。
如下所示:
use SOAP::WSDL;
use Data::Dumper;
my $soap = SOAP::WSDL->new(
wsdl => 'http://server/pathtoservice?WSDL',
outputhash => 1
);
my $res = $soap->call('method', { foo => 1, bar =>2 });
die $res->faultstring if $res->fault;
print Dumper($res->result);
答案 1 :(得分:2)
您可以使用wsdl2perl.pl从wsdl生成客户端存根代码。这让事情变得非常简单。 wsdl2perl.pl是SOAP :: WSDL的一部分。以下是生成客户端存根之后的示例代码。
use MyInterfaces::SoapImplService::SoapPort;
my $soap = MyInterfaces::SoapImplService::SoapPort->new();
#calling method createRecipient which takes 2 parameterss:
#1. Complex type : recipient
#2. Complex type : authentication
my $response=$soap->createRecipient( { # MyTypes::createRecipient
recipient => { # MyTypes::Recipient
address => "test701\@test.com", # string
externalID => "test701\@test.com", # string
sourceDescription => "testing perl", # string
demographics => { # MyTypes::StringCollection
},
},
},,
{ # MyTypes::authentication
username=>'testuser' , password=>'pass'
},,
);
#you can find example code of calling every function in your "MyInterfaces\SoapImplService\SoapPort.pm" file.
答案 2 :(得分:0)
如果您遇到WSDL问题,可以尝试使用SOAP :: Lite:
记住,你总是可以使用:
use SOAP::Lite qw(trace);
查看您发送的确切XML,以了解您的距离。
我没有时间对此进行测试,但这是我最好的猜测:
my $soap = SOAP::Lite
-> uri($uri)
-> on_action(sub { sprintf '"Call by on_action: %s"',shift})
-> proxy('http://192.168.1.100:8688/MyService/services/MyService.MyServicePort/');
my $id = SOAP::Data->type('int')->name('entityId')->value(0);
my $type= SOAP::Data->type('EntityType')->name('entityType')->value(NODE);
$soap->enumerateEntities($id, $param);