Loading ...
Sorry, an error occurred while loading the content.

Re: [soaplite] sending xsd:complexType in SOAP request

Expand Messages
  • Craig Dunigan
    I m pretty sure stubmaker.pl can t handle complex types. To pass a complex type, you ll actually have to pass your array as the complex type name required by
    Message 1 of 5 , Feb 4 7:43 AM
    • 0 Attachment
      I'm pretty sure stubmaker.pl can't handle complex types. To pass a
      complex type, you'll actually have to pass your array as the complex
      type name required by the method with a value of a ref to a
      SOAP::Data->value encapsulating your array, and not just a parameter
      to the method. It's also important to remember that the method name
      is *not* the name of the complex type required in the request doc.
      That is, try to think more of the request as a document that you pass
      to a service name, not as the parameter of a remote method call. The
      request doc contains a named complex type, and that doc is passed to a
      named service, and you need both names.

      It's probably better illustrated as code:

      my $ds = new AmazonSearchService;
      my @complextype = (SOAP::Data->name("author" => "Mann"),
      SOAP::Data->name("page" => "1"),
      SOAP::Data->name("mode" => "just"),
      SOAP::Data->name("tag" => "a"),
      SOAP::Data->name("type" => "try"),
      SOAP::Data->name("devtag" => "...")
      );
      # Amazon's AuthorSearchRequest method accepts a complex type named "AuthorRequest"
      # which is not the same as the method name "AuthorSearchRequest"
      $som = $ds->AuthorSearchRequest("AuthorRequest" => \SOAP::Data->value(@complextype));


      where ' "AuthorRequest" => \SOAP::Data->value(@complextype) ' is the
      request document, and ' $ds->AuthorSearchRequest ' is the service
      name that document is being passed to.



      I learned this from:

      http://tardate.blogspot.com/2007/02/complex-soaplite-requests-my-rules-for.html

      which is the first link on:

      http://www.soaplite.com/

      and from a quick search for "AuthorSearchRequest", which turned up a
      number of links telling me what the format of the request document
      should be (most especially, the name of the required complex type).

      And yes, that does mean you have to nest refs if you have a
      multi-level complex type. Oh, and if the service you're talking to
      can't handle SOAP::Lite's autotyping (.Net comes to mind), you'll have
      to explicitly "turn off" autotyping by adding ' type->("") ' to each
      of your 'SOAP::Data->name' and 'SOAP::Data->value' calls, like this:

      my @complextype = (SOAP::Data->name("author" => "Mann")->type(""),
      <snip>
      $som = $ds->AuthorSearchRequest("AuthorRequest" => \SOAP::Data->value(@complextype)->type(""));


      Hope this helps.

      --
      Craig Dunigan
      IS Technical Services Specialist
      Middleware - EIS - DoIT
      University of Wisconsin, Madison

      opinions expressed are my own, not the University's

      On Fri, 1 Feb 2008, Eric Bridger wrote:

      > I would not use stubmaker.pl since you are doing all the work
      > yourself it doesn't really give you anything.
      > The altermative (which I did once long ago) is to edit the
      > AmazonSearchSevice.pm generated by stubmaker.pl, search for your
      > method and edit it so it knows what complex type to expect. But the
      > code generated by stubmaker.pl can be cryptic.
      >
      > That's why you should try rolling your own connection to the Amazon
      > and then your code below should work.
      >
      > Eric
      >
      > On Feb 1, 2008, at 11:02 AM, Peter Hartmann wrote:
      >
      >> Hello,
      >>
      >> i have the following problem: I built the stubcode of the Amazon web
      >> services via "stubmaker.pl
      >> http://soap.amazon.com/schemas2/AmazonWebServices.wsdl". This WSDL
      >> requires complex types submitted in a request. I tried something like
      >>
      >> -------------------------------------------
      >> my $ds = new AmazonSearchService;
      >> my @complextype = (SOAP::Data->name("author" => "Mann"),
      >> SOAP::Data->name("page" => "1"),
      >> SOAP::Data->name("mode" => "just"),
      >> SOAP::Data->name("tag" => "a"),
      >> SOAP::Data->name("type" => "try"),
      >> SOAP::Data->name("devtag" => "...")
      >> );
      >> $som = $ds->AuthorSearchRequest(@complextype);
      >> -------------------------------------------
      >>
      >> to embed a complex type into the call; but what happens is that the
      >> types are added after the call:
      >>
      >> -------------------------------------------
      >> ...<soap:Body><typens:AuthorSearchRequest><AuthorSearchRequest
      >> xsi:nil="true" xsi:type="typens:AuthorRequest" /><page
      >> xsi:type="xsd:int">1</page><mode xsi:type="xsd:string">just</mode><tag
      >> xsi:type="xsd:string">a</tag><type
      >> xsi:type="xsd:string">try</type><devtag
      >> xsi:type="xsd:string">...</devtag></typens:AuthorSearchRequest></
      >> soap:Body>...
      >> -------------------------------------------
      >>
      >> does anybody know how to pass complex types in a method call?
      >>
      >> Thanks in advance,
      >> Peter
      >>
      >>
      >
      >
    • Peter Hartmann
      ... Ok, thanks for clearing this up. For those of you who want to pass complex types to a web service without dealing with the correct namespaces etc. by hand,
      Message 2 of 5 , Feb 5 12:24 AM
      • 0 Attachment
        Craig Dunigan wrote:
        > I'm pretty sure stubmaker.pl can't handle complex types.

        Ok, thanks for clearing this up.
        For those of you who want to pass complex types to a web service without
        dealing with the correct namespaces etc. by hand, you might want to try
        out SOAP::WSDL (http://soap-wsdl.sourceforge.net/ and
        http://search.cpan.org/~mkutter/SOAP-WSDL-2.00_29/lib/SOAP/WSDL.pm). It
        is still beta and returned an error when I tried to create code from the
        Amazon WSDL, but it is worth a try.

        Regards,
        Peter


        To pass a
        > complex type, you'll actually have to pass your array as the complex
        > type name required by the method with a value of a ref to a
        > SOAP::Data->value encapsulating your array, and not just a parameter to
        > the method. It's also important to remember that the method name is
        > *not* the name of the complex type required in the request doc. That is,
        > try to think more of the request as a document that you pass to a
        > service name, not as the parameter of a remote method call. The request
        > doc contains a named complex type, and that doc is passed to a named
        > service, and you need both names.
        >
        > It's probably better illustrated as code:
        >
        > my $ds = new AmazonSearchService;
        > my @complextype = (SOAP::Data->name("author" => "Mann"),
        > SOAP::Data->name("page" => "1"),
        > SOAP::Data->name("mode" => "just"),
        > SOAP::Data->name("tag" => "a"),
        > SOAP::Data->name("type" => "try"),
        > SOAP::Data->name("devtag" => "...")
        > );
        > # Amazon's AuthorSearchRequest method accepts a complex type named
        > "AuthorRequest"
        > # which is not the same as the method name "AuthorSearchRequest"
        > $som = $ds->AuthorSearchRequest("AuthorRequest" =>
        > \SOAP::Data->value(@complextype));
        >
        >
        > where ' "AuthorRequest" => \SOAP::Data->value(@complextype) ' is the
        > request document, and ' $ds->AuthorSearchRequest ' is the service name
        > that document is being passed to.
        >
        >
        >
        > I learned this from:
        >
        > http://tardate.blogspot.com/2007/02/complex-soaplite-requests-my-rules-for.html
        >
        >
        > which is the first link on:
        >
        > http://www.soaplite.com/
        >
        > and from a quick search for "AuthorSearchRequest", which turned up a
        > number of links telling me what the format of the request document
        > should be (most especially, the name of the required complex type).
        >
        > And yes, that does mean you have to nest refs if you have a multi-level
        > complex type. Oh, and if the service you're talking to can't handle
        > SOAP::Lite's autotyping (.Net comes to mind), you'll have to explicitly
        > "turn off" autotyping by adding ' type->("") ' to each of your
        > 'SOAP::Data->name' and 'SOAP::Data->value' calls, like this:
        >
        > my @complextype = (SOAP::Data->name("author" => "Mann")->type(""),
        > <snip>
        > $som = $ds->AuthorSearchRequest("AuthorRequest" =>
        > \SOAP::Data->value(@complextype)->type(""));
        >
        >
        > Hope this helps.
        >
      Your message has been successfully submitted and would be delivered to recipients shortly.