ColdFusion provides a simple method invoking and consuming web services via the CFINVOKE tag or CreateObject function. It’s also possible to use CFHTTP to send and receive SOAP messages although you loose the advantage of ColdFusion handling all of the request and response data for you.
So why would you ever want to use CFHTTP over the friendlier methods above???
One example is when a third party was trying to hook into some web services that had been written at work and the service call was constantly sending back HTTP 500’s. In the end I decided to replicate what the other party was doing by using CFHTTP and posting raw SOAP to ColdFusion.
Here’s an example of how this might work:
First an example of a simple ColdFusion webservice:
<cfcomponent output="false" style="rpc">
<cffunction name="addNumbers" access="remote" returntype="numeric" output="false">
<cfargument name="firstNumber" type="string" required="true"/>
<cfargument name="secondNumber" type="string" required="true"/>
<cfreturn arguments.firstNumber + arguments.secondNumber/>
</cffunction>
</cfcomponent>
Now the webservice calling code with CFHTTP
<!--- You'd need to strip any whitespace before passing to CFHTTP --->
<cfsavecontent variable="soap">
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:addNumbers soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://directorypath">
<firstNumber xsi:type="xsd:string">100</firstNumber>
<secondNumber xsi:type="xsd:string">10</secondNumber>
</ns1:addNumbers>
</soapenv:Body>
</soapenv:Envelope>
</cfsavecontent>
<!--- Note that there's no ?wsdl appendage to the url --->
<cfhttp url="http://myserver/webservice.cfc" method="post">
<cfhttpparam type="header" name="content-type" value="text/xml">
<cfhttpparam type="header" name="SOAPAction" value="">
<cfhttpparam type="header" name="content-length" value="#len(soap)#">
<cfhttpparam type="header" name="charset" value="utf-8">
<cfhttpparam type="xml" name="message" value="#trim(soap)#">
</cfhttp>
<!--- Dump out a nice representation of the SOAP response --->
<cfdump var="#xmlParse(cfhttp.FileContent)#">
The result should be contained within a tag named something like addNumbersReturn.
And that’s it! Hopefully it’ll be of use to somebody somewhere.