Working with SOAP Requests
ColdFusion offers a variety of ways to work with the SOAP requests and responses involved in web services. Let’s look at them closely with an example.
We have already talked about CFCs and how the same components can be used to serve different types of requests such as Adobe Flash Remoting and Ajax Remoting calls. When you want to handle SOAP requests differently and to know whether the call originated as a web service call, you can use the function IsSOAPRequest(). This function will return true if the CFC is being called as a web service.
Also we have talked about how SOAP requests for web services use HTTP as the transport medium. You also may know that HTTP uses headers to pass additional workable information about the request and its response. So depending on the use case, you may need to read SOAP request headers—for example, to get the username—or add headers to your SOAP responses—for example, an authorization header. ColdFusion provides functions that let you read and add headers to your SOAP request or SOAP response. Listing 4.10 provides an example.
Listing 4.10. /cfwack/4/soap.cfc
<cfcomponent hint="Test for SOAP headers"> <cffunction name="test" returntype="string" access="remote"> <cfset isSOAP = isSOAPRequest()> <cfif isSOAP> <!--- Get the first header as a string. ---> <cfset username = getSOAPRequestHeader("http://somenamespace/", "username")> <cfset result = "username: " & username> <!--- Get the second header as a string. ---> <cfset password = getSOAPRequestHeader("http://somenamespace/", "password")> <cfset result = result & " and password: " & password> <!--- Add a header as a string. ---> <cfset addSOAPResponseHeader("http://somenamespace/", "returnheader", "AUTHORIZED", false)> <cfelse> <cfset result = "Not invoked as a web service"> </cfif> <cfreturn result> </cffunction> </cfcomponent>
As you can see, we have a simple soap CFC that has only one function test. Within this function, we check whether the call is a SOAP request with isSOAPRequest(). If the result is true, we get the headers from the request—that is, username and password—using getSOAPRequestHeader() and set a returnheader header in the response using addSOAPResponseHeader(). If the result is false, then we send back the result “Not invoked as a web service.” This example is very simple, but you can see how different logic can be applied to perform various operations such as actual authentication.
Now let’s see this CFC in action by invoking the CFC once as a web service and for a second time as a local method on a component (Listing 4.11).
Listing 4.11. /cfwack/4/soap.cfm
<cfscript> wsURL = "http://localhost:8500/cfwack/4/soap.cfc?wsdl"; ws = CreateObject("webservice", wsURL); // Set the username and passwordheader as a string. addSOAPRequestHeader(ws, "http://somenamespace/", "username", "user"); addSOAPRequestHeader(ws, "http://somenamespace/", "password", "pass"); // Invoke the web service operation. result = ws.test(); // Get the first header as an object (string) and as XML. header = getSOAPResponseHeader(ws, "http://somenamespace/", "returnheader"); </cfscript> <cfoutput> SOAP Return value: #result#<br> SOAP Header value: #header#<br> </cfoutput> <cfinvoke component="soap" method="test" returnvariable="result"> </cfinvoke> <cfoutput>The cfinvoke tag returned: #result#</cfoutput>
Here we created a proxy for the SOAP web service using CreateObject(). Then we added two headers, username and password, for this proxy. These headers will be added to the SOAP request when the actual call is made, which is when the test method is called. We get back the result of this web service call in result. Additionally, we extract the response header that was set in the CFC from the proxy object. Next, we call a function on the SOAP CFC directly and output its results.
The output of this template when executed in a browser is obvious. For the SOAP request, the output will return the username and password that were sent as headers, and it will also return returnheader as "AUTHORIZED". For a local call, it would simply return “Not invoked as a web service.”