Using WDDX with ColdFusion


Now that you have an idea what WDDX is all about, you can start learning how to use it in your ColdFusion applications. This section introduces you to the <cfwddx> tag and gets you thinking about different ways you can use WDDX in your own pages. You will find that WDDX is a very flexible technology, appropriate for solving many types of problems, from simple to complex, lofty to mundane.

NOTE

WDDX is not just for ColdFusion developers. The same basic techniques explained in this book can be used within Java, Perl, and more. And data that has been converted to WDDX can almost always be effortlessly shared between any of these applications with no loss of integrity.


Introducing the <cfwddx> Tag

Each language or environment that supports WDDX has some way to serialize and deserialize WDDX packets. In ColdFusion, it's the <cfwddx> tag. You use <cfwddx> to serialize data from native CFML variables to the WDDX packet format. You also use it to deserialize the data from the WDDX packet back into native ColdFusion variables.

First, I'll show you how to use the <cfwddx> tag to do some simple serialization and deserialization of WDDX packets. Then we'll take a closer look at what the actual packets look like. The first thing for you to understand is the syntax supported by the <cfwddx> tag, as outlined in Table 16.1.

Table 16.1. <cfwddx> Tag Syntax

ATTRIBUTE

DESCRIPTION

actio

Required. Specifies whether to convert to or from the WDDX format. Use action="cfml2wddx" to serialize a ColdFusion variable to a WDDX packet. Use action="wddx2cfml" to deserialize a WDDX packet back into a native ColdFusion variable.

input

Required. The value to be converted. If you are using action="cfml2wddx", here is where you provide the value you want to serialize. If you are using action="wddx2cfml", provide the WDDX packet you want to deserialize.

OUTPUT

The name of a variable to hold the result of the conversion. If you are using action="cfml2wddx", the serialized WDDX packet will be stored in the variable you specify here. If you are using action="wddx2cfml", the data from the WDDX packet will be deserialized and stored in this variable.

usetimezoneinfo

Optional. Relevant only when deserializing data with action="wddx2cfml". If Yes (the default) and the WDDX packet contains dates that contain time zone information, ColdFusion will convert the dates to the server's time zone during the deserialization process. If No, all time zone information in the packet is ignored.

validate

Optional. Relevant only when deserializing data with action="wddx2cfml". If No (the default), it is assumed that the packet provided to the input attribute is known to be a valid WDDX packet. If Yes, the packet is checked for validity first, which adds a small amount of overhead. In general, the IsWDDX() function is a better way to make sure a packet is valid; for details, see the section "Validating Packets with IsWDDX()" later in this chapter.


NOTE

<cfwddx> supports two other action values, as well (cfml2js and wddx2js), and one more attribute (toplevelvariable). These items are all specific to using ColdFusion with JavaScript and are discussed in Chapter 17, "Using JavaScript and ColdFusion Together."


Creating Your First WDDX Packet

Listing 16.1 shows how to use <cfwddx> to serialize a simple string value into a WDDX packet. This listing then displays the packet and also saves the packet to the server's drive as a file called StringPacket.txt (see Figure 16.1).

Listing 16.1. Serialize1.cfmConverting a Simple String to WDDX
 <!--- Name:        Serialize1.cfm Author:      Nate Weiss and Ben Forta Description: Serialize data into a WDDX packet Created:     02/01/05 ---> <html> <head>  <title>WDDX Demonstration</title> </head> <body> <!--- set the #message# variable to a simple string value ---> <cfset Message="Hello, World!"> <!--- Serialize the #Message# variable into a WDDX Packet ---> <cfwddx action="CFML2WDDX"         input="#Message#"         output="MyWDDXPacket"> <!--- Output WDDX packet so we can see what it looks like ---> <!--- (HTMLEditFormat function lets us see tags properly) ---> <cfoutput>  <p><strong>Original Message:</strong> #Message#</p>  <p><strong>The message was serialized into             the following WDDX packet:</strong></p>  #HTMLEditFormat(MyWDDXPacket)# </cfoutput> <!--- Save the WDDX packet to a file on the server's drive ---> <cffile action="WRITE"         file="#ExpandPath('StringPacket.txt')#"         output="#MyWDDXPacket#"> </body> </html> 

Figure 16.1. Simple strings get placed between <string> tags in the WDDX format.


NOTE

