|
Some tools can not handle a wsdl referencing external schema definitions, in particular Tibco Business Studio 3.4.2 when using iProcess on the client side of the webservice.
On the server side of the webservice we needed to provide multiple webservices through java classes. We used Oracle JDeveloper 11.1.1.2.0 to create these java classes from the wsdl's. Each time you import a wsdl and generate a java webservice from it, JDeveloper creates a class ObjectFactory. With this class java objects can be instantiated that correspond to the elements/types defined in the wsdl.
JDeveloper generates for each namespace within the wsdl types tag a java package containing the types in the namespace and a class ObjectFactory. The package name is deducted from the namespace name in the wsdl.
So when importing more than one wsdl containing the same namespaces the class definition of
ObjectFactory might be overwritten or there might be more than one file ObjectFactory in the same
package. The package name can be overridden in JDeveloper, but that needs to be done each time the
wsdl is (re)imported. And overriding the package name at reimport can be easily forgotten.
So it is better to import wsdl's with different namespaces such that each ObjectFactory class ends up in its own java package. In that case you don't need to manually override the package name when importing the wsdl and generating java classes from it.
Below is an example of such a wsdl using multiple schema's with different namespaces. As shown one can use an inlined xml schema inside another xml schema within the types tag of a wsdl with the import tag without the attribute schemaLocation.
When importing this wsdl into JDeveloper as a java webservice, JDeveloper creates two packages: services.data.common and services.data.itemOperations. Both packages have their own class ObjectFactory.
Below is an example of such a wsdl using multiple schema's with different namespaces, including a schema in the empty namespace:
<?xml version="1.0" encoding="UTF-8"?>
<!-- $HeadURL: $ $Revision: $ $Date: $ $Author: $ -->
<!-- soap 1.1 instead of soap 1.2 here, namespace for soap 1.2 is
http://schemas.xmlsoap.org/wsdl/soap12/ -->
<wsdl:definitions
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="services/itemOperations.wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:d="services/data/common" xmlns:o="services/data/itemOperations" name="itemOperations"
targetNamespace="services/itemOperations.wsdl">
<wsdl:types>
<!-- including a schema without a namespace -->
<xsd:schema xmlns="">
<xsd:complexType name="NoNamespaceType">
<xsd:sequence>
<xsd:element name="firstElement" type="xsd:string"/>
<xsd:element name="secondElement" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="noNamespace" type="NoNamespaceType"/>
</xsd:schema>
<xsd:schema xmlns:d="services/data/common" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="services/data/common" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:element name="request" type="d:Request"/>
<xsd:complexType name="Request">
<xsd:sequence>
<xsd:element minOccurs="0" name="header" type="xsd:string"/>
<xsd:element minOccurs="0" name="body" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="item">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="value" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
<!-- This schema uses the schema with namespace "services/data/common"
and the schema in the empty or null namespace -->
<xsd:schema
xmlns:d="services/data/common" xmlns:o="services/data/itemOperations"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="services/data/itemOperations"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="services/data/common"/>
<!-- import the schema without any namespace -->
<xsd:import namespace=""/>
<xsd:element name="getItemsRequest" type="d:Request"/>
<xsd:complexType name="myItem">
<xsd:complexContent>
<xsd:extension base="d:item">
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<!-- use an element from the schema without any namespace -->
<xsd:element ref="noNamespace"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="itemList">
<xsd:sequence>
<xsd:element minOccurs="0" name="item" type="o:myItem"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="getItemsResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="body" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="list" type="o:itemList"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:service name="itemsOperationsService">
<wsdl:port name="itemsOperationsSOAPexplEventSource" binding="tns:itemsOperationsBinding">
<soap:address location="http://calculateonline.org:5000/itemsOperations"/>
</wsdl:port>
</wsdl:service>
<wsdl:portType name="itemsOperationsPort">
<wsdl:operation name="retrieveItems">
<wsdl:input message="tns:getItemsRequest"/>
<wsdl:output message="tns:getItemsResponse"/>
</wsdl:operation>
<!-- other operations can be defined here, they must be defined in the binding as well
If more operations are defined in a single webservice then make sure that the types of the request messages
are unique. That will prevent dispatch errors.
-->
</wsdl:portType>
<wsdl:binding name="itemsOperationsBinding" type="tns:itemsOperationsPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="retrieveItems">
<!-- the url of this operation is http://calculateonline.org:5000/itemsOperations/getItems -->
<soap:operation style="document" soapAction="/getItems"/>
<wsdl:input>
<soap:body use="literal" parts="request"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" parts="response"/>
</wsdl:output>
</wsdl:operation>
<!-- other operations can be defined here, they must be defined in the portType as well -->
</wsdl:binding>
<wsdl:message name="getItemsRequest">
<wsdl:part name="request" element="o:getItemsRequest"/>
</wsdl:message>
<wsdl:message name="getItemsResponse">
<wsdl:part name="response" element="o:getItemsResponse"/>
</wsdl:message>
</wsdl:definitions>
When importing this wsdl JDeveloper creates a package generated for the types from the schema without a namespace. This is not very clean when including multiple schema's without namespaces.
Alternatively one can import each wsdl into its own JDeveloper project. In that case there are no namespace and java package name issues. But using a different JDeveloper project for each wsdl often can lead to much code duplication: common objects will be defined separately for each JDeveloper project.
Another extra note: some tools treat an empty xmlns attribute different from a nonexisting xmlns attribute. Therefore, if a schema has no target namespace, it may be better to import it without the namespace attribute in the import statement.
|