IBM's Dojo Soap Library
IBMS's Websphere application server offers a set of dojo extensions in their web 2.0 feature pack (FEP) which includes a SOAP library. I decided to take a look at it and found that it is quite easy to use although there aren't many examples to be found on the web. There is a sample provided with the feature pack but it uses the declarative dojo notation which doesn't work for everyone depending on what the goal is.
I opted to take a scripting approach since I already know how to invoke web services on the server side, and I wanted to see how it measures up in ease of use. Below is a simple example which retrieves data from a contacts web service I blogged about a while back.
Setting up the Infrastructure
My setup involved two different boxes - one running the webservice (axisbox) and another which hosted the HTML and the dojo SOAP library (dsixedev1). Due to the cross domain security restriction enforced by the browser, I also had to set up a reverse proxy (lenovobox). Your setup may vary, if everything runs on one box then this part doesn't really matter. Here's what I have in my apache httpd.conf:
ProxyPass /contacts http://lenovobox:8080/axis2 ProxyPassReverse /contacts http://lenovobox:8080/axis2 ProxyPass /was http://dsixedev1:9080 ProxyPassReverse /was http://dsixedev1:9080
The WSDL is loaded using this code:
var wsdlParser = new ibm_soap.util.WsdlParser(); wsdlParser.parse("contacts.wsdl");
Note that I don't load the WSDL directly from the service because it contains a reference to an external schema:
<xsd:schema> <xsd:import namespace="http://dsixe.com/blog" schemaLocation="ContactService.ContactInfoPort?xsd=ContactService_schema1.xsd"/> </xsd:schema>
This reference causes the parser to fail, so I have to manually copy/paste the schema into the WSDL and then save it on the WAS server.
Putting it all Together
Here's a complete listing of the HTML document:
<html> <head> <title>DsixE SOAP Sample</title> <script type="text/javascript" src="dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true"></script> <script type="text/javascript"> dojo.require("ibm_soap.widget.SoapService"); dojo.require("dojox.wire.ml.util"); function init() { var wsdlParser = new ibm_soap.util.WsdlParser(); wsdlParser.parse("contacts.wsdl"); // Create reference to service and set the URL var myService = new ibm_soap.rpc.SoapService(wsdlParser.smdObj); myService.serviceUrl = "http://lenovobox/contacts/services/ContactService.ContactInfoPort/"; var params = new dojox.wire.ml.XmlElement("getContact"); params.setPropertyValue("arg0", "ABC123"); deferred = myService.getContact(params); deferred.addCallback(function(xmlData){ // do something useful with the data here console.log(xmlData); var phone = dojo.query("phone",xmlData)[0].textContent; var name = dojo.query("name",xmlData)[0].textContent; dojo.byId("contact").innerHTML = name + " " + phone; }); } dojo.addOnLoad(init); </script> </head> <body> <H3> DsixE SOAP Sample - Calling a custom Contacts web service </H3> This is a pure javascript example of how to invoke a SOAP operation without using declarative dojo markup. <br><br> <div id="contact"/> </body> </html>
the SOAP response:
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <dlwmin:getContactResponse xmlns:dlwmin="http://dsixe.com/blog"> <return> <name>Carl</name> <phone>678 555-1212</phone> </return> </dlwmin:getContactResponse> </soapenv:Body> </soapenv:Envelope>
and the output it produces:
DsixE SOAP Sample - Calling a custom Contacts web service This is a pure javascript example of how to invoke a SOAP operation without using declarative dojo markup. Carl 678 555-1212
Overall I'm really pleased with the way IBM has done this, I've always been leery of REST services because they lack a structured type definition available in a WSDL, and the SOAP approach makes the code much easier to read.
After spending alot of time on trying to get this to work, I finally did. It appears that that the wsdl schema needs to be inline in the wsdl. If the schema is referenced externally through the wsdl, then the wsdlParser.smdObj remains null. Once the schema is moved inline in the wsdl, all works well. This seems to be a great method to use and fairly simple to implement.
ReplyDelete