Some time back, I was in need to invoke a simple WebService and that’s when one of my colleagues brought to my notice the simplicity of WSIF. Initially it looked to me as though it’s very simple. However I had to struggle a bit to invoke a simple WebService. I believe the reason for that was their poor documentation.
Needless to say WSIF was the brain child of IBM folks (do correct me if I am wrong) and has been prominently used in this space.
This article is just to show how to invoke a simple WebService which takes a FLAT XML request object and returns a FLAT XML response.
Below is the WSDL of the WebService in question. All it does is spit back a concatenated string of what you spit at it.
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:ns="http://ws.apache.org/axis2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://ws.apache.org/axis2"> <wsdl:types> <xs:schema attributeFormDefault="qualified" elementFormDefault="unqualified" targetNamespace="http://ws.apache.org/axis2"> <xs:element name="showEcho"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="value" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="showEchoResponse"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </wsdl:types> <wsdl:message name="showEchoRequest"> <wsdl:part name="parameters" element="ns:showEcho"/> </wsdl:message> <wsdl:message name="showEchoResponse"> <wsdl:part name="parameters" element="ns:showEchoResponse"/> </wsdl:message> <wsdl:portType name="TestPortType"> <wsdl:operation name="showEcho"> <wsdl:input message="ns:showEchoRequest" wsaw:Action="urn:showEcho"/> <wsdl:output message="ns:showEchoResponse" wsaw:Action="urn:showEchoResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="TestSoap11Binding" type="ns:TestPortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <wsdl:operation name="showEcho"> <soap:operation soapAction="urn:showEcho" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="TestSoap12Binding" type="ns:TestPortType"> <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <wsdl:operation name="showEcho"> <soap12:operation soapAction="urn:showEcho" style="document"/> <wsdl:input> <soap12:body use="literal"/> </wsdl:input> <wsdl:output> <soap12:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="TestHttpBinding" type="ns:TestPortType"> <http:binding verb="POST"/> <wsdl:operation name="showEcho"> <http:operation location="Test/showEcho"/> <wsdl:input> <mime:content type="text/xml" part="showEcho"/> </wsdl:input> <wsdl:output> <mime:content type="text/xml" part="showEcho"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Test"> <wsdl:port name="TestHttpSoap11Endpoint" binding="ns:TestSoap11Binding"> <soap:address location="http://10.142.20.66:8080/axis2/services/Test.TestHttpSoap11Endpoint/"/> </wsdl:port> <wsdl:port name="TestHttpSoap12Endpoint" binding="ns:TestSoap12Binding"> <soap12:address location="http://10.142.20.66:8080/axis2/services/Test.TestHttpSoap12Endpoint/"/> </wsdl:port> <wsdl:port name="TestHttpEndpoint" binding="ns:TestHttpBinding"> <http:address location="http://10.142.20.66:8080/axis2/services/Test.TestHttpEndpoint/"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
NOTE: This WebService was developed with the help of AXIS 2 runtime. I just created a normal java class and put the complied class file (after renaming its extension from .class to .aar) into the repository folder of the AXIS 2 server.
Now the Class used to invoke the WebService
package com.datel.transliterator.app; import org.apache.log4j.Logger; import org.apache.wsif.WSIFException; import org.apache.wsif.WSIFMessage; import org.apache.wsif.WSIFOperation; import org.apache.wsif.WSIFPort; import org.apache.wsif.WSIFService; import org.apache.wsif.WSIFServiceFactory; import org.apache.wsif.providers.soap.apacheaxis.WSIFDynamicProvider_ApacheAxis; import org.apache.wsif.util.WSIFPluggableProviders; public class WSInvoke { Logger log = Logger.getLogger(RunNow.class); public static void main(String[] args) throws Exception { new WSInvoke().invoke(); } public void invoke() throws Exception { String result = null; WSIFPluggableProviders.overrideDefaultProvider("http://schemas.xmlsoap.org/wsdl/soap/", new WSIFDynamicProvider_ApacheAxis() ); // create a service factory WSIFServiceFactory factory = WSIFServiceFactory.newInstance(); WSIFService service = factory.getService( "http://localhost:8080/axis2/services/Test?wsdl", //Location of the WSDL null, null, "http://ws.apache.org/axis2", //TargetNamespace as per the WSDL "TestPortType"); //PortType as per the WSDL WSIFPort port = service.getPort(); // create the operation WSIFOperation operation = port.createOperation("showEcho"); // create the input, output and fault messages associated with this operation WSIFMessage input = operation.createInputMessage(); WSIFMessage output = operation.createOutputMessage(); WSIFMessage fault = operation.createFaultMessage(); /*VALUE : BECAUSE OF THE attribute VALUE <xs:element name="showEcho"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="value" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="showEchoResponse"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> */ input.setObjectPart("value", " Hi there"); if (operation.executeRequestResponseOperation(input, output, fault)) { result = (String) output.getObjectPart("return"); System.out.println(result); } else { System.out.println("Invocation failed"); // extract fault message info } } }
We have created an “input” request object and set it with a key value pair, where the key is “name”. This is because the XML request object takes an attribute “name”
We have created an “output” response object and get it with a key value pair, where the key is “return”. This is because the XML response object takes an attribute “return”
Important:
This example is assuming the structure of the XML request and response object. I have only been able to using this type of invocation for FLAT XML objects. For complex XML request object please wait for PART 2 to see how its invoked.
Eda, is there an id where I can contact you? Wanted a small help from you. In case you can help..
Kiku
Hello, did you manage to invoke a service with complex XML request object?
Thanks
Yes, I did invoke the Webservice with Complex Objects. I wanted to write about it but couldn’t manage it to Second Part. Hopefully sometime in the near future.