Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

SOAP::Lite:Java vs Perl

by mrguy123 (Hermit)
on May 26, 2008 at 12:47 UTC ( [id://688516]=perlquestion: print w/replies, xml ) Need Help??

mrguy123 has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,
I am trying to retrieve data from a web server using a SOAP API.
Unfortunately, all the examples are in Java :(
In the past I have managed to translate Java SOAP requests to Perl using SOAP::Lite, but I am quite stuck this time
These are the SOAP functions in Java:
##Connecting to the WSDL file Public myService As DialogSearch.SearchService = New _ DialogSearch.Se +archService ##Creating a session object Public mySession As DialogSearch.SessionStruct = New _ DialogSearch.S +essionStruct ##Updating the object parameters mySession.Account = “123456” mySession.Password = “xyzabc” mySession.Cost = 0 mySession.State=”START_SESSION” mySession.Atomic = True mySession.Interupt = False ##Sending the object as input to the Version function Dim myResult As DialogSearch.StringResult = _ MyService.Version(mySession)
I haven't used Java for a while, but it seems that you need to connect the the WSDL page, create a "session" object, and then send it as input to a one of the SOAP functions. I tried doing the same in Perl, using a hash instead of an object:
use strict; use warnings; use SOAP::Lite+trace=> 'debug'; { ##Connecting to the SOAP API my $request = SOAP::Lite->service('http://searchapi2.dialog.com/ax +is/DialogSearch.wsdl'); ##The session object with parameters my $session = {}; $session->{Account} = 'account'; $session->{Password} = 'pass'; $session->{State} = 'START_SESSION'; $session->{Cost} = 0; $session->{Atomic} = 'True'; $session->{Interupt} = 'False'; $session->{ProcessID} = ''; ##Calling the version function my $result = $request->Version($session); }
When I run this program, I get this XML message:
<faultcode>soapenv:Server.userException</faultcode> <faultstring>org.xml.sax.SAXException: Deserializing parameter &apo +s;Session&apos;: could not find deserializer for type SessionStruct< +/faultstring>
I'm not sure exactly what this means,but my guess is that the Server tries to use the XML to create an object and fails. I tried using a Perl Module instead of a hash as the "session" object but with the same results.
Right now, if you run this and look at the XML that is created, all the parameters from the hash are sent. It should be OK, but something is missing.
The bottom line is that I seem to need an object in Perl that is bit more similar to an object in Java for the XML.
Any suggestions?
Thanks,
Guy Naamati (mrguy123)


For the children, they mark, and the children, they know The place where the sidewalk ends. --Shel Silverstein

Replies are listed 'Best First'.
Re: SOAP::Lite:Java vs Perl
by Your Mother (Archbishop) on May 26, 2008 at 20:45 UTC

    SOAP::Lite is kind of... well, it's not so great in it's present state. I highly recommend checking out XML::Compile::SOAP. It is trivial to compile a WSDL (remote or stored locally for speed bump) and run SOAP requests from the operations it exposes. I've only used it to play around (as a model with Catalyst) but I was very impressed and the author is quite receptive to constructive feedback.

      how about an example for http://searchapi2.dialog.com/axis/DialogSearch.wsdl?

        Give this a spin. (I was wrong, you have to provide the file/XML, it won't do remote requests natively -- I think the Catalyst Model module does). You should be able to see what's going on and check the docs (and dive the dump info or the published human API if there is one) for how to make calls.

        use strict; use warnings; use Data::Dumper; $Data::Dumper::Terse = 1; use XML::Compile::WSDL11; use LWP::Simple; # use XML::LibXML; # might want this my $uri = shift || die "Give a WSDL URI!\n"; my $wsdl = LWP::Simple::get($uri) || die "Couldn't get $uri"; my $schema = XML::Compile::WSDL11->new($wsdl); print Dumper($schema), "\n"; print "OPERATIONS_______________________________\n"; for my $op ( sort { $a->{operation} cmp $b->{operation} } $schema->operations ) { print "\t", $op->{operation}, "\n"; }

        (update, added sort)

Re: SOAP::Lite:Java vs Perl
by Anonymous Monk on May 26, 2008 at 14:20 UTC
    stubmaker
      Thanks, checking it out
Re: SOAP::Lite:Java vs Perl
by Herkum (Parson) on May 27, 2008 at 17:34 UTC

    In your XML on the data types is declared to be 'SessionStruct'. There are a couple of default types that come with XML; string and integers to name two.

    SOAP::Lite comes with its own default parser, and this parser attempts to take your XML file and make it into a Hash. The problem is that it reads the type from the XML document and then calls a module to decode the data type for that XML element. When you have custom types, it does not know what to do and blows up.

    XML has some definition documents that help to identify and support these custom formats. The problem for SOAP::Lite is that it does not know how to read these definition documents. Java had alot more work put into it than Perl and so its SOAP utilities can read these definition documents and can handle stuff like this.

    What I ended up do is using SOAP::Lite to get the document and don't attempt to deserialize the document. Instead I used XML::Twig to parse my XML.

    Hope that helps

      Thanks for your answer

      Unfortunately the problem is not parsing the XML, but sending it. I don't get any XML back which I can parse. I think the XML is sent (I can see it in debug mode), but on the Server side it is not received correctly (can't deserialize). The question is whether this is a problem with SOAP::Lite or with the XML created by SOAP::Lite?

Re: SOAP::Lite:Java vs Perl
by rahed (Scribe) on May 31, 2008 at 15:00 UTC
    When I want to build a web service (client/server) with SOAP::Lite I first avoid using service method. So I constructed it like this with Data objects:
    use strict; use warnings; use Data::Dumper; my ($soap,$data,$result,$session); use SOAP::Lite+trace=> 'debug'; { ##Connecting to the SOAP API $soap = SOAP::Lite->new( 'proxy' =>('http://searchapi2.dialog.com/axis/services/D +ialogSearchPort'), ); $soap->default_ns('urn:DialogSearch'); $data = SOAP::Data ->name('Session'=>\SOAP::Data->value( SOAP::Data->name(Account=>'account')->type(''), SOAP::Data->name(Password=>'pass')->type(''), SOAP::Data->name(State=>'START_SESSION')->type('' +), SOAP::Data->name(Cost=>0)->type(''), SOAP::Data->name(Atomic=>'True')->type(''), SOAP::Data->name(Interrupt=>'False')->type(''), SOAP::Data->name(ProcessId=>'')->type(''), ), ); $result = $soap->Version($data); }
    It returns:
    <ErrorMessage xsi:type="xsd:string">Invalid user id = account</ErrorM +essage>
    I had to exclude type definitions from xml because the server returned IllegalArgumentException error.
    hth

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://688516]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (9)
As of 2024-03-28 09:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found