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