2009-11-17 11 views
5

Estoy intentando acceder a un servicio web utilizando SOAP a través de Perl y tengo problemas para llamar a las funciones del servicio que requieren parámetros. El XSD que dicta la llamada SOAP dice,Llamando funciones con parámetros utilizando SOAP con 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> 

De acuerdo con la documentación para el servicio, las firmas para las dos funciones son:

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

soy capaz de llamar a la primera función, que requiere no hay parámetros de entrada, utilizando:

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

... pero mi intento (abajo) a llamar a una función con parámetros cambiando la línea 11 en adelante han sido inútiles.

... 
@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é estoy haciendo mal que me impide llamar funciones del servicio con parámetros?


Editar: Aquí está el código de ejemplo actualizado con el uso 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 
); 

Respuesta

5

Uso SOAP::WSDL para consumir el servicio WSDL, también mariscales de y (opcionalmente) a los datos Perl llanura estructuras para ti. Módulo altamente recomendado.

algo como lo siguiente:

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

que hacer esto, pero estoy dijo, "No se puede importar sin espacio de nombres ... URI base. Utilice> parse_uri < or > set_uri

+0

Tengo un problema similar, y he intentado con esta solución, y los parámetros simplemente no llegan a la solicitud saliente. Http://stackoverflow.com/questions/1765248 – aidan

+0

suministrar el servicio y las URL WSDL para probar? Lo anterior funciona para mí contra muchos servicios –

0

Puedes probar a utilizar SOAP :: Lite si está teniendo problemas con el WSDL:

recordar, siempre se puede utilizar:

use SOAP::Lite qw(trace); 

para ver el XML exacto que está enviando para ver qué tan cerca está.

no tengo tiempo para probar esto, pero aquí es mi mejor estimación de la parte superior de mi cabeza:

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

Se puede utilizar para generar código wsdl2perl.pl resguardo del cliente a partir de WSDL. Esto hace las cosas bastante fáciles. wsdl2perl.pl es parte de SOAP :: WSDL. Aquí está el código de muestra después de generar el código auxiliar del cliente.

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. 
Cuestiones relacionadas