Hi Anne,

Sorry for my slow response - I wanted to spend some time playing with the settings and code to see if I could make some headway.

I have, now, two solutions to this particular problem, which I'll detail here for the purposes of list archive:

1) Switching from doc/lit to rpc/lit and rebuilding client and server code with WSDL2Java immediately solves the problem.

This is done by switching/inserting 'style="rpc"' into the binding declaration:

<soap:binding transport="http://schemas.xmlsoap.org/soap/http"; style="rpc" />

and leaving 'use="literal"' in the soap:body declaration.

I had not understood that "signature" in the frame of a web service is defined by the body, and that in doc/lit form that this "signature" is different to the way that signature is traditionally defined in OOP. It appears that using rpc/lit recovers the more traditional definition of signature.

2) The operation that is called can be specified as a soapAction and passed in the HTTP header in doc/lit form. My WSDL did not define a default soapAction, but the addition of the relevant attribute, along with a rebuild of all the client and server code does the job. So here is a snippet from the WSDL which uses doc/lit, but which can distinguish between different operations at the end of the service while using the same soap body:

<soap:binding transport="http://schemas.xmlsoap.org/soap/http"; style="document" />
<wsdl:operation name="RequestFileDetails">
  <soap:operation soapAction="RequestFileDetails"/>
    <wsdl:input>
      <soap:body use="literal" />
    </wsdl:input>
    <wsdl:output>
      <soap:body use="literal" />
    </wsdl:output>
</wsdl:operation>

According to your WSDL, you have five request messages that have
identical signatures:
- ArticleUpdateNotificationRequest
- UnsetLicenseRequest
- ViewLicenseRequest
- LicenseStatusRequest
- RequestFileDetailsRequest

A SOAP message signature is determined by the child element of the
<soap:Body>. When using document style, that message signature element
is the element referenced in the <wsdl:part> definition.

This is what scuppered me. In doc/lit, the message names are basically irrelevant unless you specify a soapAction. I would say this is very counter intuitive, since the traditional definition of the signature would include at least the operation name, as well as the parameters.

But you have four other request messages that look exactly the same.
There is absolutely no way for Axis to determine which operation you
want to invoke, therefore it always invokes the first operation.  So
as I said in my first response, you must define unique signatures for
each operation -- that means that each operation request message must
reference a unique element name in its message part.

Although there actually is a way for Axis to determine which operation you want to invoke, which is to do exactly what it does do when you specify a soapAction, and look in the HTTP headers.

I recommend that you define a type called "singleGuidType" and then
define five separate elements, each with a name corresponding to the
method name, e.g.:

<xsd:complexType name="singleGuidType">
  <xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="guid" type="xsd:string"/>
  </xsd:sequence>
</xsd:complexType>

<xsd:element name="ArticleUpdateNotification" type="singleGuidType"/>

<wsdl:message name="ArticleUpdateNotificationRequest">
    <wsdl:part element="tns:ArticleUpdateNotification"
          name="body"/>
</wsdl:message>

I think this is overly complicated, and misses the crux of the problem, since the addition of the relevant soapAction did the job.

The problem that I encountered was due to a number of factors: first (and foremost), I was fairly clueless about how the deep internals of Axis worked with regard to mapping requests onto operations; second, that doc/lit when implemented using axis does not behave as you might expect (i.e. in this situation, it would probably make more sense for WSDL2Java to throw an error if no soapAction is defined, or at least generate a warning); and third that Eclipse web tools doesn't enforce, or recommend the addition of the relevant soapAction in the UI.

Anyway, I don't want to be a bad workman blaming his tools, so really it's down to me not understanding doc/lit fully before using it. Hopefully this post will help other people who get confused about the same thing ;)

Thanks for all your help,

Richard


>> I am starting to really get to grips with my web services now, with much
>> thanks to Axis.  This morning, though, I have encountered a problem
>> which I can't work out whether is my fault (likely) or a potential
>> problem.
>>
>> I have two requests defined (in the scope of this problem):
>>
>> public void requestFileDetails(String guid)
>>    throws ServiceException, RemoteException
>> {
>>    // make the request
>>    SpiralTestSoapService service = getService();
>>    SingleGUID sguid = new SingleGUID(guid);
>>    RequestFileDetailsResponse response =
>>      service.requestFileDetails(sguid);
>> }
>>
>> public void articleUpdateNotification(String guid)
>>    throws ServiceException, RemoteException
>> {
>>    // make the request
>>    SpiralTestSoapService service = getService();
>>    SingleGUID sguid = new SingleGUID(guid);
>>    service.articleUpdateNotification(sguid);
>> }
>>
>> these in turn call the relevant operations on the port type (The
>> xxx_BindingImpl class).
>>
>> When either of the above methods are called in the client, the server
>> /always/ processes the request to "requestFileDetails".  I discovered
>> that I could fix this so that it always processed the request to
>> "articleUpdateNotification" by reversing the order that these two
>> operations are specified in the server-config.wsdd:
>>
>> <operation name="articleUpdateNotification"
>>      qname="ArticleUpdateNotification" mep="oneway" >
>>    <parameter qname="pns:SingleGUID"
>> xmlns:pns="http://[...]/SpiralWebService/"; type="tns:>SingleGUID"
>>        xmlns:tns="http://[...]/SpiralWebService/"/>
>> </operation>
>> <operation name="requestFileDetails" qname="RequestFileDetails"
>>      returnQName="retNS:RequestFileDetailsResponse"
>>      xmlns:retNS="http://[...]/SpiralWebService/";
>>      returnType="rtns:>RequestFileDetailsResponse"
>>      xmlns:rtns="http://[...]/SpiralWebService/"; >
>>    <parameter qname="pns:SingleGUID"
>>        xmlns:pns="http://[...]/SpiralWebService/";
>>        type="tns:>SingleGUID"
>>        xmlns:tns="http://[...]/SpiralWebService/"/>
>> </operation>
>>
>> I upped log4j to DEBUG, and observed that the body of the request seems
>> only to contain the data type, not the operation name:
>>
>> 2006-08-11 12:39:00,795 DEBUG org.apache.axis.providers.java.RPCProvider
>> @ body is <SingleGUID xmlns="http://[...]/SpiralWebService/";><guid
>> xmlns="">1234567890</guid></SingleGUID>
>>
>> The two above methods both take the SingleGUID data type as an argument,
>> so I defined this type in the WSDL and re-used it all over the place.
>> My current guess (and it is only a guess) is that Axis is just looking
>> for the first operation that takes this data type, and executing it, no
>> matter which operation it was intended for.
>>
>> Can anyone see what I might have done wrong? Am I misappropriating the
>> data types and the way that axis uses them, or have I missed something
>> in the way to call the web service, or is there something else?
>>
>> Any help much appreciated,
>>
>> Cheers

--
Richard
-------
Richard Jones
Web and Database Technology Specialist
Imperial College London
t: +44 (0)20 759 41815
e: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to