Search code examples
javaxmlweb-servicesxsdwsdl

create a web-service request xml from xsd


I want to consume a web-service without using any framework like jax-ws or axis. By checking this article, i know that I need to create request xml. Is there a way for me to parse the wsdl and create the request xml dynamically? I have checked XSInstance for xsd but not sure how to use it with wsdls

note: a web-service may have multiple operations and i need to create request xml for any of them based on some parameter


Solution

  • Some frameworks aren't there for no reason - but if you want to go the route step by step, you should first have a look at the methods defined in the WSDL contract and add the parameters contained in the message part to the methods. To showcase the relation between a WSDL contract and a SOAP message I use an example WSDL contract taken from http://www.tutorialspoint.com/wsdl/wsdl_example.htm as the WSDL file in your link does not work for me

    <definitions name="HelloService"
       targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl"
       xmlns="http://schemas.xmlsoap.org/wsdl/"
       xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
       xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
       <message name="SayHelloRequest">
          <part name="firstName" type="xsd:string"/>
       </message>
       <message name="SayHelloResponse">
          <part name="greeting" type="xsd:string"/>
       </message>
    
       <portType name="Hello_PortType">
          <operation name="sayHello">
             <input message="tns:SayHelloRequest"/>
             <output message="tns:SayHelloResponse"/>
          </operation>
       </portType>
    
       <binding name="Hello_Binding" type="tns:Hello_PortType">
       <soap:binding style="rpc"
          transport="http://schemas.xmlsoap.org/soap/http"/>
       <operation name="sayHello">
          <soap:operation soapAction="sayHello"/>
          <input>
             <soap:body
                encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                namespace="urn:examples:helloservice"
                use="encoded"/>
          </input>
          <output>
             <soap:body
                encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                namespace="urn:examples:helloservice"
                use="encoded"/>
          </output>
       </operation>
       </binding>
    
       <service name="Hello_Service">
          <documentation>WSDL File for HelloService</documentation>
          <port binding="tns:Hello_Binding" name="Hello_Port">
             <soap:address
                location="http://www.examples.com/SayHello/">
          </port>
       </service>
    </definitions>
    

    A WSDL file contains the following parts: service, binding, portType, operations, messages.

    The service defines the actual web service which binds to a specified URL and offers the operations presented in the WSDL contract. The portType defines ports for incoming and outgoing messages and the message segment defines which parameters and return values to expect for messages received and sent. The binding itself can either be rpc or document and here again encoded or literal - this setting will affect how the actual SOAP body will look like - more information: http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/

    Furthermore, a WSDL file can either contain a link to an xsd that defines the message-parameters or return types or contain the whole xsd definition within the contract.

    In Java the method declaration of the SayHelloRequest would look like this: public String sayHello(String firstName); but invoking a SOAP based service requires an XML (SOAP) message to be sent to a listening service like this:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"    
        xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/1999/XMLSchema">
       <soapenv:Header/>
       <soapenv:Body>
           <SayHelloRequest>
               <firstName xsi:type="xsd:string">Test</firstName>
           </SayHelloRequest>
       </soapenv:Body>
    </soapenv:Envelope>
    

    So, building a SOAP message from WSDL without any framework is possible, but you have to deal with the overhead it brings to the table. Moreover you will have to validate the xsd on your own to be on the safe side.

    With this knowledge you can write your own parser that first extracts the service part, then the binding and the port type (with the defined encoding) and last but not least the defined operations with the in- and out-messages for each operation. To learn which types those parameters are, you need to further have a look at the xsd types and find similar Java classes therefore.

    HTH