Saturday, September 6, 2008

How to invoke web service with complex arguments in ColdFusion

Here is an excellent article describing how we can call web service with complex input arguments in ColdFusion. If you are well versed in WSDL, it may be easier to figure out and construct the input parameter as struct, array and simple types.
I am not good at understanding the WSDL and easily mapping those complex types to CF struct of array of struct of... Lets see if we have alternative ways to deal with the complex types.
Lets try to consume the web service described by below WSDL:
Dumping the webservice object will clearly show Method=createInvoice(com.test.vo.Invoice) and Return Type=com.test.vo.Invoice 
   <cfdump var="#createObject('webservice', 'http://myhost/above_test.wsdl')#">
Won't it be nice if we can just populate the value object Invoice and pass it the createInvoice() method?  But when I try to create an instance of com.test.vo.Invoice using createObject('java', 'com.test.vo.Invoice'), it throws Object Instantiation Exception. ColdFusion does like the idea of creating objects of axis generated classes?  No problem. We can still load these classes using Axis class loader (may not be a good idea though).
<cfset ws = createObject('webservice', 'http://adey03/java/testws.wsdl') />
<cfset invoice = ws.getClass().getClassLoader().loadClass("com.test.vo.Invoice").newInstance() />
<cfdump var="#invoice#">
...
<cfset account= ws.getClass().getClassLoader().loadClass("com.test.vo.Account").newInstance() />
<cfdump var="#account#">
...
<cfset address= ws.getClass().getClassLoader().loadClass("com.test.vo.Address").newInstance() />
<cfdump var="#address#">
...
<cfset product= ws.getClass().getClassLoader().loadClass("com.test.vo.Product").newInstance() />
<cfdump var="#product#">
Above code will clearly describe the composite objects like Invoice, Account etc. So we just need to follow simple steps after that: 
-create and populate Address, Account, Product 
-create and populate Invoice 
-call the web service method createInvoice() and pass the invoice object created above. 
Isn't it little more object oriented than struct of array of struct of...:-)

No comments: