2009-11-17 12 views
5

Próbuję uzyskać dostęp do usługi sieci Web przy użyciu protokołu SOAP przez Perl i mam problemy z wywołaniem funkcji usługi, które wymagają parametrów. XSD dyktuje wywołanie SOAP mówiWywołanie funkcji za pomocą parametrów przy użyciu protokołu SOAP z Perl

<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> 

Zgodnie z docs dla służby, podpisy dla dwóch funkcji są:

String getVersion() 
int[] enumerateEntities (int entityId, EntityType entityType) 

jestem w stanie połączyć się z pierwszą funkcję, która wymaga bez parametrów wejściowych, używając:

#!/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;} 

... ale moja próba (poniżej) wywołania funkcji z parametrami poprzez zmianę linii 11 była daremna.

... 
@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; 

Co robię źle uniemożliwiając mi wywoływanie funkcji usługi za pomocą parametrów?


Edit: Oto zaktualizowana przykładowy kod z użyciem mydła :: 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 
); 

Odpowiedz

5

Zastosowanie SOAP::WSDL zużywają WSDL usług, ale również marszałkowie z i (opcjonalnie) do zwykłego danych perla struktury dla ciebie. Wysoce zalecany moduł.

Coś jak następuje:

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); 
+0

mogę to zrobić, ale mi powiedziano, „Nie można zaimportować nazw ... bez podstawowego URI. Użyj> parse_uri < or > set_uri

+0

Mam podobny problem i próbowałem tego rozwiązania, a parametry po prostu nie trafiają do wychodzących żądań http://stackoverflow.com/questions/1765248 – aidan

+0

Czy możesz dostarczyć usługi i adresy URL WSDL do testowania? Powyższe działa dla mnie przeciwko wielu usługom –

0

Można spróbować użyć SOAP :: Lite, jeśli masz problemy z WSDL:

Pamiętaj, że zawsze możesz użyć:

use SOAP::Lite qw(trace); 

, aby zobaczyć dokładny kod XML, który wysyłasz, aby zobaczyć, jak blisko jesteś.

Nie mam czasu na przetestowanie tego na zewnątrz, ale tutaj jest mój najlepszy przypuszczenie przy mojej głowie:

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); 
2

Można użyć wsdl2perl.pl wygenerować skrótową klient kod z WSDL. To sprawia, że ​​wszystko jest łatwe. wsdl2perl.pl jest częścią SOAP :: WSDL. Oto przykładowy kod po wygenerowaniu kodu pośredniczącego klienta.

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. 
Powiązane problemy