Вызов функций с параметрами с помощью SOAP с Perl
Я пытаюсь получить доступ к веб-сервису, используя SOAP через Perl, и у меня возникают проблемы с вызовом функций сервиса, которые требуют параметров. XSD, который диктует вызов SOAP, говорит:
<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
);
3 ответа:
Используйте 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);
Вы можете использовать wsdl2perl.pl для генерации клиентского стаб-кода из wsdl. Это делает вещи довольно легкими. wsdl2perl.pl входит в состав мыла:: 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.
Вы можете попробовать использовать SOAP:: Lite, Если у вас возникли проблемы с WSDL:
Помните, что вы всегда можете использовать:
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);