Hi all
I'm having a problem properly putting a
parameter into a call to a document style webservice. I have a generic
client build in axis, the basics of while are demonstrated with the
following code extracts:
ServiceFactory serviceFactory =
ServiceFactory.newInstance();
Service webService =
serviceFactory.createService(wsdlUrl, serviceQName);
Call opCall = webService.createCall(portQName,
operationName);
Object response =
opCall.invoke(params);
The webservice I'm trying to call is a document
style, here are the parts of the wsdl relevant to the input
messages
<?xml version="1.0"
encoding="UTF-8"?>
<wsdl:definitions
targetNamespace="urn:TransactionTypesWs"
xmlns="urn:TransactionTypesWs"
xmlns:apachesoap="
http://xml.apache.org/xml-soap"
xmlns:impl="urn:TransactionTypesWs"
xmlns:intf="urn:TransactionTypesWs"
xmlns:soapenc="
http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/
"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="
http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema
targetNamespace="urn:TransactionTypesWs">
<!-- Input types -->
<xsd:element
name="Request">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="Type"
type="xsd:string"/>
<xsd:element minOccurs="1" maxOccurs="1" name="From"
type="xsd:string"/>
<xsd:element minOccurs="1" maxOccurs="1" name="Until"
type="xsd:string"/>
<xsd:element minOccurs="1" maxOccurs="1" name="Status"
type="xsd:string"/>
<xsd:element minOccurs="1" maxOccurs="1" name="ExtId"
type="xsd:string"/>
<xsd:element minOccurs="1" maxOccurs="1" name="ExtPwd"
type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!-- Output types
-->
...
</xsd:schema>
</wsdl:types>
<wsdl:message
name="getTransactionDetailsRequest">
<wsdl:part
name="req" element="impl:Request"/>
</wsdl:message>
...
<wsdl:portType name="Transactions">
<wsdl:operation name="getTransactionDetails" parameterOrder="req
resp">
<wsdl:input
message="impl:getTransactionDetailsRequest"
name="getTransactionDetailsRequest"/>
...
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TransactionsSoapBinding"
type="impl:Transactions">
<wsdlsoap:binding
style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation
name="getTransactionDetails">
<wsdlsoap:operation soapAction=""/>
<wsdl:input
name="getTransactionDetailsRequest">
<wsdlsoap:body namespace="urn:TransactionTypesWs"
use="literal"/>
</wsdl:input>
...
</wsdl:operation>
</wsdl:binding>
<wsdl:service
name="TransactionsService">
<wsdl:port
binding="impl:TransactionsSoapBinding"
name="Transactions">
<wsdlsoap:address location="..."/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
So the service is expection an input message
with a soap body that looks like this
<soap:Body>
<Request>
<Type>...</Type>
<From>...</From>
<Until>...</Until>
<Status>...</Status>
<ExtId>...</ExtId>
<ExtPwd>...</ExtPwd>
</Request>
</soap:Body>
I've worked out that to have axis format my
input as a proper document style soap message rather than escape the xml and
make it a string parameter, I should invoke the call with an
org.w3c.dom.Document object as the parameter. However, if I build a
document object from xml with the <Request> tag as it's root element,
when incorparates it into the soap message, there is an extra set of
<Request> tags, presumably auto-generated by axis based on what's in
the wsdl file, so the end message looks like
<soap:Body>
<Request>
<Request>
<Type>...</Type>
...
</Request>
</Request>
</soap:Body>
The fact that axis has automatically inserted
one set of <Request> tags made me think that I should only enter the
child elements of <Request>. However, because the method is
specified as only requiring one parameter, passing in the six child elements
as separate org.w3c.dom.Element objects causes an axis fault for
providing the wrong number of parameters. And the only way I know
of to combine them into one object is to make a Document object but that
can't be done unless there is one root element surrounding the six, which
puts me back to where I started.
Can anyone help? How can I get the
correct input into axis to generate the correctly formatted soap
message? As I said, this is a generic web service client and I have
several other document style services to integrate with which are
going to cause the same problem so generating bespoke code for
each new web service isn't a viable option. I'll be eternally
grateful if there's an easy answer to this, thanks.