Hi,

I have a peculiar use-case where in I need to invoke a SOAP Service without
refering the WSDL and without creating the stubs & JAXB classes. Custom
implementation of data mapping well suits to our needs and infact we have
it in-place.

I have the following information to invoke the Service :

Style and Use
Operation Name
Namespace URI
SOAPAction
Endpoint URL
Binding SOAP version - 1.1/1.2


With the above information we are able to make a service call using Axis2.

I am trying to achieve the same using CXF. Basically I tried the below.



import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Iterator;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.w3c.dom.NodeList;


public class CXFClient {

/**
 * @param args
 */
public static void main(String[] args) {
try
{
//TYPE-1
 JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("
http://wsekhc1w7:8989/web/SOAPServlet/SOAP/TestService/Sample?WSDL";);
 Object[] res = client.invoke("TestServiceSOAP1", "Hello...!");
System.out.println("Response :::    " + res[0]);
 //TYPE-2
     //QName serviceName = new QName("urn:SOAP:TestService:Sample",
"SampleService");
//QName serviceName = new QName("Test", "Test");
QName serviceName = new QName("", "");
    Service service = Service.create(serviceName);

    //QName portName = new QName("urn:SOAP:TestService:Sample",
"SamplePortSOAP");
    //QName portName = new QName("Test", "Test");
    QName portName = new QName("", "");

    service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, "
http://wsekhc1w7:8989/web/SOAPServlet/SOAP/TestService/Sample";);
    Dispatch<SOAPMessage> dispatch = service.createDispatch(portName,
SOAPMessage.class, Service.Mode.MESSAGE);

        // Test request-response
        InputStream is = new
FileInputStream("F:\\CXF_Demo\\src\\SampleRequestEnvelope.xml");
        SOAPMessage soapReqMsg =
MessageFactory.newInstance().createMessage(null, is);

        SOAPMessage soapResMsg = dispatch.invoke(soapReqMsg);

    SOAPPart soapPart = soapResMsg.getSOAPPart();
    SOAPEnvelope envelope = soapPart.getEnvelope();
    SOAPBody body = envelope.getBody();

    Iterator iter = body.getChildElements();
    while(iter.hasNext())
    {
     Node tempNode = (Node) iter.next();
     if(tempNode.getNodeType()==Node.ELEMENT_NODE)
     {
     NodeList list = tempNode.getChildNodes();
     for(int i=0; i<list.getLength(); i++)
     {
     if(list.item(i).getNodeType() == Node.ELEMENT_NODE)
     {
     NodeList list1 = tempNode.getChildNodes();
     for(int j=0; j<list.getLength(); j++)
     {
     //System.out.println(list1.item(j).getNodeName());
     if(list1.item(j).getNodeType() == Node.ELEMENT_NODE)
     {
     System.out.println("NodeName : " + list1.item(j).getNodeName() + "\n
 NodeValue : " + list1.item(j).getFirstChild().getNodeValue());
     }
     }
     }
     }
     }
     //System.out.println("TempNode : " + tempNode.getNodeName());
    }
}
catch(Exception e)
{
e.printStackTrace();
}
}
}



In the above code snippet, TYPE-1 is using CXF's dynamic client with which
found no way to decouple the WSDL dependency. Because all the
 JaxWsDynamicClientFactory.createClient() overloaded methods need WSDL URL.

Though TYPE-2 does the same for us (without WSDL URL), but the concern here
is that it uses the JAX-WS API and can we be able to embedd the CXF feature
support (like WS-*).

Suggestion to implement CXF dynamic client (without stubs & classes
creation) greatly appreciated.

Thanks in advance.

Regards,
Chandu

Reply via email to