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

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

Expand Messages
  • Eric Bridger
    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
    Message 1 of 5 , Feb 1, 2008
    • 0 Attachment
      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
      >
      >
    • 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 2 of 5 , Feb 4, 2008
      • 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 3 of 5 , Feb 5, 2008
        • 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.