In the last section, we walked through the fundamentals of creating Web services. As we discovered, Web service creation in ColdFusion MX is exceptionally easy when we utilize the functionality inherent in ColdFusion components (CFCs). So how do we "consume" a Web service from within ColdFusion? How do we utilize data from other ColdFusion servers or disparate platforms, such as Microsoft .NET and Oracle 9i, running on other networks? As long as these Web services are standards-compliant, we should have no problem using them. Consult the WSDLThe first step to consuming a Web service is obtaining the URL of the WSDL document for the service you'll be using. To do this, consult a UDDI directory or the Web service provider. The WSDL document contains all the information you will need to call the Web service (methods, parameters, data types, expected return values, and so on). In Listing 24.14, let's take a look at part of the WSDL for our number translation Web service from a previous section. Listing 24.14. Partial WSDL Display (NumericString.cfc)<wsdl:message name="IntegerToStringResponse"> <wsdl:part name="IntegerToStringReturn" type="xsd:string"/> </wsdl:message> <wsdl:message name="IntegerToStringRequest"> <wsdl:part name="numberNumeric" type="xsd:double"/> </wsdl:message> <wsdl:portType name="NumericString"> <wsdl:operation name="IntegerToString" parameterOrder="numberNumeric"> <wsdl:input message="impl:IntegerToStringRequest" name="IntegerToStringRequest"/> <wsdl:output message="impl:IntegerToStringResponse" name="IntegerToStringResponse"/> <wsdl:fault message="impl:CFCInvocationException" name="CFCInvocationException"/> </wsdl:operation> </wsdl:portType> As designed, this Web service has an operation named IntegerToString that accepts a number as input and returns its textual name. The request message contains one input parameter, whose data type is double. The response message contains one output parameter of type string. Invoking ColdFusion MX Web ServicesInvoking a ColdFusion Web service from within ColdFusion is extremely easy. There are two simple methods for accomplishing this: createObject()/<cfobject> and <cfinvoke>. createObject()/<cfobject>This function and tag can instantiate a Web service similarly to a ColdFusion object, given the WSDL location. Once instantiated, all the developer has to do is call methods that the Web service makes available with the correct parameters. Listing 24.15 shows a sample call. Listing 24.15. createObject() Example Invocation<cfscript> /* Construct the URL dynamically */ if (not findNoCase("https", cgi.server_protocol)) theURL = "http://"; else theURL = "https://"; /* Add the server and current path */ theURL = theURL & cgi.server_name & ":" & cgi.server_port & cgi.script_name; /* Now remove this file's name, which is at the end */ theURL = listDeleteAt(theURL, listLen(theURL,"/"), "/"); // Initialize the input parameter num = "4"; // Instantiate the Web Service ws = createObject("webservice", "#theURL#/NumericString.cfc?wsdl"); // Call the Web Service's integerToString method result = ws.integerToString(num); </cfscript> <cfoutput>The number #num# as a string is #result#.</cfoutput> As in the earlier example, the script begins by simply determining the current location of the file in the form of a URL. This lets us then call the Web service in the current directory using a full URL. Since you may have copied this book's files to a nonstandard directory, calling the Web service using a URL helps the code be more portable. Once we have figured out the URL, the createObject() function is called to create a reference to the Web service. After that is done, we can invoke methods on the Web service. In this case, we call the integerToString method to convert the number to a string. <cfinvoke><cfinvoke> is an extremely powerful tag. It is recommended that you review the ColdFusion Tag Reference before implementing any <cfinvoke> calls because there are at least five ways to use it. Listing 24.16 shows two sample calls. Listing 24.16. <cfinvoke> Example Invocation<!--- DATE: 12/30/04 AUTHOR: Raymond Camden (ray@camdenfamily.com) ---> <!--- Construct the URL dynamically ---> <cfif not findNoCase("https", cgi.server_protocol)> <cfset theURL = "http://"> <cfelse> <cfset theURL = "https://"> </cfif> <!--- Add the server and current path ---> <cfset theURL = theURL & cgi.server_name & ":" & cgi.server_port & cgi.script_name> <!--- Now remove this file's name, which is at the end ---> <cfset theURL = listDeleteAt(theURL, listLen(theURL,"/"), "/")> <!--- Invoke the web service ---> <cfinvoke webservice="#theURL#/NumericString.cfc?wsdl" method="integerToString" numberNumeric="#randRange(0,9)#" returnVariable="result"> <cfoutput>Result of web service call: #result#</cfoutput> <p> <!--- now do a simple CFC call ---> <cfinvoke component="NumericString" method="integerToString" numberNumeric="#randRange(0,9)#" returnVariable="result"> <cfoutput>Result of component call: #result#</cfoutput> Once again, the script starts by figuring out the current root URL. After that, we use <cfinvoke> to call the NumericString Web service. We tell the tag which method to execute, and we pass in the numberNumeric attribute. Lastly, we tell the <cfinvoke> tag to return the result in a variable called result. The next use of <cfinvoke> calls the exact same code, except this time it is used as a ColdFusion component. Complex Data TypesAs we discussed previously, a complex data type can be described as a data type that represents multiple values. Arrays, record sets, and structures are good examples of complex data types. Although these are relatively easy to visualize and describe, representing them programmatically among different application servers on different platforms presents a formidable obstacle. SOAP saves us from having to code our Web services to accommodate every server's interpretation of every data type. This is accomplished by defining SOAP-specific data types that are a workable subset of common data types. The most that developers must do is plug their variables into the appropriate SOAP data types. Each application is responsible for translating to and from the SOAP data types. CFML contains several of these complex data types. As part of consuming Web services, you will need to know how ColdFusion converts WSDL-defined data types to ColdFusion data types and vice versa. In order to facilitate their uses in CFCs exposed as Web services, CFMX maps certain objects to their corresponding SOAP data types completely behind the scenes. Table 24.3 shows this mapping.
Invoking with DreamweaverMacromedia Dreamweaver MX reads the WSDL document when you register a Web service so that it can generate the invocation code for you. You never have to read the WSDL yourself! Figure 24.9 shows the Dreamweaver user interface for invoking a Web service. Figure 24.9. Dreamweaver's user interface for invoking a Web service.You point Dreamweaver to a UDDI registry or directly at a WSDL document. Dreamweaver analyzes the WSDL and outputs the correct method calls for you as drag-and-drop snippets. These operations are done via the Components panel. Invoking .NET Web ServicesMicrosoft's much-hyped .NET architecture is going to have a huge impact in the Web Services arena. Because .NET offers multiple languages to choose from (VB.NET, C#, and others), a large developer base, and simple Web Services development tools, many corporations are taking a serious look at standardizing on the Microsoft platform. As long as the Web services that are created in .NET adhere to the established standards, any Web services developed for .NET can be accessed easily from ColdFusion. Listing 24.17 shows you the simplicity with which a ColdFusion page can invoke a Web service built using Microsoft's .NET architecture. Listing 24.17. Consuming a Microsoft .NET Web Service (DotNetDaily.cfm)<html> <head> <title>DotNet Daily</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body> <cfinvoke webservice="http://www.xmlme.com/WSDailyNet.asmx?WSDL" method="getDotnetDailyFact" returnvariable="aString" /> <cfoutput> Your Daily DotNet for #dateFormat(now(), "MM-dd-yyyy")#:<br> #aString# </cfoutput> </body> </html> NOTE You can sometimes tell from its extension what language or platform a Web service is written in. The .asmx extension tells you that this Web service has been written in .NET. The example in Listing 24.17 is something we might build into a .NET Web site in much the same way Ben Forta's ColdFusion Tip of the Day is displayed on multiple sites within the ColdFusion community. Take a look at the pure-text output in Figure 24.10. Figure 24.10. Text output from Listing 22.18.This Web service's WSDL can be found at www.Xmethods.net along with a number of our example calls to other platforms' Web services. Invoking Java Web ServicesColdFusion MX Enterprise Edition can run on top of any of four Java Application Servers that have native Java support for Web services. Java Web services are usually in the remote procedure call (RPC)style, though Java also supports message-style Web services that implement a JMS (Java Messaging Service) message listener. In Java, an RPC Web service is usually implemented by deploying a stateless session Enterprise JavaBean (EJB) as a Web service. Clients invoke the Web service by sending parameters via HTTP to a Web service that executes the applicable method within the EJB and processes any return data. ColdFusion MX Enterprise Edition can currently run on top of these four Java application servers:
Calling a Java Web service running on BEA WebLogic from ColdFusion is no different from calling a .NET Web servicewhich is the point, of course. With Web services, you really don't need to care what application server is running behind the scenes. You simply worry about the API of the service itself. Database Web ServicesThe world of Web Services is not the domain of the Web application server alone. A number of relational databases can deploy Web services, making them capable of exposing internal information to the outside world. Two of the top databases in the enterprise, Microsoft's SQL Server 2000 and Oracle's 9i, both have the capability to deploy Web services (through add-ons and tool kits) and implement industry-standard protocols such as UDDI, WSDL, XML, and SOAP.
|