Jan 14
Invoking a webservice using CFHTTP
Posted by James Netherton | Sunday 14 January 2007 9:42 PM | In ColdFusion
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:
<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
<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.
9 Comments
[Post comment]
1
Posted by Dave | Thursday 26 July 2007 6:27 PM
Thanks!
I'm using this right now!
2
Posted by morten | Monday 14 January 2008 12:46 PM
Very nice.
But I have to make more soap calls and therfore I make a loop. But this do not work properly.
It fails with a "You can use only one cfhttpparam of type XML or body".
How to do more calls?
3
Posted by James Netherton | Monday 14 January 2008 1:35 PM
You need to have the loop around the entire CFHTTP tag and not just around the CFHTTPPARAM tag.
4
Posted by rhoan | Thursday 20 March 2008 3:29 PM
I am getting error using above code any idea.
org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.
5
Posted by James | Thursday 20 March 2008 3:48 PM
I suspect that is happening because you have some whitespace at the beginning of your xml string.
Make sure you trim any whitespace before making the request.
6
Posted by viki | Thursday 20 March 2008 4:46 PM
if I use cfinvoke do I need SOAP CALL. IS cfinvoke make soap call automatically?.
If i want to call test.cfc - coldfusion webservice in ASP. How can I do that. I mean i have to use cfhttp..
Thanks
7
Posted by Chris | Thursday 19 June 2008 10:59 PM
@rhoan:
change:
<cfhttpparam type="xml" name="message" value="#soap#">
to
<cfhttpparam type="xml" name="message" value="#trim(soap)#">
8
Posted by James Netherton | Friday 20 June 2008 8:19 AM
Thanks for the hint Chris, I have updated the code snippet.
9
Posted by Chris | Wednesday 16 July 2008 7:52 PM
Another potential reason for using this is if CF doesn't know how to map your data to the WSDL, which is unfortunately common for complex types.