Thanks to ColdFusion 8's support of JSON, we can easily convert ColdFusion objects to and from JSON using SerializeJSON() and DeserializeJSON(). In conjunction with this explicit JSON serialization, ColdFusion 8 has also added the ability for remote access ColdFusion functions to return ColdFusion objects as JSON data when they are invoked as web services (using the ReturnFormat = "JSON" CFFunction attribute). Now that we have covered all basics, let's take a look at an example of how ColdFusion 8 remote access functions can be used as JSON serving web services in an AJAX application.
To demonstrate this, I have created a web service ColdFusion component, TextUtility.cfc, which has one remote access method, GetWords(). This method takes a string and breaks it up into an array of words, which it then returns:
Launch code in new window » Download code as text file »
Notice that the function returns the actual ColdFusion array - we are not using the SerializeJSON() method. By setting the ReturnFormat CFFunction attribute to "JSON," we are getting ColdFusion to convert the array into Javascript object notation when it is returning the array as a remote method call. This is sooo awesome because, remember, a remote-access function can be called locally as well as remotely; by controlling the format using ReturnFormat rather than through explicit conversion, we don't have to worry about data issues when used locally.
Also notice that we are taking the array of words returned from the String::Split() method and converting that into a ColdFusion array. This is necessary since the Java string array (String[]) returned from Split() is not a true ColdFusion array and if you tried to return it from the method, ColdFusion would throw the following error when trying to create the serialized JSON data:
Could not convert a value of type class [Ljava.lang.String; to an Array.
Now that we have the remote web service in place, we can create an AJAX application that will consume it. For our demo, we are going to keep it really simple; our application will take a phrase from one text input, pass it to the web service, and then output each of the returned words on a new line of a textarea:
Launch code in new window » Download code as text file »
We are using jQuery to make the AJAX / JSON calls. By doing so, we are hiding the fact that the JSON data returned by the web service is being converted to a Javascript array, but rest assured, that is what $.getJSON() is doing. Take a look at the $.getJSON() method call and you will see that it has three arguments. The first is the URL that we are invoking as a web service. For our demo, that web service URL is the TextUtility.cfc with the WSDL flag. The Second argument is the parameters struct; our parameters consist of the method name, GetWords, and the argument that we are passing in, Text. The third argument is the call back method that gets fired when the AJAX call returns. This is the method to which the JSON data (turned Javascript Array) is sent.
The call back method just loops over the passed in array and puts each index of the array on its own line of the page's textarea input. If we run the above page and enter the phrase:
Hold me close and hold me fast, the magic spell you cast, this is La Vie en Rose
... we get the following output:
| | | | ||
| | ![]() | | ||
| | | |
As you can see, ColdFusion 8's ability to return ColdFusion objects as JSON data is going to make interacting with AJAX application much easier. This will hold especially true when those web services also have to interact with other ColdFusion-based modules (in which case, returning JSON data would not be a valid option).
Download Code Snippet ZIP File
Comments (11) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
John Rambo Trailer (Rambo IV) - Old Dog, New Tricks
ColdFusion 8's New Nested Query Loop Behavior (Thanks Rick Osborne)
Ben, Thanks a lot for this great article. I enjoy reading your articles very much.
Posted by siby thomas on Jun 11, 2007 at 9:52 AM
@Siby,
Thanks a lot for the kind words. If you ever want to see an article on something specific, please do not hesitate to ask.
Posted by Ben Nadel on Jun 11, 2007 at 9:56 AM
Very nice article, Ben! Just a note - you don't need the wsdl flag when invoking CFCs as JSON web services. These are REST web services, rather than SOAP.
Posted by Ashwin on Jun 15, 2007 at 9:03 AM
@Ashwin,
Thanks for the tip. My web service understanding is a bit fuzzy. So, you only need WSDL when using CFInvoke to call the web services?
Posted by Ben Nadel on Jun 15, 2007 at 10:54 AM
Ben,
You should at least be using cfajaxproxy! The whole application can be written with the new ColdFusion 8 AJAX tags, right? :-)
Something for another entry perhaps?
Keep up the great postings.
Posted by Tom Jordahl on Jun 15, 2007 at 3:07 PM
Ben,
The ?wsdl URL param is only used for GET requests when you are in fact getting WSDL for your web service client software. For instance cfinvoke gets the WSDL and generates Java artifacts (via Apache Axis) that it then compiles and invokes to consume the service.
For AJAX, the access="remote" CFC functions are invoked in an entirely different way. The HTTP request contains URL parameters (?method=GetWords) which then indicates which method to call with what arguments.
Cfajaxproxy can take care of this all for you for AJAX.
Hope this clear it up a little.
Posted by Tom Jordahl on Jun 15, 2007 at 3:12 PM
@Tom,
I will definitely be checking on the CF8 AJAX stuff. I figured one topic per post... plus Ray Camden seems to be exploring a lot of the layout / AJAX stuff and I don't want to deal with his Jedi mind tricks - next thing you know I am showing up to work wearing a tutu :)
Yeah, my web service understanding is the sketchy part of my understanding. Web services, SOAP, etc... all get grouped under stuff I have used but don't fully understand.
From your comments above, are you saying that CFInvoke does not need the WSDL flag all the time? Or are you saying that since CFInvoke is totally different from AJAX that is actually does need the WSDL flag?
Thanks for all the clarification.
Posted by Ben Nadel on Jun 15, 2007 at 5:57 PM
Hi,
I installed the snippets on Coldfusion 8. But for some unknown reason, the words don't get display after I press 'Get Words' button. Nothing happens.
The GetWords function gets indeed called. The returned Response is shown below (retrieved using Firedebug). I am running Coldfusion 8 with Cumulative Hot Fix 1.
I really don't understand what's happining. The getJSON flickr example (http://docs.jquery.com/Ajax/jQuery.getJSON) on the jquery.com works fine for me.
I will greatly appreciate any help/suggestions.
Thank you very much!
Alex
Note: The only change of code I made is to replace the line that loads jquery.js with the following
<script src="http://code.jquery.com/jquery-latest.js"></script>
-----------------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
</head>
<body>
</body>
</html>
["abc","def","ghi"]
-----------------------------------------------------
Posted by Alex on Nov 20, 2007 at 8:56 AM
@Alex,
If the words array is coming back from the JSON request, it must be something wrong with the ShowWords() method. My suggestion is to start putting some alerts() in there to see where the code is actually going wrong.
However, if there are no errors, then I have heard that JSON might be messing up. Apparently when a JSON request fails, it fails quietly. Try alerting the returned JSON data as the first thing in the ShowWords() method.
Posted by Ben Nadel on Nov 20, 2007 at 2:00 PM
Hey Ben...
I'm having an issue with the getJSON jQuery method and calling a CFC directly. I posted it about it on the jQuery list, but since you're a CF guy, you might be a better person to ask.
http://groups.google.com/group/jquery-en/browse_thread/thread/21a68cea4bb11e84
Have any input?
Posted by Andy Matthews on Mar 13, 2008 at 12:35 AM
@Andy,
Unfortunately, I do not know. I have not done any cross-domain JSON calls yet. Hmmm. Weird.
Posted by Ben Nadel on Mar 13, 2008 at 7:33 AM