I’ve been using the AjaxCFC library for years. It’s my preferred way of integrating Javascript and ColdFusion via AJAX. I’ve even modified it from its original form so that my implementation was strictly for integration with jQuery, only returns JSON strings (ignoring WDDX and simple string), and can work with ColdSpring.
Now that I’m a heavy user of the Sencha ExtJS framework, I thought it would be useful to port the jQuery.ajaxCFC.js file over to an Ext.AjaxCFC.js file that extended the native Ext.data.Connection class and utilized the Ext.Ajax object.
Took me about half the day, but I finally got a working Ext.AjaxCFC.request() method that uses the same syntax as the $.AjaxCFC() method. For those familiar with the inner workings and code of the jQuery AjaxCFC class, this will look very familiar.
So now I can make AJAX calls using native ExtJS classes, access ColdSpring beans in my application’s bean factory, or connect directly to any CFC
Ext.AjaxCFCConnection = Ext.extend(Ext.data.Connection, {
data : null,
queryFormat : 'array',
factory : (typeof(__ajaxConfig) == 'undefined') ? null : __ajaxConfig.beanFactory,
timeout : (typeof(__ajaxConfig) == 'undefined') ? 30000 : __ajaxConfig.defaultTimeout,
url : __ajaxConfig.url,
bean : null,
request : function(arguments) {
var params = (typeof(arguments.data) == 'undefined') ? {} : arguments.data;
arguments.params = {};
arguments.params['C0-ID'] = (Math.floor(Math.random() * 10001) + "_" + new Date().getTime()).toString(),
arguments.params['method'] = 'init';
arguments.params['component'] = arguments.component;
arguments.params['bean'] = (typeof(arguments.bean) == 'undefined') ? this.bean : arguments.bean;
arguments.params['factory'] = this.factory;
arguments.params['C0-METHODNAME'] = arguments.method;
arguments.params['queryFormat'] = (typeof(arguments.queryFormat) == 'undefined') ? this.queryFormat : arguments.queryFormat;
arguments.params['C0-PARAM0'] = params;
arguments.url = this.url + '?method=' + arguments.params['method'];
arguments.method = 'POST';
arguments.failure = arguments.error;
arguments.timeout = this.timeout;
var ____success = arguments.success;
arguments.success = function(data) {
data = data.responseText.replace(/^\s*|\s*$/g, '');
if (data.substring(0,9) == '__json__:') {
data = Ext.util.JSON.decode(data.slice(9));
}
____success(data, this);
};
if ( params ) {
if (typeof params != 'string') {
arguments.params['C0-PARAM0'] = Ext.util.JSON.encode(params);
}
}
Ext.Ajax.request(arguments);
}
});
Ext.AjaxCFC = new Ext.AjaxCFCConnection();
// Include Ext.AjaxCFC code
<script type="text/javascript" src="js/Ext.AjaxCFC.js"></script>
// Default configuration properties for the ajaxCFC library
__ajaxConfig = {
'url':'/myApp/ajaxCFC/ajax.cfc',
'defaultTimeout':30000,
'beanFactory':'application.beanFactory'
};
// AjaxCFC call using Ext.data.Connection class
Ext.AjaxCFC.request({
bean: 'AColdSpringBean',
method: 'aMethod',
data: {
'id': 416198,
'first_name': 'Steve',
'last_name': 'Brownlee'
},
success: function(details, s){
DataStore.loadData(details);
},
error: function(results){
Ext.MessageBox.alert('Search Failed', 'An unexpected error occurred. Please try again.');
}
});
It’s been a bit hectic at work in the last 2 years. Well, perhaps hectic isn’t the perfect word, but it’s close. Since I started working here, we’ve gone through two complete development technology stack switches.
Back in the halcyon days of 2007, I had the unenviable task of shoring up some very hastily written applications (by database developers and a couple of hacks who were here before me) using ColdFusion and HTML/Javascript. I beefed up the corporate offerings by implementing industry-accepted practices and patterns, used well-established libraries and got upgrades to the ColdFusion servers.
Then, in late 2008, the decision was made to scrap any future development of HTML/Javascript user interfaces and use Flex instead. That was exciting because of two reasons:
Fast forward to 2010 and now the entire company is rolling over to the .NET stack. Now I get to brush up on my rusty C# skills which I haven’t used in almost 4 years; I get to learn the ASP.NET MVC architecture; I get to have fun learning how to connect our .NET applications to our Oracle databases; lastly, I get to estimate how long it would take to convert our entire ColdFusion code base to .NET.
I’ll still get to work in ColdFusion from time to time, but .NET is the future…. for now. Perhaps 2012 will be the year we convert everything to Java!
I’m all for rolling with the punches and evolving my skill set to match what is needed for the organization to be successful, but I’m also no longer 24 years old with oodles of free time at my disposal (or the accompanying mental agility). Doing these massive switches takes a little more time at my venerable age.
With many developers these days writing web applications using popular Javascript libraries (e.g. Prototype or jQuery), many find themselves having to work with data objects in Javascript to enhance the user experience.
In a recent project, I was implementing a screen that required many popup dialog boxes, related Ajax calls, and periodic status updates to ensure a slick interface to the users without the need for any screen refreshes.
Without going into the nitty, gritty of the business reasons behind all the doo-dads I was creating, I reached a point where I needed to take ColdFusion queries and convert them to Javascript objects in order to push data from function to function.
To avoid further confusion, this function is simply a customization of the existing toScript() function available in ColdFusion (you can see I use it in my code below). What this does is allow you to customize the structure of the resulting Javascript object.
<cfcomponent displayname="QueryToObject" hint="Converts a ColdFusion query into a simple Javascript object" output="false">
<cffunction name="convert" displayname="convert" hint="Converts a query to a Javascript object" access="public" output="true" returntype="void">
<cfargument name="queryName" displayName="queryName" type="Query" hint="The ColdFusion query to be converted" required="true" />
<cfargument name="objectName" displayName="objectName" type="string" hint="The name of the resulting Javascript object" required="true" />
<cfargument name="idColumn" displayName="idColumn" type="string" hint="The unique identifier column of the query to be used in the Javascript object" required="true" />
<cfset var local = structNew() />
<cfset local.jsMappingStruct = StructNew() />
<cfprocessingdirective suppresswhitespace="true">
<script>
<cfloop query="arguments.queryName">
<cfloop from="1" to="#listLen(arguments.queryName.columnList)#" index="local.c">
<cfset local.colName = listGetAt(arguments.queryName.columnList, local.c) />
<cfset local.cell = arguments.queryName[local.colName][arguments.queryName.currentRow] />
<cfif isDate(local.cell)>
<cfset local.cell = dateFormat(local.cell, "mm/dd/yyyy") />
<cfelseif isNumeric(local.cell)>
<cfset local.cell = val(local.cell) />
</cfif>
<cfset local.jsMappingStruct[local.colName] = local.cell />
</cfloop>
#toScript(local.jsMappingStruct,arguments.objectName & arguments.queryName[arguments.idColumn][arguments.queryName.currentRow],true,false)#
</cfloop>
</script>
<cfreturn />
</cfprocessingdirective>
</cffunction>
</cfcomponent>
<cfset createObject("component", "utility.data.converters.javascript.QueryToObject").convert(steelers, "steeler.number_", "jerseyNumber") />
<script>
steelers.number_43= new Object();
steelers.number_43["first_name"] = "Troy";
steelers.number_43["last_name"] = "Polamalu";
steelers.number_43["position"] = "Safety";
steelers.number_43["nfl_ranking"] = "1";
</script>
A recent discussion with a colleague in San Diego led me to realize that, while I have a lot of seperate snippets of how to setup CF/JBoss, I never published a nice comprehensive, step-by-step post to show how to do it from start to finish.
This post is going to cover how to set up your server to run the JBoss Application Server – parsing ColdFusion code in its web apps. Future posts will cover how to set up JBoss AS/Apache/ColdFusion, and JBoss AS/JBoss WS/ColdFusion.
The first thing you need to do is download and/or run the ColdFusion installation package. During the installation wizard, ensure that you choose to install the J2EE/WAR installation type. When the installer is done, go to the installation directory in which you will see a cfusion.war file.
A WAR file (Web Application aRchive) is simply a ZIP archive, which means you can use whichever program you have for unzipping files. Simply unzip the archive into any location you choose. When done, you will have three directories:
The only two you will be interested in are the WEB-INF and CFIDE directories. You can safely delete the META-INF directory.
Now you can download and install the version of JBoss that you want to run your applications. Installation is as easy as unzipping the downloaded ZIP file to the directory from which you want to run JBoss. When done, you’ll have the following directory structure:

