ColdFusion provides two methods for consuming web services. The method that you choose depends on your ColdFusion programming style and application.
The following table describes these methods:
Method |
CFML operator |
Description |
---|---|---|
CFScript |
CreateObject() |
Consumes a web service from within a CFScript block |
CFML tag |
cfinvoke |
Consumes a web service from within a block of CFML code |
One important consideration is that all consumption methods use the same underlying technology and offer the same performance.
The examples in this section reference the BabelFish web service from AltaVista. BabelFish can translate string up to 5 KB in length from one language to another. You can read the WSDL file for this web service in "Reading a WSDL file".
If you add the BabelFish web service in Dreamweaver MX, you see the following description of it in the Application panel.
For information on adding a web service in Dreamweaver, see "Viewing a WSDL file using Dreamweaver MX". For more information on BabelFish, see http://babelfish.altavista.com/.
One type of information in the WSDL file defines the web service operations and the input and output parameters of each operation, including the data type of each parameter. If you register the web service in Dreamweaver MX, as shown in the previous section, you see that the data type of both input parameters is string.
The following example shows a portion of the WSDL file for the BabelFish web service:
<message name="BabelFishRequest">
<part name="translationmode" type="xsd:string" /> <part name="sourcedata" type="xsd:string" /> </message> <message name="BabelFishResponse"> <part name="return" type="xsd:string" /> </message> <portType name="BabelFishPortType"> <operation name="BabelFish"> <input message="tns:BabelFishRequest" /> <output message="tns:BabelFishResponse" /> </operation> </portType>
The operation name used in the examples in this section is BabelFish. This operation takes a single input parameter defined as a message of type BabelFishRequest.
You can see that the message BabelFishRequest contains two string parameters: translationmode
and sourcedata
. When you call the BabelFish operation, you pass both parameters as input.
Web service operations often return information back to your application. You can determine the name and data type of returned information by examining the WSDL file for the web service.
If you register the web service in Dreamweaver MX, you see that the data type of the return value is string.
The following example shows a portion of the WSDL file for the BabelFish web service:
<message name="BabelFishRequest">
<part name="translationmode" type="xsd:string" /> <part name="sourcedata" type="xsd:string" /> </message> <message name="BabelFishResponse"> <part name="return" type="xsd:string" /> </message> <portType name="BabelFishPortType"> <operation name="BabelFish"> <input message="tns:BabelFishRequest" /> <output message="tns:BabelFishResponse" /> </operation> </portType>
The operation BabelFish returns a message of type BabelFishResponse. The message statement in the WSDL file defines the BabelFishResponse message as containing a single string parameter named return
.
This section describes how to consume a web service using the cfinvoke
tag. With the cfinvoke
tag, you reference the WSDL file and invoke an operation on the web service with a single tag.
The cfinvoke
tag has the following syntax:
<cfinvoke
webservice = "URLtoWSDL" method = "operationName" inputParam1 = "val1" inputParam2 = "val2" ... returnVariable = "varName" >
webservice
specifies the URL to the WSDL file for the web service.
method
specifies the operation of the web service to invoke.returnVariable
specifies the name of the variable containg any results returned from the web service. <cfinvoke webservice = "http://www.xmethods.net/sd/2001/BabelFishService.wsdl" method = "BabelFish" translationmode = "en_es" sourcedata = "Hello world, friend" returnVariable = "foo"> <cfoutput>#foo#</cfoutput>
The following string appears in your browser:
Hola mundo, amigo
You can pass parameters to web services using two other mechanisms: the cfinvokeargument
tag and the argumentCollection
attribute of the cfinvoke
tag.
To pass parameters using the cfinvokeargument
tag, you write your call to the web service, as the following code shows:
<cfinvoke
webservice ="http://www.xmethods.net/sd/2001/BabelFishService.wsdl" method ="BabelFish" returnVariable = "varName" > <cfinvokeargument name="translationmode" value="en_es"> <cfinvokeargument name="sourcedata" value="Hello world, friend"> </cfinvoke> <cfoutput>#varName#</cfoutput>
The cfinvokeargument
tag is a nested tag of the cfinvoke
tag that lets you specify the name and value of a parameter passed to the web service.
You can also use an attribute collection to pass parameters. An attribute collections is a structure where each structure key corresponds to a parameter name and each structure value is the parameter value passed for the corresponding key. The following example shows an invocation of a web service using an attribute collection:
<cfscript>
stArgs = structNew(); stArgs.translationmode = "en_es"; stArgs.sourceData= "Hello world, friend"; </cfscript> <cfinvoke webservice = "http://www.xmethods.net/sd/2001/BabelFishService.wsdl" method = "BabelFish" argumentCollection = "#stArgs#" returnVariable = "varName" > <cfoutput>#varName#</cfoutput>
In this example, you create the structure in a CFScript block, but you can use any ColdFusion method to create the structure.
The example in this section uses CFScript to consume a web service. In CFScript, you use the CreateObject
function to connect to the web service. After connecting, you can make requests to the service. The CreateObject
function has the following syntax:
webServiceName = CreateObject("webservice", "URLtoWSDL")
where URLtoWSDL specifies the URL to the WSDL file for the web service.
After creating the web service object, you can call operations of the web service using dot notation, in the following form:
webServiceName.operationName(inputVal1, inputVal2, ... )
You can handle return values from web services by writing them to a variable, as the following example shows:
resultVar = webServiceName.operationName(inputVal1, inputVal2, ... );
Or, you can pass the return values directly to a function, such as the writeOutput
function, as follows:
writeoutput
(webServiceName.operationName(inputVal1, inputVal2, ...) );
<cfscript> ws = CreateObject("webservice", "http://www.xmethods.net/sd/2001/BabelFishService.wsdl"); xlatstring = ws.BabelFish("en_es", "Hello world, friend"); writeoutput(xlatstring); </cfscript>
The following string appears in your browser:
Hola mundo, amigo
You can also use named parameters to pass information to a web service. The following example performs the same operation as above, except that it uses named parameters to make the web service request:
<cfscript>
ws = createObject("webservice", "http://www.xmethods.net/sd/2001/BabelFishService.wsdl"); xlatstring = ws.BabelFish(translationmode = "en_es", sourcedata = "Hello world, friend"); </cfscript> <cfoutput>#xlatstring#</cfoutput>
The Flash Remoting service lets you call ColdFusion pages from a Flash Client, but it does not let you call web services directly. To call web services from a Flash client, you can use Flash Remoting to call a ColdFusion component that calls the web service. The Flash client can pass input parameters to the component, and the component can return to the Flash client any data returned by the web service.
For more information on Flash Remoting, see Chapter 29, "Using the Flash Remoting Service".
Web services might throw errors, including SOAP faults, during processing that you can catch in your application. If uncaught, these errors propagate to the browser.
To catch errors, you specify an error type of application to the ColdFusion cfcatch
tag, as the following example shows:
<cftry
>
Put your application code here ... <cfcatch
type
="application"> <!--- Add exception processing code here ... ---> </cfcatch
> . . . <cfcatch
type
="Any"> <!--- Add exception processing code appropriate for all other exceptions here ... ---> </cfcatch
> </cftry
>
For more information on error handling, see Chapter 14, "Handling Errors".
Some web services define inout and out parameters. You use out parameters to pass a placeholder for a return value to a web service. The web service then returns its result by writing it to the out parameter. Inout parameters let you pass a value to a web service and lets the web service return its result by overwriting the parameter value.
The following example shows a web service that takes as input an inout parameter containing a string and writes its results back to the string:
<cfset S="foo">
<cfscript> ws=createobject("webservice", "URLtoWSDL") ws.modifyString("S"); <cfscript> <cfoutput>#S#</cfoutput>
Even though this web service takes as input the value of S, because you pass it as an inout parameter you do not enclose it in pound signs.
Note: ColdFusion supports the use of inout and out parameters to consume web services. However, ColdFusion does not support inout and out parameters when creating web services for publication.
The ColdFusion Administrator lets you register web services so that you do not have to specify the entire WSDL URL when you reference the web service.
Note: The first time you reference a web service, ColdFusion automatically registers it in the Administrator.
For example, the following code references the URL to the BabelFish WSDL file:
<cfscript>
ws = CreateObject("webservice", "http://www.xmethods.net/sd/2001/BabelFishService.wsdl"); xlatstring = ws.BabelFish("en_es", "Hello world, friend"); writeoutput(xlatstring); </cfscript>
If you register the BabelFish web service in the ColdFusion Administrator using, for example, the name wsBabel, you could then reference the web service as follows:
<cfscript>
ws = CreateObject("webservice", "wsBabel"); xlatstring = ws.BabelFish("en_es", "Hello world, friend"); writeoutput(xlatstring); </cfscript>
Not only does this enable you to shorten your code, registering a web service in the ColdFusion Administrator lets you change a web service's URL without modifying your code. So, if the BabelFish web service moves to a new location, you only update the administrator setting; not your application code.
For more information, see the online help in the ColdFusion Administrator.
A WSDL file defines the input and return parameters of an operation, including data types. For example, the BabelFish web service contains the following definition of input and return parameters:
<message name="BabelFishRequest">
<part name="translationmode" type="xsd:string" /> <part name="sourcedata" type="xsd:string" /> </message> <message name="BabelFishResponse"> <part name="return" type="xsd:string" /> </message>
As part of consuming web services, you must understand how ColdFusion converts WSDL defined data types to ColdFusion data types. The following table shows this conversion:
For many of the most common data types, such as string and numeric, a WSDL data type maps directly to a ColdFusion data type. For complex WSDL data types, the mapping is not as straight forward. In many cases, you map a complex WSDL data type to a ColdFusion structure. For more information on handling complex data types, see "Handling complex data types".
Your application might consume web services created in ColdFusion. You do not have to perform any special processing on the input parameters or return values because ColdFusion handles data mappings automatically when consuming a ColdFusion web service.
For example, when ColdFusion publishes a web service that returns a query, or takes a query as an input, the WSDL file for that service lists its data type as QueryBean. However, a ColdFusion application consuming this web service can pass a ColdFusion query object to the function as an input, or write a returned QueryBean to a ColdFusion query object.
Note: For a list of how ColdFusion data types map to WSDL data types, see "Data conversions between ColdFusion and WSDL data types".
The following example shows a ColdFusion component that takes a query as input and echoes the query back to the caller:
<cfcomponent>
<cffunction name='echoQuery' returnType='query' access='remote'> <cfargument name='input' type='query'> <cfreturn #arguments.input#> </cffunction> </cfcomponent>
If you add this web service in Dreamweaver MX, you see the following description of it in the Application panel:
Note: This figure assumes that you create a web component named echotypes.cfc that contains the echoQuery function definition shown above, and write echotypes.cfc to your web root directory.
In the WSDL file for the echotypes.cfc component, you see the following definitions that specify the type of the function's input and output as QueryBean:
<wsdl:message name="echoQueryRequest">
<wsdl:part name="input" type="tns1:QueryBean"/> </wsdl:message> <wsdl:message name="echoQueryResponse"> <wsdl:part name="return" type="tns1:QueryBean"/> </wsdl:message>
Since ColdFusion automatically handles mappings to ColdFusion data types, you can call this web service as the following example shows:
<head>
<title>Passing queries to web services</title> </head> <body> <cfquery name="GetEmployees" datasource="CompanyInfo"> SELECT FirstName, LastName, Salary FROM Employee </cfquery> <cfinvoke webservice = "http://localhost/echotypes.cfc?wsdl" method = "echoQuery" input="#GetEmployees#" returnVariable = "returnedQuery"> <cfoutput> Is returned result a query? #isQuery(returnedQuery)# <br><br> </cfoutput> <cfoutput query="returnedQuery"> #FirstName# #LastName# #Salary#<br> </cfoutput> </body>