Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a SOAP message with a fully populated request from WSDL without code gen

Tags:

I would like to ask you how I can generate a SOAP request/response in a XML format on the basis of the WSDL file. The target platform is JVM so a wide set of languages can be used (e.g. Java, Scala, Groovy, JRuby, Jython, etc.). The SOAP request/response generation should be done purely on the XML level without any class-generation and class-loading (WSDL2Java, JAXB or similar approaches are inappropriate in this case). Generation should be done programmatically with the usage of open-source components. The generation technique should support document-literal, rpc-encoded and rpc-literal flavors, so proper encoding of parameters should be handled by the generator. Request/response messages should be fully-populated -> empty nodes should be generated even for empty/blank values.

Cutting the long story short -> I would like to do programmatically the thing that is doable in SoapUI IDE. I already had a look at different Java-related libraries/frameworks (SAAJ, WSDL4J) or Ruby (Savon) but I am struggling to move it any further.

A sample Web-Service definition (WSDL and XSD) that I am working on is stockquote-ws.wsdl and stockquote-schema.xsd.

What I would like to do is:

SoapMessageGenerator generator = new SoapMessageGenerator("stockquote-ws.wsdl");
String request = generator.generateSoapRequest();
String response = generator.generateSoapResponse();

In this case a request should look like this:

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:stoc="http://centeractive.com/stockquote.wsdl" xmlns:stoc1="http://centeractive.com/stockquote.xsd">
   <soapenv:Header/>
   <soapenv:Body>
      <stoc:GetLastTradePrice soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <stoc1:TradePriceRequest>
            <tickerSymbol xsi:type="xsd:string">?</tickerSymbol>
         </stoc1:TradePriceRequest>
      </stoc:GetLastTradePrice>
   </soapenv:Body>
</soapenv:Envelope>

... whereas a response should look like this:

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:stoc="http://centeractive.com/stockquote.wsdl" xmlns:stoc1="http://centeractive.com/stockquote.xsd">
   <soapenv:Header/>
   <soapenv:Body>
      <stoc:GetLastTradePriceResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <stoc1:TradePrice>
            <price xsi:type="xsd:float">?</price>
         </stoc1:TradePrice>
      </stoc:GetLastTradePriceResponse>
   </soapenv:Body>
</soapenv:Envelope>
like image 735
tom.bujok Avatar asked Sep 20 '11 15:09

tom.bujok


People also ask

Can SOAP work without WSDL?

Without the WSDL, it will be responsibility of the developer to know the definition of the SOAP Web Service to consume . SOAP envelope, SOAP Body and the complete XML request has to be built by the developer and pass it to the Http client.


2 Answers

OK. I managed to fully solve this problem. I have extracted some code from soapUI and started an open-source project to support SOAP in a purely XML way in Java. The main reason behind the class extraction was to separate the code that is responsible for the generation of the SOAP messages from the rest of the soapUIs code that is tightly coupled with other modules, such as soapUIs graphical user interface, etc. You can find the project here: https://github.com/reficio/soap-ws Not only is it able to generate SOAP messages, but also provides SOAP client and server. More details here: http://www.reficio.org/projects

like image 112
tom.bujok Avatar answered Sep 18 '22 13:09

tom.bujok


What about the SOAPUI library:

package com.bbog.soap;

import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlImporter;
import com.eviware.soapui.model.iface.Operation;

public class WsdlAnalyzer {

    public static void main(String[] args) throws Exception {
        WsdlProject project = new WsdlProject();
        WsdlInterface[] wsdls = WsdlImporter.importWsdl(project, "http://localhost:7000/Solicitud?wsdl");
        WsdlInterface wsdl = wsdls[0];
        for (Operation operation : wsdl.getOperationList()) {
            WsdlOperation op = (WsdlOperation) operation;
            System.out.println("OP:"+op.getName());
            System.out.println(op.createRequest(true));
            System.out.println("Response:");
            System.out.println(op.createResponse(true));
        }
    }
}
like image 29
sonnykwe Avatar answered Sep 18 '22 13:09

sonnykwe