Notice the SAR and WAR directories under the deploy directory. You need to create one for your new web application. For example, if your application is the website for www.widgets.com, simply create a widgets.war directory.

Remember the WEB-INF and CFIDE directories you unpacked previously, well now we need them. Copy them from their current location to your new widgets.war web application directory. Amazingly, you are almost done! These two directories are all that is needed to get a JBoss web app to parse ColdFusion files.

Now, here’s where you need to determine how JBoss is going to serve your Widgets application. This is done by creating a jboss-web.xml file inside the widgets.war\WEB-INF directory.

If the Widgets application is the only application you want to server from JBoss, or it is going to be your root application – in both cases, what you want served when someone hits www.widgets.com – you specify this application as the root application. This is what the jboss-web.xml file would look like.

However, if you want this application to be a subdirectory off of your root, you would specify that subdirectory name in the jboss-web.xml file.

The last thing you might need to do – if JBoss is functioning as your main web server – is change the port on which JBoss is listening. For this, you need to look inside the deploy\jbossweb-tomcat50.sar\server.xml file.

The very first setting in this file is the port on which Tomcat is listening for HTTP requests. The default value is 8080, but if JBoss is your default web and application server, you will need to change the port attribute value to 80.

This is the most basic configuration for JBoss / ColdFusion. After completing these steps, you can start your JBoss instance and hit your designated URL and ColdFusion files will light up.
For more advanced configurations of JBoss, here are some links to other relevant posts.
Running multiple ColdFusion instances
Securing your JBoss web applications
Hosting multiple domains in JBoss
Flexible ColdFusion deployment – serving from anywhere