(For more resources on ColdFusion, see here.)
Each of our shared scopes has a life span. They come into existence at a given point, and cease to exist at a predictable point. Learning to recognize these points is very important. It is also the first aspect of "Scope".
The request scope is created when a request is made to your ColdFusion server from any source. This could either be a web browser, or any type of web application that can make an HTTP request to your server. Any variable placed into the request structure persists until the request processing is complete.
Variable persistence is the property of data remaining available for a set period of time. Without persistence, we would have to make information last by passing all the information from one web page to another, in all forms and in all links. You may have heard people say that web pages are stateless. If you have passed all the information into the browser, they would be closer to stateful applications, but would be difficult to manage. In this article, we will learn how to create a stateful web application. Here is a chart of the "life spans" of the key scopes:
|Request||Begins when a server receives a request from any source.
Created before any session or an application is created.
|Ends when the processing for this request is complete.
Ending has nothing to do with the end of applications or sessions.
|Application||Begins before a session but after the request.
Begins only when an Application.cfc file is first run with the current unique application name, or when the <cfapplication> tag is called in older code CF applications.
|Ends when the amount of time since a request is greater than the expiration time set for the application.|
|Session||Begins after an application is created.
Created inside the same sources as the application.
|Ends when the amount of time since a request is greater than the expiration time set for the session.|
|Client||Begins when a unique visitor first visits the server.||If you want them to expire, you can store client variables in encrypted cookies. Cookies have limited storage space and are not always available.|
We will be discussing the scopes in more detail later in this article series.
All the scopes, except the client scope, expire if you shut down your server. When we close our browser window or reboot the client side, a session does not come to an end, but our connectivity to that particular session scope ends. The information and resources for storing that session are held until the session expires. Then, when connecting the server starts a new session and we are unable to reconnect to the former session.
Introducing the Application.cfc object
The first thing we need to do is to understand how this application page is called. When a .cfm or .cfc file is called, the server looks for an Application.cfc file in the current directory where the web page is being called from. It also looks for an Application.cfm file. We do not create an application or session scope with the .cfm version because .cfc provides many advantages and is much more powerful than the .cfm version. It provides better encapsulation and code reuse. If the application file is found, ColdFusion runs it. If the file is not found, then it moves up one directory towards the sever root directory in order to search for an Application.cfc file. The search stops either when a file is found, or once it reaches the root directory and a file is not found.
There are several methods in the Application.cfc file. It is worth noting that this file does not exist by default, the developer must create it. The following table gives the method names and the details as to when those methods are called:
|Method name||When a method is called|
|onApplicationEnd||The application ends; the application times out.|
|onApplicationStart||The application first starts: the first request for a page is processed or the first CFC method is invoked by an event gateway instance, a web service, or Macromedia Flash Remoting CFC.|
|onCFCRequest||HTTP or AMF (remote special Flash) calls.|
|onError||An exception occurs that is not caught by a try or catch block.|
|onMissingTemplate||ColdFusion receives a request for a non-existent page.|
|onRequest||The onRequestStart() method finishes(this method can filter request contents).|
|onRequestEnd||All pages in the request have been processed.|
|onRequestStart||A request starts.|
|onSessionEnd||A session ends.|
|onSessionStart||A session starts.|
|onServerStart||A ColdFusion server starts.|
When the Application.cfc file runs for the first time, these methods are called in the order as shown in the following diagram. The request variable scope is available at all times. Yet, to make the code flow right, the designers of this object made sure of the order in which the server runs the code. You will also find that for technical reasons, there are some issues that arise when we use the onRequest() method. Therefore, we will not be using this method.
The steps in the previous screenshot are explained as follows:
- Browser Request: The browser sends a request to the server. The server passes the processing to the Application.cfc file, if it exists. It skips the step if it does not exist. The Application.cfc file has methods that execute if they exist too. The first method is onApplicationStart(). This executes on the basis of the application name. If the unique named application is not currently running on the server, then this method is called.
- Application Start: The next thing that Application.cfc does is to check if the request to the server is a pre-existing application. If the request is to an application which has not started, then it calls the onApplicationStart() method, if the method exists.
- Session Start: On every request to the server, if the onSessionStart() method exists, then it is called at this particular point in the processing.
- Request Start: On every request to the server, if the onRequestStart() method exists, then it is called at this particular point in the processing.
- OnRequest: This step normally occurs after the onRequestStart() method. If the onRequest() method was used, then by default it prevented the calling of CFCs. We do not say that it is always wrong to use this method. However, we will avoid it as much as possible.
- Requested Page: Now, the actual page requested is called and processed.
- Request End: After the requested page is processed, the control is passed back to the onRequestEnd() method, if it exists in Application.cfc.
- return response to browser: This is the point when ColdFusion has completed its work of processing information to respond to the browser request. At this point, you could either send HTML to the browser, a redirect, or any other response.
- Session End: The onSessionEnd() method is called if the method exists but only when the time since the user has last made a request to the server is less than the time for the session timeout.
- Application End: The onApplicationEnd() method is called if it exists when the time since the last request was received by the server is greater than the timeout for the application.
The application and session scopes have already been created on the server and they do not need to be reinitialized. Once the application is created and other requests are made to the server, the following methods are called with each request:
In previous versions of ColdFusion, when the onRequest() method of the Application.cfc was called, it blocked CFCs from operating correctly. You may see some fancy code in older frameworks that check if the current request is calling a CFC. They would then delete the onRequest() method for that request. Now there is a new method called onCFCRequest(). If you need backwards capability to previous versions of ColdFusion, then you would delete the onRequest() method. You can use either of these approaches depending on whether you need the code to run on prior versions of ColdFusion. The onCFCRequest() method will execute at the same point as the onRequest() method in the previous examples. You can add this code in or not depending on your own preferences. The previous example still operates as expected if you leave the method out.
The OnRequestEnd.cfm side of using Application.cfm based page calls does not execute if the page runs a <cflocation> tag before the OnRequestEnd.cfm is run. It is also not a part of Application.cfc based applications and was intended for use with Application.cfm in older versions of ColdFusion.
Here is a representation of the complete process that is less granular. We can see that the application behaves just as it did in the earlier illustration; we just do not go into explicit detail about every method that is called internally. We also see that the requested page can call additional code segments. These code segments can be a CFC, a custom tag, or any included page. Those pages can also include other pages, so that they create a proper hierarchy of functionality. Always try to make sure that functionality is layered, so the separation of layers provides a structured and simpler approach to creation, maintenance, and long-term support for your web applications.
The variables set in Application.cfc can be modified before the requested page is called, and even later. Let us say for example, you want to record the time at which the session was last hit. You could choose to set a variable, <cfset session._stat.lasthit = now()>. This could be set either at the beginning of a request, or at the end. Here, the question is where you would put this function. At first, you might think that you would add this function to the OnSessionStart() method or OnSessionEnd() method. This would cause an issue because these two methods are only called when a session has begun or when it has come to an end. You would actually put the code into the OnRequestStart() or OnRequestEnd() code segment of the Application.cfc file for the function to work properly. The request methods are called with every server request. We will have a complete Application.cfc to use as a model for creating our own variations in future projects. Remember to place the code in the right place and test your code using CFDump or by some other means to make sure it works when creating changes.
(For more resources on ColdFusion, see here.)
There are some application variables that determine the behavior of an application. Inside the application, all the variables are stored inside this scope. The scope refers to the location where the .cfc file is found. Generally, this is not considered a good practice because the variables are not protected from outside the object. In Application.cfc, this is not an issue because there is no code to create an instance of the object for reuse. The following are the application scoped variables in Appliation.cfc that you will use.
|name||no name||This is the application name. If you do not set this variable, or set it to the empty string, your CFC applies to the unnamed application scope, which is the ColdFusion MX J2EE servlet context.|
|applicationTimeout||Administrator value||Life span, as the actual number of days of the application, including all Application scope variables. Use the CFML CreateTimeSpan function to generate this variable's value.|
|clientManagement||Administrator value||Checks whether the application supports Client scope variables.|
|clientStorage||Administrator value||Client variables are stored here. Client variables can be cookie, registry, or the name of a data source.|
|customTagPaths||Administrator value||Contains ColdFusion custom tag paths. To use this variable, set the custom tag path in the Administrator EXTENSIONS | Custom Tag Paths page. The settings that you define here take precedence over the custom tag paths defined in the Administrator SERVER SETTINGS | Mappings page for the current application.|
|debugIPAddress||Overrides the default administrator settings. It does not report compile-time exceptions.|
|enableRobustException||Overrides the default administrator settings. It does not report compile-time exceptions.|
|googleMapKey||The Google Maps API key required to embed Google Maps in your web pages.|
|datasource||Name of the data source from which the query retrieves data.|
|loginStorage||Cookie||Whether to store login information in the Cookie scope, or the Session scope.|
|mappings||Administrator value||A structure that contains ColdFusion mappings. Each element in the structure consists of a key and a value. The logical path is the key and the absolute path is the value. To use this value, select the Enable Per App Settings option in the Administrator SERVER SETTINGS | Settings page.|
|serverSideFormValidation||yes||Whether to store login information in the Cookie scope or the Session scope.|
|sessionManagement||no||Checks whether the application supports Session scope variables.|
|sessionTimeout||Administrator value||Life span, as the actual number of days, of the user session, including all session variables. Use the CFML CreateTimeSpan function to generate this variable's value.|
|setClientCookies||true||Whether to send CFID and CFTOKEN cookies to the client browser.|
|setDomainCookies||false||Whether to set CFID and CFTOKEN cookies for a domain (not just for a host).|
|scriptProtect||Administrator value||Whether to protect variables from cross-site scripting attacks.|
|secureJSON||Administrator value||A Boolean value that specifies whether to add a security prefix to a value that the ColdFusion function returns in JSON-format, in response to a remote call. The default value is the value of the Prefix serialized JSON setting in the Administrator SERVER SETTINGS | Settings page (which defaults to false).You can override this value in the <cffunction> tag.|
|A struct that contains the following values: server, username, and password. If no value is specified, takes the value of the administrator.|
|timeout||The lifespan. Timeout set using <cfsetting requesttimeout=""> overrides the timeout in Application.cfc using this.timeout-"".|
|A comma-delimited list of names of the files. It tells ColdFusion not to call the onMissingTemplate() method if the files are not found. Use this variable to prevent ColdFusion from invoking the onMissingTemplate() handler if all of the following items are true:
The following is an example of setting some application variables as might be done in an Application.cfc file:
this.name = "ApplicationName1";
this.applicationTimeout = createTimeSpan(0,2,0,0);
this.clientManagement = true;
this.clientStorage = "cookie;
this.loginStorage = "session";
this.sessionManagement = true;
this.sessionTimeout = createTimeSpan(0,0,20,0);
this.setClientCookies = true;
this.setDomainCookies = false;
this.scriptProtect = false;
This is just an example as to how we could set these variables. There is never a special way to do this. For each site, we should consider a particular format or method that makes the most sense for how we want these settings. The type of work done by some people may mean that they end up using the same settings all the time. That is also fine, as long as, we remember to think about getting the settings right.
In this article we covered the life expectancy for various types of information, Application.cfc object class and the application variables. In the next article we will see Application, Session, and Request Scope in ColdFusion 9
- ColdFusion 9 Developer Tutorial [Book]
- ColdFusion 9: Power CFCs and Web Forms [Article]
- Application, Session, and Request Scope in ColdFusion 9 [Article]