Because the MyWDDXPacket variable contains tags that look like HTML tags, most Web browsers will not display the packet's contents unless each <and> character is converted to a &lt; or &gt; symbol. ColdFusion's HTMLEditFormat() function escapes these types of special characters automatically, which is the reason that function is used in Listing 16.1. You can leave out this function if you want, but in that case you must use the browser's View Source command to actually see the packet's contents. Alternatively, you could use the HTMLCodeFormat() function, which would cause the browser to display the packet's contents using a fixed-width ("code") font, always on one long line.


Deserializing Your First WDDX Packet

Listing 16.2 shows how to deserialize a WDDX packet. As you can see, the process is very similar to the serialization process; you just use action="wddx2cfml" instead of action="cfml2wddx" in the <cfwddx> tag, and supply the text of the WDDX packet as the tag's input attribute.

Whatever is stored in the WDDX packet will become available in the variable you specify in the output attribute. In this case, the contents of the packet is the "Hello, World" message from Listing 16.1. So, after the <cfwddx> tag, the Message variable contains that string and can be displayed in a <cfoutput> block just like any other string variable (see Figure 16.2).

Listing 16.2. Deserialize1.cfmDeserializing the Packet Created with Listing 16.1
 <!--- Name:        Deserialize1.cfm Author:      Nate Weiss and Ben Forta Description: Deserialize data from a WDDX packet Created:     02/01/05 ---> <html> <head>  <title>WDDX Demonstration</title> </head> <body> <!--- Read the WDDX packet from the file on the server's drive ---> <cffile action="READ"         file="#ExpandPath('StringPacket.txt')#"         variable="MyWDDXPacket"> <!--- Deserialize the WDDX packet back into native #Message# variable ---> <cfwddx action="WDDX2CFML"         input="#MyWDDXPacket#"         output="Message"> <cfoutput>  <!--- Display the message we retrieved from the WDDX packet --->  <p><strong>Deserialized Message:</strong> #Message#</p>  <p><strong>The message was deserialized from             the following WDDX packet:</strong></p>  <!--- Output WDDX packet so we can see what it looks like --->  <!--- (HTMLEditFormat function lets us see tags properly) --->  #HTMLEditFormat(MyWDDXPacket)# </cfoutput> </body> </html> 

Figure 16.2. You can easily deserialize any WDDX packet with the <CFWDDX> tag.


Serializing and Deserializing Complex Data

Listings 16.1 and 16.2 showed you how to serialize and deserialize a simple string value. Although those listings are a useful demonstration of the <cfwddx> tag, the actual result is not that interesting. Those listings simply stored a string value in a file; you could have achieved that result by saving the string to a simple text file with the <cffile> tag alone.

Things get a lot more interesting when you use <cfwddx> to serialize and deserialize complex data types such as arrays, query recordsets, and structures. In fact, just about any CFML variable can be serialized (and then deserialized) with WDDX, and the <cfwddx> tag syntax remains exactly the same.

Listing 16.3 creates a structure called MyStruct, fills it with various types of data (including a nested array and a nested query recordset), and serializes it with the <cfwddx> tag (see Figure 16.3). The packet is stored in a text file called StructPacket.txt.

Figure 16.3. Complex values such as structures, recordsets, and arrays can be serialized with <cfwddx>.


Listing 16.4 uses <cfwddx> to deserialize the packet and then display some of the information that it contained (see Figure 16.4). The output proves that the deserialized MyStruct variable holds exactly the same information as it did before the serialization/deserialization process. Even if the MyStruct structure contained nested structures that in turn contained other structures, or arrays that contained recordsets, you could still serialize it using the same approach.

