2009-11-17 3 views
5

Je tente d'accéder à un service Web en utilisant SOAP via Perl et j'ai des problèmes pour appeler les fonctions du service qui nécessitent des paramètres. Le XSD qui dicte l'appel SOAP dit,Fonctions d'appel avec des paramètres utilisant SOAP avec 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> 

Selon la documentation pour le service, les signatures pour les deux fonctions sont:

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

Je suis en mesure d'appeler la première fonction, ce qui nécessite aucun paramètre d'entrée, à l'aide:

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

... mais ma tentative (ci-dessous) à appeler une fonction avec des paramètres en changeant la ligne 11 sur ont été vains.

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

Qu'est-ce que je fais mal qui me empêche d'appeler des fonctions du service avec des paramètres?


Edit: Voici l'exemple de code mis à jour avec l'aide de 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 
); 

Répondre

5

Utilisez SOAP::WSDL pour consommer le wsdl de service, il a également maréchaux de et (éventuellement) aux données de perl plaine structures pour vous. Module hautement recommandé.

Quelque chose comme ce qui suit:

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

-je faire cela, mais je suis dit, « ne peut pas namespace importer ... sans uri de base. Utilisez> parse_uri < or > set_uri

+0

J'ai un problème semblable, et j'ai essayé cette solution, et les paramètres ne font tout simplement pas à la demande sortante http://stackoverflow.com/questions/1765248 – aidan

+0

Pouvez-vous Fournir le service et les URL WSDL pour le test? Ce qui précède fonctionne pour beaucoup de services –

0

Vous pouvez essayer d'utiliser SOAP :: Lite si vous rencontrez des problèmes avec le WSDL:

rappelez-vous, vous pouvez toujours utiliser:

use SOAP::Lite qw(trace); 

pour voir le code XML exact que vous envoyez pour voir si vous êtes proche.

Je n'ai pas le temps de le tester, mais voici ma meilleure estimation du haut de ma tête:

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

Vous pouvez utiliser wsdl2perl.pl pour générer du code stub client de wsdl. Cela rend les choses assez faciles. wsdl2perl.pl fait partie de SOAP :: WSDL. Voici l'exemple de code après avoir généré le talon du client.

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. 
Questions connexes