Application.cfc

Application.cfc is a richer alternative to Application.cfm, giving you hooks into various states and life cycle points of an application and request. Packaged as a standard CFC, you override the methods you wish to provide processing for and the engine will take care of the rest.

As with any other CFC, this component can be overridden, subclassed and reused. There is very little restrictions as to what you can do with this particular component. The location of this file is the same as the Application.cfm, in that, OpenBD will look for it in the same directory as the requesting template and continue up the parent directory stack until it finds one. Please note the case of this file is very important - the capital "A" is required.

Application.cfc reduces the complexity of managing cfApplication's as you do not have to worry about complicated locking techniques to avoid initialization duplicates at startup if multiple requests hit it at once. By utilising the Application.cfc method, you do not require any CFAPPLICATION tag.

Method Hooks

The following methods can be defined:

  • onApplicationStart()
    Called when the application is first initialized. This method will only be called once.
  • onApplicationEnd()
    Called when the application is being unloaded due to inactivity. This method will only be called once.
  • onClientStart()
    Called when the client request is found not to previously exist and has just been freshly created. This method is only valid if the client management has been enabled for this application.
  • onSessionStart()
    Called when the session request is found not to previously exist and has just been freshly created. This method is only valid if the session management has been enabled for this application.
  • onSessionEnd( session, appdata )
    Called when the session has ended, passing in the current session and application data that was part of this session
  • onError( catchdata, eventname )
    If an error occurs within the application, then this method is called passing in the catchdata and the eventname of the error.
  • onRequest( pageuri )
    Used when you want to replace the processing for a given template. If this method is found then the calling template will not be called.
  • onCFCRequest( cfcname, cfcmethod, args )
    Used when you want to replace the processing for remote CFC methods. If this method is found then the CFC will not be called but instead this method.
  • onRequestStart( pageuri )
    Called when a request has just come in and is ready for processing. Called before the template.
  • onRequestEnd( pageuri )
    Called when a request has completed and is called after the requesting template has fininshed.
  • onMissingTemplate( pageuri )
    Called when a request for a missing template is made.
  • onMissingMethod( methodName, methodArguments )
    If a call is made to a method that is not found, then this method is then triggered passing in the relevant method arguments and name.

Defining cfApplication Properties

The standard cfApplication has properties that are associated with it and these are historically defined using the attributes of the CFAPPLICATION tag. This tag is not required when using the Application.cfc method. Instead, you define the properties of the cfApplication as top level object variables, using CFSCRIPT or CFSET.

  • this.name
    Defines the name of the cfApplication; this is just a plain string value
  • this.scriptprotect
    This boolean determines if the script protection layer is enabled
  • this.mappings
    This structure contains the mappings for this application
  • this.customTagPaths
    This is a string denoting the list of paths that will be searched before the standard custompath
  • this.applicationtimeout
    This is the length of time, defined as a factor of a date (use CreateTimeSpan()) that this application will be available in memory after no requests are made to it.
  • this.sessiontimeout
    This is the length of time, defined as a factor of a date (use CreateTimeSpan()) that this session will be available in memory after no requests are made to it.
  • this.setclientcookies
    This boolean controls whether or not client cookies will be used.
  • this.sessionmanagement
    This boolean controls whether or not session management is enabled.
  • this.sessionstorage
    This is the URI connection string to where the session data can be stored. See the section below on the session storage
  • this.setdomaincookies
    This boolean controls whether domain cookies will be used instead of full server name cookies.
  • this.clientmanagement
    This boolean controls whether or not client management is used.
  • this.clientstorage
    This string controls the client storage method. Valid values are: COOKIE, REGISTRY or DATASOURCE
  • this.loginstorage
    This string controls the login storage method. For use with CFLOGIN
  • this.securejson
    This boolean controls whether or not SecureJSON feature is used in WebServices communications.
  • this.securejsonprefix
    If the secure JSON flag is set, this variable lets you define the prefix that will be used for the JSON prefix.
  • this.datasource
    The default datasource for this application that CFQUERY/CFSTOREDPROC/QueryRun() will use if one is not explicitly defined.

Session Storage - Cluster/Enterprise

By default, session objects are stored within the server they are running. If you have a cluster of machines, then sharing sessions across the servers is impossible unless you use the underlying J2EE session management facilities. However, this has a number of problems. Firstly the J2EE server you are running OpenBD upon may not easily or quicly support session sharing in a manner that would allow you to operate. For example, some implementations rely on technologies (multicast) that are not able to run in certain cloud implementations (Rackspace/Amazon). Secondly, the J2EE session management is not as powerful as that on offer, and you expect, from the CFML world.

OpenBD makes it easy to make your applications run across multiple servers seemlessly without you have to worry about the logistics of moving the session scope around.

You have the choice of using the following storage engines:

  • Default in memory
  • J2EE Session Management
  • Memcached/CouchBase servers (this.sessionstorage = 'memcached://10.0.0.1:11211';)
  • MongoDB servers (this.sessionstorage = 'mongo://10.0.0.1:27017';)

Memcached/CouchBase Configuration

You can easily use a remote farm of Memcached (or CounchBase) servers by specifying the connection URI: memcached://server1:27017 server1:27017

MongoDB Configuration

More efficient than Memcached is the MongoDB storage engine. Sessions are loaded and saved to remote MongoDB servers (configured in a replic or sharded set). Sessions that have not changed, are efficiently handled as to not incurr the overhead of always moving data around. With the MongoDB connection URI, you can specify the Mongo database to use, though it defaults to 'openbd' with the collection 'sessions'.

The connection string format is: mongo://[user@pass:]server1:port1 server2:port2[/db]. Examples:

  • mongo://10.0.0.1:27017
  • mongo://user1@pass1:10.0.0.1:27017
  • mongo://10.0.0.1:27017 10.0.0.2:27017
  • mongo://10.0.0.1:27017 10.0.0.2:27017/CustomDB
  • mongo://user1@pass1:10.0.0.1:27017 10.0.0.2:27017/CustomDB

Notes

  • The complete 'session' scope is stored in the remote storage
  • All data types; simple, struct, queries, arrays and loaded objects are supported
  • For the best performance keep the amount of data held in the session to a minimum
  • The bluedragon.log file will detail any errors with connections that may happen; if a connection is loss, the session will be reset

Sample Application.cfc

The following is a short sample of a Application.cfc that may be used.

<cfcomponent>

  <cfset this.name = "myApplication">

  // alternatively you can do this inside a cfscript block
  <cfscript>
    this.sessionmanagement = false;
    this.clientmanagement = false;
  </cfscript>

  <cffunction name="onApplicationStart">
    // your code to initialise the variables that will go in "application" scope
    <cfset application.datasource = "myDatasource">
  </cffunction>

  <cffunction name="onRequestStart">
    <cfargument name="requesturi" required="true"/>
  </cffunction>

</cfcomponent>