Reputation: 1085
I received the following WSDL from a vendor. The sample service behind it runs on Microsoft .NET. I need to create a web service in Java based on this WSDL.
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:tns="http://www.somecompany.com/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
targetNamespace="http://www.somecompany.com/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.somecompany.com/">
<s:import namespace="http://www.w3.org/2001/XMLSchema" schemaLocation="http://www.w3.org/2001/XMLSchema.xsd" />
<s:element name="getInventoryStatus">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="DealerCode" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="SupplierCode" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="PartNumber" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Quantity" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="DeliveryLocation" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="getInventoryStatusResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="getInventoryStatusResult">
<s:complexType>
<s:sequence>
<s:element ref="s:schema" />
<s:any />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="getInventoryStatusSoapIn">
<wsdl:part name="parameters" element="tns:getInventoryStatus" />
</wsdl:message>
<wsdl:message name="getInventoryStatusSoapOut">
<wsdl:part name="parameters" element="tns:getInventoryStatusResponse" />
</wsdl:message>
<wsdl:portType name="InventoryInquirySoap">
<wsdl:operation name="getInventoryStatus">
<wsdl:input message="tns:getInventoryStatusSoapIn" />
<wsdl:output message="tns:getInventoryStatusSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="InventoryInquirySoap" type="tns:InventoryInquirySoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="getInventoryStatus">
<soap:operation soapAction="http://www.somecompany.com/getInventoryStatus" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="InventoryInquiry">
<wsdl:port name="InventoryInquirySoap" binding="tns:InventoryInquirySoap">
<soap:address location="http://www.somecompany.com/InventoryInquiry.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I modified the WSDL I received to include the following line so that Eclipse would recognize the WSDL as valid:
<s:import namespace="http://www.w3.org/2001/XMLSchema" schemaLocation="http://www.w3.org/2001/XMLSchema.xsd" /> <!-- added for Eclipse-->
I've included this WSDL file in a new Dynamic Web Project. I used the New Web Service wizard to create a new top down web service based on the WSDL.
When I deploy the project to Tomcat and call the web service, Apache Axis reports back the following:
AXIS error
Sorry, something seems to have gone wrong... here are the details:
Fault - makeTypeElement() was told to create a type "{http://www.somecompany.com/}>>getInventoryStatusResponse>getInventoryStatusResult", with no containing element
AxisFault faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException faultSubcode: faultString: makeTypeElement() was told to create a type "{http://www.somecompany.com/}>>getInventoryStatusResponse>getInventoryStatusResult", with no containing element faultActor: faultNode: faultDetail: {http://xml.apache.org/axis/}hostname:HOME-DELL
The demo web service provided by the vendor returns the following:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetInventoryStatusResponse xmlns="http://ctire.aktion.com/">
<GetInventoryStatusResult>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="InventoryStatus">
<xs:complexType>
<xs:sequence>
<xs:element name="InStock" type="xs:int" minOccurs="0"/>
<xs:element name="EstDeliveryDate" type="xs:string" minOccurs="0"/>
<xs:element name="EstDeliveryTime" type="xs:string" minOccurs="0"/>
<xs:element name="DeliveryLocation" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet xmlns="">
<InventoryStatus diffgr:id="InventoryStatus1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
<InStock>36</InStock>
<EstDeliveryDate>09/27/2016</EstDeliveryDate>
<EstDeliveryTime>12:00 PM</EstDeliveryTime>
<DeliveryLocation>883620750</DeliveryLocation>
</InventoryStatus>
</NewDataSet>
</diffgr:diffgram>
</GetInventoryStatusResult>
</GetInventoryStatusResponse>
</soap:Body>
</soap:Envelope>
I think I need to reference a schema for the NewDataSet in the WSDL, but I'm not sure how to do that.
Upvotes: 6
Views: 1752
Reputation: 282
It's recommended to use JAX-WS, which is a Java Standard. It cooperates easily with JAXB, which is also needed here.
In this case, the server has a dynamic response which includes an schema definition and a free object, but it seems that is an diffgram node (from a Microsoft XSD) and an object instance that complies with the previous XSD definition and some diffgram attributes.
This solution ignores the diffgram node (but not it's contents) because i don't have the appropiate XSD from Microsoft (it's supposed to be in "msdata.xsd from Visual Studio %InstallRoot%\Xml\Schemas directory). It's only a matter of putting the right XSD and following the steps.
Steps to create the service:
Put in the schema definition from the sample response in diffgram-v1.xsd
Generate JAXB classes in a command line with "xjc diffgram-v1.xsd" (from java bin classpath)
Implement InventoryInquirySoapImpl.getInventoryStatus returning the XSD parsed and an instance of NewDataSet:
InventoryStatus ie = new InventoryStatus();
ie.setDeliveryLocation("del");
ie.setInStock(36);
ie.setEstDeliveryDate("09/27/2016");
ie.setDeliveryLocation("883620750");
NewDataSet nds = new NewDataSet();
nds.getInventoryStatus().add(ie);
GetInventoryStatusResponse.GetInventoryStatusResult _return = new GetInventoryStatusResponse.GetInventoryStatusResult();
_return.setSchema(parseDiffgramSchema());
_return.setAny(nds);
return _return;
parseDiffgramSchema can be implemented with JABX:
// TODO cache
URL file = this.getClass().getClassLoader()
.getResource("diffgram-v1.xsd");
JAXBContext jaxbContext = JAXBContext.newInstance(Schema.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Schema schema = (Schema) jaxbUnmarshaller.unmarshal(file);
return schema;
Full example in my GIT https://github.com/sergio-otero/TestJAXWS/tree/master/TestJAXWS
Upvotes: 0
Reputation: 682
Do you know soapUI? You can import your WSDL and make some requests against the demo service. Just to check that your infrastructure works properly.
If everything seems to work, try this: Have Java generate the classes from the WSDL via the "wsimport" command like this:
%JAVA_HOME%/bin/wsimport -d [RELATIVE_PATH_FOR_GENERATED_CLASSES] -encoding UTF-8 -keep -verbose [RELATIVE_PATH_OF_YOUR_WSDL]
In your code try to use these generated classes and deploy again.
You can get the full documentation of wsimport from here
Hope that helps in any way.
Upvotes: 0