Posts
1-10 of 16
| Next>
| Last>>
About CFScript
Thread posted on Apr 03 by
Tayyab Hussain
Title: About CFScript
Content: CFScript is a language within a language. It is a scripting language that is like JavaScript but is simpler to use. Also, unlike JavaScript, CFScript only runs on the ColdFusion server; it does not run on the client system. CFScript code can use all the ColdFusion functions and expressions, and has access to all ColdFusion variables that are available its scope.
CFScript provides a compact and efficient way to write ColdFusion logic. Typical uses of CFScript include the following:
-
Simplifying and speeding variable setting
-
Building compact JavaScript-like flow control structures
-
Creating user-defined functions
Because you use functions and expressions directly in CFScript, you do not have to surround each assignment or function in a cfset tag. Also, CFScript assignments are often faster than cfset tags.
CFScript provides a set of decision and flow-control structures that are more familiar than ColdFusion tags to most programmers.
In addition to variable setting, other operations tend to be slightly faster in CFScript than in tags.
You can use CFScript to create user-defined functions, or UDFs (also known as custom functions). You call UDFs in the same manner that you call standard ColdFusion functions. UDFs are to ColdFusion built-in functions what custom tags are to ColdFusion built-in tags. Typical uses of UDFs include data manipulation and mathematical calculation routines.
You cannot include ColdFusion tags in CFScript. However, some functions and CFScript statements are equivalent to commonly used tags. For more information, see Tag equivalents in CFScript.
Comparing tags and CFScript
The following examples show how you can use CFML tags and CFScript to do the same thing. Each example takes data submitted from a form and places it in a structure; if the form does not have a last name and department field, it displays a message.
Code: Using CFML tags
cfif IsDefined("Form.submit")> <cfif (Form.lastname NEQ "") AND (Form.department NEQ "")> <cfset employee=structnew()> <cfset employee.firstname=Form.firstname> <cfset employee.lastname=Form.lastname> <cfset employee.email=Form.email> <cfset employee.phone=Form.phone> <cfset employee.department=Form.department> <cfoutput> Adding #Form.firstname# #Form.lastname#<br> </cfoutput> <cfelse> <cfoutput> You must enter a Last Name and Department.<br> </cfoutput> </cfif> </cfif>
Using CFScript <cfscript> if (IsDefined("Form.submit")) { if ((Form.lastname NEQ "") AND (Form.department NEQ "")) { employee=StructNew(); employee.firstname=Form.firstname; employee.lastname=Form.lastname; employee.email=Form.email; employee.phone=Form.phone; employee.department=Form.department; WriteOutput("Adding #Form.firstname# #Form.lastname# <br>"); } else WriteOutput("You must enter a Last Name and Department.<br>"); } </cfscript>
CF10- XMLsearch() & XMLTransform() now support Xpath 2
Thread posted on Mar 08 by
Tayyab Hussain
Title: CF10- XMLsearch() & XMLTransform() now support Xpath 2
Content: We don't often work with XML now, most of the data exchange is done through JSON. Most of the APIs that supported XML and JSON said XML is still a data type that will inevitably be a part of our lives for some time are now dropping XML support. That's why it's actually kind of exciting that ColdFusion 10 now supports XPath 2.0 in the xmlSearch() and xmlTransform() functions. I agree that I am decades behind developers who rule the web, but sill, after some Googling I worked out to put forward a demo of the functionality that is now available in ColdFusion 10.
XPath is used to navigate through elements and attributes in an XML document. XPath is a major element in W3C's XSLT standard - and XQuery and XPointer are both built on XPath expressions.
Code: <!--- Create an XML document on which to test new XPath 2.0 functionality support. ---> <cfxml variable="bookData">
<books> <book id="101" rating="4.5"> <title>ZAVIA</title> <author>Ashfaq Ahmad</author> <published>Sep 1, 2004</published> <isbn>9693515870</isbn> </book> <book id="201" rating="4"> <title>Butt Parey</title> <author>Dr. Younis Butt</author> <published>November 1, 2007</published> <isbn>9693510151</isbn> </book> <book id="301" rating="4.5"> <title>KHARMASTIAN</title> <author>DR.MUHAMMAD YOUNAS BUTT</author> <isbn>9693510488</isbn> </book> </books>
</cfxml>
<!--- Groovy - now let's execute some XML Path queries. ---> <cfscript>
// Get all of the ratings that are greater than or equal to 4.5. results = xmlSearch( bookData, "//book/@rating[ number( . ) > 4.0 ]" );
// Get the average rating of the reviews. results = xmlSearch( bookData, "avg( //book/@rating )" );
// Get a compoud result of the Title and Author notdes. Notice // that we can now create divergent results in the SAME path. // We don't need to create two completely different paths. results = xmlSearch( bookData, "//book/( title, author )" );
// Get all of the book's children EXCEPT for the ISBN number. // XPath 2.0 introduces some intesting operators like "except", // "every", "some", etc. results = xmlSearch( bookData, "//book/( * except isbn )" );
// XPath 2.0 now uses sequences instead of node-sets which allow // for more interesting data combinations. This only gets the // nodes from one collection that are NOT in the other collection. // We're using inline branching and merging! results = xmlSearch( bookData, "//book/( (title, published) except (isbn, published) )" );
// Get all of the ISBN numbers that use a 10-digit ISBN. XPath // 2.0 now supports regular exprdssion functions like matches(), // replace(), and tokenize() -- thought it is quicky and a // bit limited in patterns. results = xmlSearch( bookData, "//book/isbn[ matches( text(), '^\d{10}$' ) ]" );
// Iterate over one collection and map it onto the resultant // collection. We can now iterate inline within a path. results = xmlSearch( bookData, "for $b in (//book) return ( $b/published )" );
// We can now pass in params into our xmlSeach() calls. Notice // that the key, "title" is quoted - that is because XPATH is // case-sensitive. results = xmlSearch( bookData, "//book/title[ . = $title ]", { "title": "KHARMASTIAN" } );
// Get the given book, no matter what the casing. FINALLY, we // can case-insensitive searching in XML :) results = xmlSearch( bookData, "//book[ upper-case( title ) = 'Butt Parey' ]" );
// Debug the results. writeDump( results );
</cfscript>
CF10-HTML5 Video
Thread posted on Apr 09 by
Tayyab Hussain
Title: CF10-HTML5 Video
Content: With Coldfusion 10, we deep dive into the world of HTML5 video support through the CFMEDIAPLAYER tag
Then(CF 9) : The cfmediaplayer tag could only support Flash videos,the likes of flv,f4v.
Now (CF 10): The cfmediaplayer can now support HTML 5 videos , the likes of mp4,ogv,webm ; formats conditioned for video playback over the internet.These require no additional plugins. You can skin/style the player,use Javascript functions ,set event handlers and even set a customised title !
More on all that later!!
Snippet #1: Just specify your HTML5 video in the source attribute of the cfmediaplayer tag
|
<cfmediaplayer name="player1" source="sample_webm.webm" />
|
Play the snippet in Firefox or Chrome to view the webm video
Alternately , you can use ColdFusion.MediaPlayer.setSource() method and add to your existing code.
Snippet #2 : Use the all new "type" attribute to tell your browser whether to play the same video as flash or HTML. This is pretty useful when you want to enforce a particular type of content to be sent to the client. MP4 videos can play as flash and HTML videos. This essentially means that if you try to play an MP4 video with flash enabled,you see a flash player loaded (right click on the player and observe the "About Flash Player" info ) and when flash is disabled the HTML% player is loaded
Try this in Chrome to see the difference:
|
<cfmediaplayer name="player2" source="sample_mp4.mp4" type="html" />
<cfmediaplayer name="player3" source="sample_mp4.mp4" type="flash" />
|
The Flash and HTML5 players have been designed to look as identical as possible so as to support seamless fallback.
Snippet #3: Use the HTML source tag to set multiple videos as sources to the cfmediaplayer tag and let ColdFusion handle the video playback depending on video support by the browser
|
<cfmediaplayer name="player4" source="sample_webm.webm" type="html">
<source src="sample_mp4.mp4" type="video/mp4" />
</cfmediaplayer>
|
Now play the snippet in IE9,Firefox,Chrome and Safari .
You will see : IE9 and Safari5 : playing sample_mp4.mp4 in HTML because it currently doesnt support WEBM Firefox and Chrome : playing sample_webm.webm
A few things to consider :
1)Use the <!DOCTYPE html > and the <head/> <body> tags to write your cfm page for best results. A few browsers will not render the player properly otherwise! 2)Can't play your video ? Are you using a web server ? Then make sure the right mime-types are added so that content can be served to the client. 3)Video playback is subject to browser support for formats,codecs and rendering.
File: sample_webm.webm (9.78 Mb)
Coldfusion 10
Thread posted on May 16 by
Tayyab Hussain
Title: Coldfusion 10
Content: Coldfusion 10 Finally is Public
Image:
ColdFusion 10 - Secure you application
Thread posted on May 22 by
Muhammad Iftkhar
Title: ColdFusion 10 - Secure you application
Content:
- Additional / Improved Encoders: Proper XSS protection requires escaping/encoding untrusted output that is rendered in the browser to prevent arbitrary code from running and being used to exploit other user. In the past ColdFusion developers have used the built in functions HTMLEditFormat(), XMLFormat(), URLEncodedFormat(), and JSStringFormat() for these purposes. And while they work in some situations, they were not designed for security purposes and cannot be used to cover all bases.
It would be nice to have encoders designed with security in mind that would cover all of the contexts that need to be protected (HTML content, HTML attribute, CSS, JavaScript, URL) and even to have encoders to prevent other types of injection attacks (LDAP, Windows Command Line, Unix Shell, etc). The ESAPI for JEE Project actually has all of these encoders available and they can be added to your current ColdFusion installations quite easily, but it would be ideal to have them built in. It might have encoder tags. Just like:
| <cfencode type="HTML">#untrustedInput#</cfencode> |
OR
| <cfhtmlformat>#untrustedInput#</cfhtmlformat> |
Again, this is currently available in the ESAPI project as a JSP tag library and can be used easily within ColdFusion now, but would be nice to have built in.
<cfimport taglib="esapi.tld" prefix="esapi"> <esapi:EncodeForHTML> <testing>&$;/"''"</testing> </esapi:EncodeForHTML> |
- CSRF Protection: This is one that I have thought a lot about, but I struggle with thinking of the best way to implement it. CSRF protection is an easy way for developers to create a CSRF token, add it to a persistent scope, include it in a form post, and then verify it when appropriate.
For instance, when a user is creating a form, it might look something like this:
<form action="index.cfm?event=deletePage" method="POST"> <cftoken scope="session" key="deletePage" /> <input type="hidden" name="pageid" value="#pageid#" /> </form> |
Then when the page is rendered, that cftoken tag would automatically create a token/nonce, place it into session.tokens.deletePage and create a hidden form field inside of the <form> (with a default name of csrfToken). Then, on the receiving end, either directly inline in the code, or perhaps in an AOP interceptor, have something like:
| <cfset validToken = checkToken(form.csrfToken) /> |
I'm not sure if it is a good idea or not, I feel like it is, but I would like to see checkToken() have a second parameter for "throw".
| <cfset validToken = checkToken(name=form.csrfToken, throw=true) /> |
If throw was set to "false" then the function would return a boolean. If throw was true, then it would throw an exception if the result was false.
- Additional Session SSL Token: This idea actually comes from Mary Jo Sminkey. We had several conversations about session management some time ago. The reason for this idea is because it is not a straight forward task to have a partially SSL protected site.
Let's look at a scenario to better describe this one. Say you have an ecommerce site that:
-
- Allows you to browse for merchandise
- Allows you to put merchandise into a cart and then purchase it online
- Allows you to edit your account settings
- Allows you to interact with other customers in a forum
Now in this situation above, you probably only want to perform items numbers 2 and 3 over SSL. Using SSL for the items 1 and 4 would work, but SSL is slower and has more overhead, so on a very active site, you'd probably want to limit the amount of time your users spending on an SSL connection. Now switching between SSL and Non-SSL is pretty easy (http:// vs. https://). The hard part is dealing with your session token cookie(s). Briefly, if your user's session token is compromised by a malicious user, their session can be hijacked and the hacker can impersonate the user on your site. If you browse our hypothetical ecommerce site over a non-SSL connection, your session token is sent over EVERY unencrypted request. So it is being exposed to everyone who knows how to see it (which is more than you would guess). So if one of your users in a Starbucks surfing on their unprotected Wifi and looking at your commerce site, they are exposing their session token on every request while browsing for merchandise. Even a simpleton attacker could pluck that session token out of the air and hang onto it. Once your user decided on their purchase and logged in to complete it, the hacker would then browse to your site after manually creating a session token cookie to match the one he stole from your user. He would then be logged in to your site as your user. Yes, it really is that easy. There are a few ways to stop this type of attack.
-
- You could simply place your whole site on SSL, but as we already discussed, this could cause performance problems.
- You could have the secure sections of the site be a separate ColdFusion application with a different session token.
- You could change the user's session token when they switch to SSL. But then you have to worry about transferring all of the user's data from the old session to the new one. You would also need to be able to switch it back if the user decided to Shop >> Login >> Shop some more >> Edit account settings >> Shop some more >> beging checkout >> change mind and shop more >> finally complete checkout. I know that's how I shop.
- When the user logs in and tries to access a secured part of the site (i.e. Checkout, account settings) then you have them re-authenticate. Upon re-authentication, you assign them a second token. This token, just like the session token, will be sent over EVERY request. But this new token will have the SECURE flag set on it, which means it will only be sent over every SSL request. On non-SSL requests, the browser will not send the new token, which means the attacker will never see it in-the-clear. Then on the server, for every request to a secured area you would check THAT token for authorization.
Option #4 above is what I mean when I say "Additional Session SSL Token". If there was some way to implement this type of functionality in ColdFusion, that would, I think, be a big benefit to sites that need to have only certain sections protected by SSL. I don't think the second token would need to be a whole second session scope, it would be more of a pseudo-session id for access control, although having a separate secure Session scope might work too, I'd have to give that some thought.
- Improved Logging: I don't think that many people realize how big a piece of a solid security plan logging is. Logging is a VERY important part of security. And the more logging you can do, the better. For those interested in PCI-DSS, you'll need to know that logging is a HUGE part of achieving that compliance.
We should be logging all sorts of activity that we probably are not. Login attempts, user activity, system changes, user account changes, administrator activity, and more. Logging serves a few purposes.
-
- Logs, of course, serve as a tool for debugging. Typically that is what we use them for, but many times only during development. Then when we put those apps into production, we minimize the amount of logging we do for performance reasons. It would be nice if we did not need to do that.
- Logging can help you discover where your application is being attacked. Web server logs can help with that, but custom logs can be a much better source of information. With proper logging and log analysis, you can detect attacks that you would not have otherwise known about.
- Logs can be offered as evidence to the authorities that you might call in the event of a breach. They can be used to help an investigation and could even help in the courtroom, if admissible.
Having improved logging, both in performance and features, would go a long way in the next version of ColdFusion, I think. Features like asynchronous logging in <cflog>, custom log locations, and maybe even some alerts for certain keywords or events would be great.
- invalidate() for CF Sessions: One of the AWESOME features of using JEE sessions in ColdFusion is the ability to instantly invalidate an existing session by calling invalidate() on it. This allows the developer to programmatically invalidate a session so that it can no longer be used and without having to wait for the session to time out.
It would be nice to have the same ability with ColdFusion sessions.
- Easy session key rotation: There are certain times in our applications when a user should be given a new session instead of continuing the use of an old one (for example, after they move from an un-authenticated state to an authenticated state). Right now, there is not an easy way to do that. It would be nice to have a single function that can "rotate" their session to a new one. Essentially, it would need to:
- Create a new session
- Copy all the data from the old session to the new one
- Invalidate the old session (optionally)
- Invalidate or overwrite the old session cookies
- If old cookies are invalidated, create new session cookies
- Built-In Indirect Object Reference Map: One of the OWASP Top 10 security risks is insecure direct object reference. One way of solving the problem of insecure direct object reference is to use an Object Reference Map. An Object Reference Map is essentially a structure or hashmap that resides in memory, typically in the session scope. A direct reference to an object (i.e. fileid=12 or userid=1) can be mapped to an indirect reference to that object (i.e. a random number or UUID). Then any page that needs to reference that object will use the indirect reference instead of the direct one. On the back-end the system can link the indirect reference to the actual object through the reference map.
Having an object reference map and some utility functions to use with it could make this process much easier.
- Remove Insecure Defaults: I know backward compatibility is important to Adobe and that they don't want an upgrade to break existing installations, but insecure defaults are JUST BAD and they should be changed.
Some of the insecure defaults in ColdFusion are:
-
- Not having "Use UUID for cftoken " checked
- Not checking Enable Global Script Protection(Even though Global Script Protect offers very little protection, it's better than nothing, improving Global Script Protect as Pete suggested would help this suggestion carry more water.)
- Disable Flash Remoting by default.
- Make it easier to change the name of the Admin user
- Limit DSN default privileges to CRUD (Remove GRANT, REVOKE, etc)
- Other insecure defaults that may exist.
- Add iterations argument to hash(): There has been some discussion over whether or not iterating over password hashes will actually improve security or not. There are not many people with the skills to determine whether or not it really makes a difference(me included). But all of the guidance I have seen from "the experts" indicates that it should be done. What I propose here is to simply add a third, optional argument to the existing hash() function to indicate a number of times the hash should be iterated.
For example,
| <cfset hashedPass = hash(password & salt, "SHA-256", 3) /> |
would be the same as doing this:
| <cfset hashedPass = hash(hash(hash(password & salt, "SHA-256"), "sha-256"), "sha-256") /> |
Except that the actual code we would be using might be more like this:
| <cfset hashedPass = hash(password & salt, "SHA-256", 75000) /> |
- Add a security course to the ColdFusion training and education curriculum: Training is an important part of a developers education and the existing security training resources fall short of what developers really need.
I can see that the course designers really tried to include security information in their courses, and I suspect that for the amount of time available in which the course it to be taught, that they could not have added much more. That is why I think a whole separate course should focus just on writing secure applications and on administering a secure server. This could be a 2-3 day course in the training materials and an add-on to the advanced education curriculum.
|
Coldfusion 10 Beta - Language enhancements
Thread posted on Feb 24 by
Tayyab Hussain
Title: Coldfusion 10 Beta - Language enhancements
Content: Coldfusion 10 Beta Launched. Language fearutes are as follows
Support for for-in construct (for query) Provide file content in the tag body Callstack for ColdFusion functions Function to get application metadata Function to get disk space details Application-specific In-memory file system Secure file upload by verifying the MIME type Implicit constructor for CFC Method chaining for CFC methods CFC Implicit notation New function ArraySlice New parameter merge supports arrayAppend New parameter format added to LSParseDateTime function New attribute runOnce added to cfinclude New attribute timeout in cfstoredproc New attribute maxLength in cfparam New functions dateTimeFormat and lsDateTimeFormat New function reEscape The function replaceList takes delimiters Modifications to the functions arraySort, listSort, and structSort Implicit struct now supports use of : (colon) separator The attribute output is ignored in the interface signature FUNCTION is now a ColdFusion datatype Dynamic references supported in query looping New function invoke New attribute secure in cfpop New attribute group in cfloop For-in constructs now support Java arrays Enhancements to queryAddRow and queryNew functions New function listRemoveDuplicates Support for XPath 2.0 and XSLT 2.0 syntax
Image:
ColdFusion 10: RESTful WebServices in ColdFusion - Introduction
Thread posted on May 18 by
Tayyab Hussain
Title: ColdFusion 10: RESTful WebServices in ColdFusion - Introduction
Content: In ColdFusion 10, support for creating and publishing REST services has been added. The ColdFusion components can now be made available as REST services and these services can be consumed by various clients. REST stands for Representational State Transfer. It is an architectural style which is based on web standards and HTTP protocol. The idea here is to use HTTP protocol instead of complex mechanisms such as CORBA, RPC or SOAP to connect between the machines. In fact, the World Wide Web which is based on HTTP can be viewed as a REST based architecture.
REST Architectural principles:
A REST based application follows some architectural principles:
- Resource Identification: In a REST based architecture everything is a resource. Each of these resources should be identified with a URI. In ColdFusion, the functions are identified as resources, each of these resources can then be invoked using an URI.
- Uniform and constrained interface: Every resource in a RESTful application should support HTTP common operations. The resources are manipulated with the HTTP protocol methods – GET, PUT, POST, DELETE. In ColdFusion, the resources (functions) can be accessed via HTTP and each of these resource support the HTTP verbs. Depending on the verb specified in the request, the corresponding resource would be invoked.
- Representation oriented: REST allows resources to have different representation – plain, html, xml, json etc. A client can request a specific representation via the HTTP protocol. HTTP provides a simple content-type negotiation protocol between the client and the server. For example, an AJAX application may need data in JSON format, where as a Java application may need it in XML format.
- Stateless communication: In REST, the server doesn’t store the client session data. However, many techniques exist to exchange state information such as URI rewriting, cookies and hidden form fields. Also, for encryption REST can be used on top of HTTPS.
Getting Started with creating REST services
New attributes have been added to cfcomponent, cffunction and cfargument to aid in creating a REST service. Once a component is created it has to be registered with the Administrator and then it can be accessed via a HTTP request.
Creating a RESTful Web Service
cfcomponent:
As mentioned above, functions in a CFC are the resources and are invoked using a HTTP request. To mark a component as a REST service, attributes rest and restpath are provided. The attribute rest is a boolean attribute, if true the component is enabled as a REST service. This is an optional attribute if restpath is specified in cfcomponent tag. The restpath attribute is used to specify the path using which the REST service would be accessed. If restpath is not specified then the path to the CFC would be used in the URI to invoke the service.
<!--- component with attributes rest and restpath --->
<cfcomponent rest="true" restpath="/crudService">
<!--- handle GET request (httpmethod), take argument in restpath(restpath={customerID}), return query data in json format(produces=text/json) ---> <cffunction name="getHandlerJSON" access="remote" httpmethod="GET" restpath="{customerID}" returntype="query" produces="application/json"> <cfargument name="customerID" required="true" restargsource="Path" type="numeric"/>
<cfset myQuery = queryNew("id,name", "Integer,varchar", [[1, "Sagar"], [2, "Ganatra"]])>
<cfquery dbtype="query" name="resultQuery"> select * from myQuery where id = #arguments.customerID# </cfquery>
<cfreturn resultQuery>
</cffunction>
</cfcomponent>
The function ‘getHandlerJSON’ handles a GET request and accepts an argument customerID. Notice the additional attributes in cffunction tag. The attribute ‘httpmethod’ is used to specify the type of request this function would handle (GET,POST etc,.). Attribute ‘restpath’ is used to specify the path that should be used in the URL, here the path is specified in curly braces as {customerID}. When this type of notation is used it indicates that a value is passed in the URL and the same has to be copied to the functions’ argument. Therefore the name of the argument is same as the one specified in restpath. There are different ways to pass arguments to a REST service, I’ll explain this in my next post.
Complex data types in ColdFusion such as Array, Query, Struct etc, will be serialized to either JSON or XML format. The produces attribute specifies the mime type to which the data returned by the function will be serialized to. There is also an attribute ‘consumes’ that specifies the mime type of data present in the request body.
Coming to the function arguments, the new attribute restargsource specifies the way in which arguments are passed to a rest service. In this example it is path which indicates the argument will passed in the URL path itself. The other possible values include Matrix, Header, Cookie, Form and Query.
Registering a REST Service
There are two ways in which the REST services can be registered with the Administrator. You can either use the Admin API (functions defined in extensions.cfc) or use the function restinitApplicaiton. The former method requires a Administrator privileges and therefore would be available only to selected users. The function restInitApplication can be used to register a REST service and doesn’t require Administrator privileges.
restInitApplication(‘Absolute_path’,[‘Service mapping’])
The directory containing CFC files with with either rest=’true’ or with a restpath in the cfcomponent tag should be specified as the first argument. To identify the set of CFCs in a directory the Service mapping has to be provided. This is an optional fied, if there is an Applicaiton.cfc file present in the directory. In which case the Application name would be used to identify the REST services in the directory.
If any changes are made to any of the components in the registered directory then the corresponding service has to be refreshed. Again this can be done in the Administrator or a call to restInitApplication would refresh the registered service.
Accessing a REST service via HTTP
A RESTful Web service can be accessed either by using HTTP or HTTPS. The URL to access a REST service in ColdFusion follows this format:
http://servername:port/context_path_j2ee/ rest/rest_application_name_or_serverMapping/restpath_or_componentPath/additionalrestPaths/params_ifany/
Here, the context_path_j2ee is applicable only if you have installed ColdFusion as J2EE on any of the Application servers. In which the context path would be cfusion (by default). However, this can be omitted on Standalone installation.
The string ‘rest’ in URL specifies that the request is for a REST service. ColdFusion has a servlet mapping for the same and would direct the request to the servlet that handles REST service. If there is a directory in the server webroot with the same name, then the servlet mapping has to be updated in web.xml file inside wwwroot\WEB-INF directory.
As mentioned earlier, while registering a REST service the application name specified in Applicaiton.cfc file would be used in the URL to access the REST service. If there is no Applicaiton.cfc then the specified service mapping would be used. To access a service specified in the component the restpath for the component has to be specified. However, if the restpath is not specified in the cfcomponent tag then the path to the CFC would be used in URL. Also, the functions defined in component can also have restpath defined and this has to be specified in the URL. If arguments are to be passed in the URL path then the same can also be specified.
In this example, the function ‘getHandlerJSON’, can be accessed using cfhttp:
<cfhttp url="http://localhost:8500/rest/restapp/crudService/1" result="restResult" method="GET"/>
Here restapp is the application name defined in Applicaiton.cfc file. /crudService is the restpath specified in the cfcomponent tag and the numeric 1 is the argument to the REST service. There are various ways in which arguments can be passed to a REST service, I’ll explain this in my next post.
ColdFusion ORM : The basics
Thread posted on May 19 by
Tayyab Hussain
Title: ColdFusion ORM : The basics
Content: OK, I agree that I should have masterd this long time but it took me time to study this concept as I was not getting out of the SQL Frame . After a long wait I finallay decided to tell some thing about ORM and hence I decided to do a post on the ORM basics. In this post, we will build a simple example to get a taste of ColdFusion ORM (CF-ORM) and during that we will also understand some of the basic concepts.
ORM is object relational mapping and in ColdFusion, objects are created using CFC. CFCs that needs to be persisted are called persistent CFC and that is marked by setting ‘persistent’ attribute to true on the component. We also need to define what persistent fields will be there in a persistent CFC and that is defined using ‘cfproperty’. A field/property is marked persistent by setting persistent attribute to true on the cfproperty. By default, if the CFC is persistent, all its properties are considered as persistent unless you mark a property non-persistent. So typically ‘persistent’ attribute on the property is used only when you need to make that property non-persistent.
Each persistent CFC in ColdFusion application maps to a table in the database and each property in the persistent CFC maps to a column in the table (not exactly true but we will come to that later.. For the time being lets keep it that way). We will use the cfartgallery datasource for this example which has Artists and Art tables.
The first thing you need to do is – enable ORM for the application and define a datasource to be used (What is an ORM without a datasource?). ColdFusion ORM uses Application.cfc to define all the ORM specific settings. (If you haven’t started using Application.cfc for your application, its time to start using it!)
Application.cfc
Component {
this.name="ArtGallery";
this.ormenabled="true";
this.datasource="cfartgallery";
}
Note that the datasource setting defined here makes it the default datasource of your application which can be used by tags like cfquery, cfinsert, cfupdate, cfdbinfo. The same default datasource will be used by ORM as well.
Now that the application is configured, let us build the object and define the persistence information on it. To start with, we will first define the
Artist.cfc
Artists.cfc
/**
* @persistent
*/
Component {
property name="artistid" generator="increment";
property firstname;
property lastname;
property address;
property city;
property state;
property postalcode;
property email;
property phone;
property fax;
property thepassword;
}
This is the most simplistic definition of the component where we have defined only the component and its properties names. Since the table for this CFC already exists in the database, we have not added any table specific information in this and we will let ORM infer all the information from the database. The only additional setting that we have added here is the ‘generator’ attribute which is used to auto-generate the primary key.
After the components are defined, the first request to this application (i.e a page in this application) will make CF-ORM do all the setup necessary (basically generation of hibernate configuration, mapping files, building the session factory etc). Once the setup is done, you are all set to work with the entities.
We will first list all the artists and here is what you need to do for that
listAll.cfm
<cfscript>
artists = EntityLoad("Artists");
writedump(artists);
</cfscript>
To load a particular Artists with its ID, here is what you do
list.cfm <cfscript>
artist = EntityLoadByPK("Artists", 1);
writedump(artist);
</cfscript>
There are several flavors of EntityLoad functions details of which can be read here Let us now see how to perform insert and update on it. save.cfm
<cfscript><br> // Insert a new artist
artist = new Artists();
artist.setfirstname("Leonardo");
artist.setlastname("Da vinci");
artist.setcity("Paris");
EntitySave(artist);
writeOutput(artist.getartistid());// Update an artist
artist = EntityLoadByPK("Artists", 2);
artist.setcity("NewYork"); // artist is automatically updated.
</cfscript>
As we see in the above example, EntitySave is used to insert/update an object in the table. There are some important things to note here - EntitySave is an intelligent function which automatically finds if a new row needs to be inserted for the given object or whether an eisting row needs to be updated.
- We called EntitySave for the insert here but not for update but even then artist ‘2′ gets updated. So how did that happen? Actually what happens here is when you load an artist object, it becomes associated with the hibernate session which keeps track of any changes in the object and automatically saves it when the session is flushed. We will talk about more about hibernate session in a later post. For the time being lets just say that Hibernate Session is a short-lived object that represents a conversation between the application and the persistence layer and also acts as the first level of cache.
- We did not write any setter or getter method for artist’s properties in Artists.cfc but we are calling them here. That works because ColdFusion 9 automatically generates accessor methods for any property written in a CFC. More details on generated methods in a later post.
- At line no 6, we called entitySave, but if you check the database, the row is not inserted yet. So when does that happen? Hibernate batches up all the operations till the end of the request or to be exact till hibernate session is flushed. ColdFusion ORM starts up a session when the first ORM method is called in the request and is automatically flushed when the request ends. The batching is done for performance reason so that hibernate executes the sql with the final state of the objects. It will be a huge performance bottleneck if ORM keeps executing sql for each changes in the object.
To delete an Artist, you need to call EntityDelete() passing the object to be deleted.
delete.cfm
<cfscript>
artist = EntityLoadByPK("Artists", 15, true);
EntityDelete(artist);
</cfscript>
RelationshipSo far we have seen how to perform CRUD for a single entity. But in any application, there will be entities which are associated and ORM must load the associated object as well when loading a particular entity. For our example, an Art will have an Artist and when loading the art object, it should also load the associated artist. So lets build the model first after which we will see how to work with the association. In cfartgallery, the table Artists has a one-to-many relationship with Art table, which are joined using the foreign key column ARTISTSID. This means that each artist has created multiple arts and each art is created by one artist. To represent this in the object model, each ARTIST object would contain an array of ART objects. Each ART object will also contain a reference to its ARTIST object thereby forming a bidirectional relation. To achieve this, we will need to add an extra property ‘arts’ to ‘Artists’ that contains an array of ART objects for that Artist. The modified Artists.cfc would look like /**
* @persistent
*/
Component {
property name="artistid" generator="increment";
property firstname;
property lastname;
property address;
property city;
property state;
property postalcode;
property email;
property phone;
property fax;
property thepassword;
property name="arts" fieldtype="one-to-many" fkcolumn="artistid" cfc="Art" cascade="all" inverse="true";
}
Here is the Art.cfc
/**
* @persistent
*/
Component {
property name="artid" generator="increment";
property artname;
property price;
property largeimage;
property mediaid;
property issold;
property name="artist" fieldtype="many-to-one" fkcolumn="artistid" cfc="Artists" ;
}
Notice the artist property above which is of many-to-one type. Also notice that both the property use the same value for fkcolumn attribute i.e ‘artistid’ of Art table that references artistID pk of Artist table.
Since we have added a new persistent CFC (Art.cfc) after the application was loaded, we need to re-initialize the ORM for this application so that mappings for Art.cfc also gets generated. This can be done by calling ORMReload() method. There are some nice ways to do this but for the time being lets keep it simple by putting this in a separate page which we will call to reload ORM.
initializeORM.cfm
<cfset ormReload()>
If you load and dump Artist (using listAll.cfm), you should also see the associated art objects for artists. Now let us create a new Art and associate it with an existing Artist. artCreate.cfm <cfscript>
artist = EntityLoad("artists", 1 ,"true");
art = new Art();
art.setartname("landscape");
art.setPrice(1500);
art.setissold(false);
art.setartist(artist);
artist.addArts(art);
EntitySave(art);
</cfscript>
If you notice line 7-8 above, we associate artist to art by calling art.setArtist(artist) as well as art to artist by calling artist.addArts(art). Hibernate needs us to do this in order to set up the bidirectional relation properly. Since it is a bidirectional relation, you must also decide which side will set the relation in the database. i.e which side of the relation will set the fkcolumn in the table. This is controlled by the “inverse” attribute of proeprty, which if set to true, tells hibernate that this is a inverse of the other relation and this side of relation should be ignored for persistance. If you don’t set inverse to true, Hibernate will unnecessarily fire two sqls for the same association.
So there you have it. We have seen how you can use ORM to perform the basic CRUD operations on entities. For more details, you can refer to the ORM doc and Hibernate docs. Please also go through the attached Power Point Slide
Note: EntityLoadByPK(”artists”, 1) & EntityLoad(”artists”, 1 ,”true”) are the same
This method was added because it always gives the object right back and you don’t have to pass the boolean parameter. however it was not documented, Just went through an article and noticed.
File: CF-orm-2010.ppt (5.81 Mb)
Creating and Consuming Web Services with CFML
Thread posted on Apr 08 by
Tayyab Hussain
Title: Creating and Consuming Web Services with CFML
Content: What are Web Services
In simple a web page designed to be consumed by software, not by humans. Who remembers WDDX? It Could “serialize” data to Allaire-specified XML and Could output from page request, pass to caller. But it had some Problems. It was Non-standard (though see openwddx.org) and aasn’t a function call/response approach.
So technically speaking
- Web services are application components
- Web services communicate using open protocols
- Web services are self-contained and self-describing
- Web services can be discovered using UDDI
- Web services can be used by other applications
- XML is the basis for Web services
So How does web services work ?
The basic Web services platform is XML + HTTP.
XML provides a language which can be used between different platforms and programming languages and still express complex messages and functions.
The HTTP protocol is the most used Internet protocol.
Web services platform elements:
- SOAP (Simple Object Access Protocol)
- UDDI (Universal Description, Discovery and Integration)
- WSDL (Web Services Description Language)
But the good news is CFML hides the need for you to understand any of these. Many languages support web services like Java, ASP.net, Perl etc. They often use API which involve lots of coding. Coldfusion support very easy publication and consumption of web services. For this you do not need to know JAVA, SOAP, WSDL,UDDI not even XML.
Publishing Your First Web Service
You only need to create a CFC function that returns that data, expose function as “remote”.
If you’re new to CFCs’, they have many other benefits and features.
Their use for web services is actually one of their easier purposes to understand.
Building the Component Function
<!--- hello.cfc ---> <CFCOMPONENT> <CFFUNCTION NAME="GetHello" ACCESS="REMOTE" RETURNTYPE="String"> <CFRETURN "Hello World"> </CFFUNCTION> </CFCOMPONENT>
There you go, your first web service. Now any web service client (caller) can invoke this web service (hello.cfc) and its method (GetHello)
Calling Your Web Service
You Can call from any language/platform that supports web services
Simply need to refer to:
- Domain name (and port, if needed) that’s
- used to access code on CFMX
- Directory in which CFC is located
- CFC name
- ?WSDL indicator
For example http://localhost/demo/hello.cfc?wsdl
Consuming our Web Service via Invoke
To use the web service within CFML, use either CFINVOKE, CFOBJECT, or createObject
CFINVOKE:
Calls web service (using URL described earlier, with ?wsdl as querystring), names method to execute, and variable to hold returned result
<cfinvoke webservice="http://localhost/demo/hello.cfc?wsdl" returnvariable="fromhello" method="GetHello"> <cfoutput>#fromhello#</cfoutput>
Consuming our Web Service via CFObject/Createobject
You can also use CFOBJECT/CreateObject instead. It is Slight difference from CFINVOKE
- They return an object representing the web service
- Then can invoke method in CFML as with other objects
<cfobject webservice="http://localhost/demo/hello.cfc?wsdl“ name="fromhello"> <cfoutput>#fromhello.GetHello()#</cfoutput>
Or
<cfscript> fromhello=createobject("webservice","http://localhost/demo/hello.cfc?wsdl"); writeoutput(fromhello.GetHello()); </cfscript>
There you go. Your first web service which can be called from any scripting Language
Improvements in <cfinclude> - CF Zeus
Thread posted on Jan 17 by
Tayyab Hussain
Title: Improvements in <cfinclude> - CF Zeus
Content: Any one who has made use of cfinclude in the past has probably run into situations where they've accidentally included the same template twice. Some times this isn't a big deal. Other times it can lead to bugs or just having your site run a bit slower than expected. ColdFusion Zeus adds a simple way to ensure your includes are never run more than once. Consider the template below
<cfinclude template="include_target.cfm" runonce="true"> <cfinclude template="include_target.cfm" runonce="true">
We've added a new attribute, runonce, that when set to true, will ensure the target of the include is only executed once. This is request-level intelligent as well. So given this CFM:
<cfinclude template="include_target.cfm" runonce="true"> <cfinclude template="include_test.cfm">
If include_test.cfm contains the include statements you saw above, then they recognize that they were already run before in the parent. Hopefully that didn't come out as confusing as it sounds. ;)
|
Filter by Date
|
<<
May 2013
>>
|
| Su |
Mo |
Tu |
We |
Th |
Fr |
Sa |
| |
|
|
01
|
02
|
03
|
04
|
| 05
|
06
|
07
|
08
|
09
|
10
|
11
|
| 12
|
13
|
14
|
15
|
16
|
17
|
18
|
| 19
|
20
|
21
|
22
|
23
|
24
|
25
|
| 26
|
27
|
28
|
29
|
30
|
31
|
|
Filter by Tag
All
announcement
Benefit
Flash
General
General Discussion
Question
Sticky
Change View
Titles
Summaries
Table
Clip
Clip & Comments
Full
Change Sort
Alphabetically
By Last Activity
By Date Posted
By Number of Comments
By Number of Views
By Author
|