Listing 16.3. Serialize2.cfmSerializing a Structure that Contains an Array and Recordset
 <!--- Name:        Serialize2.cfm Author:      Nate Weiss and Ben Forta Description: Serialize data into a WDDX packet Created:     02/01/05 ---> <html> <head>  <title>WDDX Demonstration</title> </head> <body> <!--- Run a simple database query to include in the WDDX packet ---> <!--- Limit the query to just 5 rows to keep things simple ---> <cfquery name="filmsquery" datasource="ows" maxrows="5">  SELECT FilmID, MovieTitle, AmountBudgeted, DateInTheaters  FROM Films  ORDER BY MovieTitle </cfquery> <!--- Create a structure ---> <cfset MyStruct=StructNew()> <!--- Add a few simple string values ---> <cfset MyStruct.CompanyName="Orange Whip Studios"> <cfset MyStruct.CompanyURL="http://www.orangewhipstudios.com"> <!--- Add the current date and time ---> <cfset MyStruct.PacketDate=Now()> <!--- Add the contents of the FilmsQuery query ---> <cfset MyStruct.Films=FilmsQuery> <!--- Add a simple array ---> <cfset MyStruct.Offices=ArrayNew(1)> <cfset MyStruct.Offices[1]="New York, NY"> <cfset MyStruct.Offices[2]="Paris, France"> <cfset MyStruct.Offices[3]="Pittsfield, MA"> <!--- Serialize the #MyStruct# structure into a WDDX Packet ---> <cfwddx action="CFML2WDDX"         input="#MyStruct#"         output="MyWDDXPacket"> <!--- Output WDDX packet so we can see what it looks like ---> <!--- (HTMLEditFormat function lets us see tags properly) ---> <cfoutput>  <p><strong>The structure was serialized into the             following WDDX packet:</strong></p>  #HTMLEditFormat(MyWDDXPacket)# </cfoutput> <!--- Save the WDDX packet to a file on the server's drive ---> <cffile action="WRITE"         file="#ExpandPath('StructPacket.txt')#"         output="#MyWDDXPacket#"> </body> </html> 

Figure 16.4. After deserialization, the data from a WDDX packet can be used just like any other data.


Listing 16.4. Deserialize2.cfmDeserializing a Multifaceted Data Structure
 <!--- Name:        Deserialize2.cfm Author:      Nate Weiss and Ben Forta Description: Deserialize data from a WDDX packet Created:     02/01/05 ---> <html> <head>  <title>WDDX Demonstration</title> </head> <body> <!--- Read the WDDX packet from the file on the server's drive ---> <cffile action="READ"         file="#ExpandPath('StructPacket.txt')#"         variable="MyWDDXPacket"> <!--- Deserialize the WDDX packet back into native #MyStruct# variable ---> <cfwddx action="WDDX2CFML"         input="#MyWDDXPacket#"         output="MyStruct"> <!--- Output various information from the packet, to prove that --->  <!--- the structure contains all of the original information ---> <cfoutput>  <!--- MyStruct.CompanyName should be a string value --->  <strong>Company name:</strong>   #MyStruct.CompanyName#<br>     <!--- MyStruct.Offices should be an array --->  <strong>Number of offices:</strong>   #ArrayLen(MyStruct.Offices)#<br>    <!--- MyStruct.PacketDate should be a date/time object --->  <strong>Information recorded at:</strong>   #DateFormat(MyStruct.PacketDate)# #TimeFormat(MyStruct.PacketDate)#<br>  <!--- MyStruct.Films should be a query recordset --->  <p><strong>Films:</strong><br>  <cfloop query="MyStruct.Films">   #MovieTitle#<br>  </cfloop> </cfoutput> </body> </html> 

It's worth emphasizing that <cfwddx> doesn't care what a variable contains when you serialize it. You feed it whatever data you want converted to a packet, and it obliges. Compare this to traditional XML approaches, with which you would normally have to decide on what tag and attribute names you wanted to use, perhaps creating a DTD along the way, and then populate an XML document using DOM-like syntax. Don't get me wrong here. I'm not trying to suggest that WDDX is better than other types of XML. But WDDX is unquestionably easier to use for quick-and-dirty tasks where all you want to do is convert data to XML in a quick and reliable fashion.

Validating Packets with IsWDDX()

Sometimes you'll want to deserialize packets that may be coming from some other application or location. If you're unsure whether a WDDX packet is valid, you can use the IsWDDX() function to validate it before attempting to deserialize it with the <cfwddx> tag.

The IsWDDX() function accepts a single argument, which is the string value that you suspect to be a WDDX packet. The function returns TRue or false, depending on whether the packet is indeed valid. If the result is false, the packet cannot be deserialized with <cfwddx>.

For instance, you could add the following <cfif> block to Listing 16.4, after the <cffile> tag but before the <cfwddx> tag:

 <!--- Make sure the packet is valid before deserializing it --->  <cfif not IsWDDX(MyWDDXPacket)>  Sorry, the StructPacket.txt file does not contain a valid WDDX packet.  <cfabort> </cfif> 



Advanced Macromedia ColdFusion MX 7 Application Development
Advanced Macromedia ColdFusion MX 7 Application Development
ISBN: 0321292693
EAN: 2147483647
Year: 2006
Pages: 240
Authors: Ben Forta, et al

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net