Tải bản đầy đủ (.pdf) (124 trang)

ColdFusion MX Bible phần 6 potx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.06 MB, 124 trang )

580
Part IV ✦ ColdFusion MX Components, Web Services, and Flash Integration
Figure 26-7 shows the properties for Update Company button.
Figure 26-7: The properties of the Update Company button.
Later on, you may want to come back and set some guides on your Stage to help you position
these form elements and maybe reformat text styles, but for now, push on to ActionScript.
Choose File ➪ Save from the Flash menu bar, and maybe take a little break. Can’t? Too
excited? Okay — onto the final piece of the Flash Remoting puzzle: ActionScript!
Building the ActionScript
The ActionScript that you’re going to build can be placed in one frame for your convenience,
then called from any other Flash object as needed. You can place code containing individual
pieces of logic within specific objects in your Flash movie if you wish (which is useful when
you are working with a team of other developers who have their own pieces of code), but
keeping all your code in one place is probably the best way to start learning how to program
with Flash MX.
Select Frame 1 of the
actions layer before proceeding so that your code is easy to find, as
shown in Figure 26-8.
Listing 26-2 shows the complete ActionScript for this application. Enter Listing 26-2 exactly as
shown in Frame 1 of the
actions layer. (Most of it is case sensitive, so treat all of it that way
to be safe.) Then we can discuss it in detail.
30546228 ch26.F 1/30/03 12:14 PM Page 580
581
Chapter 26 ✦ Flash Remoting Services
Figure 26-8: Enter all your ActionScript in this example into Frame 1 of the actions layer.
Listing 26-2: The ActionScript used by the application
#include “NetDebug.as”
#include “NetServices.as”
#include “DataGlue.as”
gatewayURL = “http://localhost/flashservices/gateway”;


gatewayConnection = NetServices.createGatewayConnection(gatewayURL);
companyService =
gatewayConnection.getService(“com.flashremoting.Company”, this);
function listCompanies_Result(companyListResult) {
DataGlue.BindFormatStrings(companyToShow_cb, companyListResult,
“#CompanyName#”, “#CompanyID#”);
status_txt.text = “”;
}
function getCompany() {
companyService.GetCompany({
CompanyID:companyToShow_cb.getSelectedItem().data
});
}
Continued
30546228 ch26.F 1/30/03 12:14 PM Page 581
582
Part IV ✦ ColdFusion MX Components, Web Services, and Flash Integration
Listing 26-2 (continued)
function getCompany_Result(companyRecord) {
companyName_txt.text = companyRecord.items[0].CompanyName;
address_txt.text = companyRecord.items[0].Address;
city_txt.text = companyRecord.items[0].City;
state_txt.text = companyRecord.items[0].State;
zipCode_txt.text = companyRecord.items[0].ZipCode;
}
function updateCompany() {
companyService.updateCompany({
CompanyID:companyToShow_cb.getSelectedItem().data,
CompanyName:companyName_txt.text,
Address:address_txt.text,

City:city_txt.text,
State:state_txt.text,
ZipCode:zipCode_txt.text
});
}
function updateCompany_Result() {
companyService.ListCompanies();
}
function updateCompany_Status() {
status_txt.text = “An error occurred.”;
}
companyService.listCompanies();
stop();
Let’s take Listing 26-2 from the top and work our way down.
#include “NetDebug.as”
#include “NetServices.as”
#include “DataGlue.as”
These three include statements bring the ActionScript code from these script files into your
script, so as you test and publish your Flash movie, the code from these external scripts isn’t
left behind. Notice that
include statements do not end in semicolons.
NetDebug.as provides a very useful Flash debugger that you should absolutely love and rely
on during Flash Remoting development. More on how to use it in the section “NetConnection
Debugger.” This line of code should be removed before production deployment.
NetServices.as provides extended Flash Remoting functionality and ease of use. Although
it is technically not needed for Flash Remoting development per se, most developers we
know use its extended methods as standard operating procedure (as do we).
DataGlue.as provides data-binding routines for Flash UI components, such as the Choose
Company combo box that you created in the section “Create the Company combo box,”
30546228 ch26.F 1/30/03 12:14 PM Page 582

583
Chapter 26 ✦ Flash Remoting Services
earlier in this chapter. Its functions can be duplicated through a lot of extensive coding, so
technically it is not absolutely necessary for Flash Remoting development, but trust us — you
want to use
DataGlue because, with it, you can bind a RecordSet object to a form control
with a single function call, as follows:
gatewayURL = “http://localhost/flashservices/gateway”;
gatewayConnection = NetServices.createGatewayConnection(gatewayURL);
If you are using ColdFusion MX Server with IIS or another Web server, your gatewayURL assign-
ment is as shown. If your ColdFusion MX Server was installed with its own standalone Web
server, you may need to address Port 8500 in the Flash Remoting Gateway URL, as follows:
gatewayURL = “http://localhost:8500/flashservices/gateway”;
Either way, this is the virtual Web address of your Flash Remoting Gateway.
The
gatewayConnection assignment creates an instance of the NetConnection object
through which you instantiate instances of your ColdFusion components, as follows:
companyService =
gatewayConnection.getService(“com.flashremoting.Company”, this);
Now you can call methods of the Company component through the companyService instance,
as you soon see.
As you learned in the section “How Flash Remoting Works,” earlier in this chapter, callback
functions are named by appending
_Result to the name of the original calling function, so
listCompanies_Result() is the callback function for the ListCompanies() function in the
Company ColdFusion component:
function listCompanies_Result(companyListResult) {
DataGlue.BindFormatStrings(companyToShow_cb, companyListResult,
“#CompanyName#”, “#CompanyID#”);
status_txt.text = “”;

}
The ColdFusion query object returned from the ListCompanies() ColdFusion component
function is received by the
listCompanies_Result ActionScript function as an ActionScript
RecordSet object named companyListResult.
Then
DataGlue’s BindFormatStrings() function binds the companyToShow_cb combo box
to the
companyListResult RecordSet object, using the CompanyName column values as the
display text in the combo box, and the
CompanyID column values as their corresponding data
values (similar to an HTML select menu), as follows:
function getCompany() {
companyService.GetCompany({
CompanyID:companyToShow_cb.getSelectedItem().data
});
}
function getCompany_Result(companyRecord) {
companyName_txt.text = companyRecord.items[0].CompanyName;
address_txt.text = companyRecord.items[0].Address;
city_txt.text = companyRecord.items[0].City;
state_txt.text = companyRecord.items[0].State;
zipCode_txt.text = companyRecord.items[0].ZipCode;
}
30546228 ch26.F 1/30/03 12:14 PM Page 583
584
Part IV ✦ ColdFusion MX Components, Web Services, and Flash Integration
The getCompany() ActionScript function, which is called whenever the user chooses a differ-
ent company in the Choose Company combo box, simply calls the
GetCompany() ColdFusion

component function in
companyService, which is an instance of the Company ColdFusion
component defined in the Flash Remoting Gateway. The argument to the
GetCompany()
ColdFusion function is the data value of the selected item in the companyToShow_cb (Choose
Company) combo box. We are using named argument syntax here, where the name of the
argument is followed by a colon and then by the value of the argument.
The callback function for
getCompany() — getCompany_Result() — receives the returned
RecordSet object containing a single record and internally refers to it as companyRecord. By
using familiar dot notation,
getCompany_Result() sets the values of the form fields in the
Flash movie to those returned in the
companyRecord object. Notice that you are setting the
.text attribute of the object only, and not the entire object itself.
In a similar vein,
updateCompany also uses named argument notation (our favorite method
for clarity of code) to send the text attributes of the entry fields and the data attribute of the
combo box (the currently selected
companyID) to the UpdateCompany() ColdFusion function
of the
Company component. The callback function simply recalls listCompanies() to
update the combo box’s contents:
function updateCompany() {
companyService.updateCompany({
CompanyID:companyToShow_cb.getSelectedItem().data,
CompanyName:companyName_txt.text,
Address:address_txt.text,
City:city_txt.text,
State:state_txt.text,

ZipCode:zipCode_txt.text
});
}
function updateCompany_Result() {
companyService.listCompanies();
}
function updateCompany_Status() {
status_txt.text = “An error occurred.”;
}
Here you see something new. Another automatic callback function is called if the original call-
ing function throws an error. This error callback is named by appending
_Status to the name
of the original calling function.
Everything up to this point has either been establishing a connection, instantiating an object,
or declaring functions that have yet to be called. But now you actually execute some code by
calling the
listCompanies() function of the companyServices instance of the Company
ColdFusion component and then stopping the playhead by using the stop() action, which
tells the Flash movie to stop playing. If this Flash movie contained multiple frames — as most
of your production Flash movies will — and you don’t tell the playhead to stop, it would keep
running the entire time that your Flash movie was open:
companyService.listCompanies();
stop();
Choose File ➪ Save from the Flash menu bar, and you’re done. Now to test your new baby!
30546228 ch26.F 1/30/03 12:14 PM Page 584
585
Chapter 26 ✦ Flash Remoting Services
Testing the application
Choose Control ➪ Test Movie from the menu bar and see what happens. Most likely, you find
that you have a coding typo somewhere or maybe forgot to enter an instance name for one or

more of your form objects, or did or forgot something else that prevents your Flash Remoting
application from working. Don’t worry — the NetConnection Debugger comes to your rescue!
Finally, a truly useful (and cool) debugger! To use it, just choose Window ➪ NetConnection
Debugger from the menu bar and then Control ➪ Test Movie from the Flash menu bar, and
reposition and resize the debugger window so that you don’t obscure your view of the under-
lying Flash Remoting application that you’re debugging.
If you see an error in the debugger right away, select it in the left list box and inspect its
details on the right. Correct the problem and then try again. You may need to choose
Window ➪ NetConnection Debugger again before testing the movie.
After you have all your initial errors debugged, your Flash Remoting application is ready to
be put through the ringer. To test the error callback function, enter a very long value into the
zip code field and then click the Update Company button. You should see a red error message
in the status message box that you create in the section “Create the status message box,” ear-
lier in this chapter. By the way, you can restrict the number of characters that the user can
enter into an input field through the Maximum Characters attribute in the input field’s
Properties palette.
See how everything works together? Are you getting a “feel” for the system in general. Good!
Now to go further into the details and also learn what not to do.
Details and Caveats
We really wanted you to get your feet wet in the preceding sections of this chapter with a
very simple Flash Remoting application before we dump a bunch of details on you. Learning
is so much easier if you strip away all the details and focus just on the big stuff to begin with,
but you need to know these important details and caveats before you start deploying Flash
Remoting applications in a production environment.
Publishing your Flash movie
To publish your Flash movie, click an unpopulated area of the Stage and then click the
Publish button in the Properties palette. A Publish Settings dialog box appears for you to
specify the quality and size settings that you want to use. The defaults do well for now, so just
click the dialog box’s Publish button, click its OK button, and then open the
Company.html

file from the directory in which you saved your Company.fla Flash file. You now see your
Flash Remoting application in live action!
Right-click anywhere off the Flash movie portion of the
Company.html Web page, and choose
View ➪ Source from your browser’s menu bar. You can copy and paste this code, an example
of which is shown in Listing 26-3, into your ColdFusion templates where you want to display
the Flash movie. You can also open the
Company.html file in your favorite editor.
30546228 ch26.F 1/30/03 12:14 PM Page 585
586
Part IV ✦ ColdFusion MX Components, Web Services, and Flash Integration
Listing 26-3: Flash movie embedding code
<OBJECT classid=”clsid:D27CDB6E-AE6D-11cf-96B8-444553540000”
codebase=” />swflash.cab#version=6,0,0,0”
WIDTH=”360”
HEIGHT=”250”
id=”Company”
ALIGN=””>
<PARAM NAME=movie VALUE=”Company.swf”>
<PARAM NAME=quality VALUE=high>
<PARAM NAME=bgcolor VALUE=#FFFFFF>
<EMBED src=”Company.swf”
quality=high
bgcolor=#FFFFFF
WIDTH=”360”
HEIGHT=”250”
NAME=”Company”
ALIGN=””
TYPE=”application/x-shockwave-flash”
PLUGINSPAGE=” /></EMBED>

</OBJECT>
The advanced publishing options of Flash movies are beyond the scope of this book, but this
shows you enough to make everything work very well. For more details, please refer to the
Flash MX Bible by Robert Reinhardt and Snow Dowd (Wiley) or to your Flash documentation.
Using Flash Remoting with .cfm templates
In preceding sections of this chapter, you see ColdFusion components used to provide data
services to the Flash Remoting Gateway, but you are not limited to components alone. You
can also use plain ColdFusion templates to provide data for Flash Remoting, but the mecha-
nism for returning data is necessarily different, as you have no formal “return” of data from a
standard ColdFusion template.
To establish a Flash Remoting Gateway connection to a ColdFusion template, simply specify
the directory containing the template as the service and use the file-name root of the tem-
plate (that is, without the
.cfm extension) as the name of the function that you’re calling. So
if you have a ColdFusion template named
GetCompanyList.cfm inside webroot/com/cfms,
you can call it from a Flash Remoting application as follows:
cfmService = gatewayConnection.getService(“com.cfms”, this);
cfmService.GetCompanyList();
30546228 ch26.F 1/30/03 12:14 PM Page 586
587
Chapter 26 ✦ Flash Remoting Services
If you want to send parameters to a ColdFusion template, just set them positionally in an
ActionScript array, as follows:
Flash.Params = new Array();
Flash.Params[0] = 115;
Flash.Params[1] = “Razzmatazz Industries”;
Flash.Params[2] = “35 Bowling Way”;
Flash.Params[3] = “Atlanta”;
Flash.Params is received by ColdFusion as a structure named Flash that’s containing an

array rather than as a plain array. You can access the parameters from within ColdFusion by
using standard dot notation, as follows:
Flash.Params[1]
Flash.Params[2]
Flash.Params[3]
Flash.Params[4]
Notice that an “index shift” occurs because ActionScript arrays are zero-based (that is, they
start at index
0) whereas ColdFusion arrays are one-based (that is, they start at index 1).
To send data from a ColdFusion template back to the Flash Remoting Gateway, you assign the
return data to the
Result variable in ColdFusion MX’s new Flash scope. If you have a
ColdFusion template that creates a query object named
myQuery that you want to return to
the Flash Remoting Gateway, for example, assign it to
Flash.Result, as follows:
<cfset Flash.Result = myQuery>
The Flash Remoting Gateway takes whatever is set in Flash.Result and routes it to the
appropriate callback method in your Flash movie, just as it would if it received data back
from a ColdFusion component function.
Integrating Web services with Flash Remoting
To make your Flash Remoting application work from a Web service rather than a ColdFusion
component, just replace the
webroot subdirectory path with the full URL to the Web service’s
WSDL file, as follows:
wsdlURL = “ />companyService = gatewayConnection.getService(wsdlURL, this);
Now you can call the Web service’s functions by using the same syntax you’re used to, as
follows:
companyService.listCompanies();
You can reference any WSDL file on any platform. Where ColdFusion MX uses the URL to a

CFC with a
wsdl parameter tacked on, some systems have precreated WSDL files as follows:
wsdlURL = “ />companyService = gatewayConnection.getService(wsdlURL, this);
Regardless of the target platform or how the WSDL file is generated, as long as you can point
to a valid WSDL file, the Flash Remoting Gateway can use it.
30546228 ch26.F 1/30/03 12:14 PM Page 587
588
Part IV ✦ ColdFusion MX Components, Web Services, and Flash Integration
Creating paged data displays
If your Flash query returns thousands of records from ColdFusion, you probably want to start
returning the first page of records to Flash as soon as they become available rather than wait
for all of them. By setting the values of
Flash.Pagesize in ColdFusion and calling RecordSet.
setDeliveryMode() in ActionScript, you can make Flash Remoting handle large record sets
in “pages.”
ColdFusion controls the initial return of data by setting the value of
Flash.Pagesize to the
number of records to place in each “page,” as follows:
<cfset Flash.Pagesize = 10>
If the query returned by the function call contains more than Flash.Pagesize number of
records, the
RecordSet becomes “pageable” by Flash Remoting (i.e., you can view one page
of rows at a time, rather than all of them at once), and the first
Flash.Pagesize number of
records to be returned from the query are immediately returned to Flash Remoting while the
remaining records continue to arrive in the background.
After ColdFusion makes its initial return to the Flash Remoting Gateway, the Flash movie must
specify how the remainder of the data retrieval is to behave, and it does so through the
RecordSet function setDeliveryMode().
setDeliveryMode() has the following three settings:


recordSet.setDeliveryMode(“ondemand”): The default setting instructs the
Gateway to stream more records as needed by the databound form control that
requests them as, for example, a list box scrolls through its records.

recordSet.setDeliveryMode(“page”, pageSize, pagesToPreFetch): This setting
instructs the Gateway to prefetch a number of pages of a specified size.

recordSet.setDeliveryMode(“fetchall”, recordsInEachGroup): This setting
downloads a specific number of records in each group rather than a number of pages
of a specific size.
Your Flash movie can test the current status of record retrieval through the use of the follow-
ing additional
RecordSet functions:

recordSet.getNumberAvailable(): This function returns the number of records that
have already been returned to the Flash movie.

recordSet.isFullyPopulated(): This function returns true if all records have been
received by the Flash movie; otherwise, it returns
false.
Flash.Pagesize can control data returned from both standard ColdFusion templates and
ColdFusion components.
Return numeric 1 or 0 rather than Boolean literal
Flash Remoting does a great job of data conversion between Flash and its remote platforms,
but one conversion that it doesn’t make is from ColdFusion’s boolean literals
True and False
to Flash’s version of true and false. For this reason, rewrite your ColdFusion functions that
normally return a Boolean value to instead return a numeric
1 or 0 and your Flash Remoting

applications can cast these values to their Boolean equivalents.
30546228 ch26.F 1/30/03 12:14 PM Page 588
589
Chapter 26 ✦ Flash Remoting Services
Securing Flash Remoting applications
To secure access to your Flash Remoting applications, use the setCredentials() function
of the
NetConnection object to set the username and password that are passed through the
Flash Remoting Gateway to ColdFusion MX. Suppose, for example, that you modify the con-
nection code from Listing 26-2 as follows:
gatewayURL = “http://localhost/flashservices/gateway”;
gatewayConnection = NetServices.createGatewayConnection(gatewayURL);
gatewayConnection.setCredentials(“”, “cutiepie”);
companyService =
gatewayConnection.getService(“com.flashremoting.Company”, this);
ColdFusion creates two structure keys named cflogin.name and cflogin.password to con-
tain
and cutiepie, respectively. In your ColdFusion code, you can now
retrieve the user record based on
cflogin.name (which contains “”)
and, if it’s found, further test the retrieved password if it matches what was passed from
Flash Remoting to
cflogin.password (which contains “cutiepie”). If you get a complete
match, you can then log in the Flash Remoting user by using ColdFusion MX’s standard secu-
rity mechanism, for example, as follows:
<cflogin>
<cfloginuser name=”#cflogin.name#”
password=”#cflogin.password#”
roles=”#ValueList(rolesQuery.RoleCode)#”>
</cflogin>

rolesQuery is a ColdFusion query object with a RoleCode column that contains the names
of the roles in which the authenticating user was granted membership.
Now if a Flash Remoting application attempts to call a component function or Web service
that is secured by using the
roles attribute of CFFUNCTION, the function throws an error if
the Flash user is not authorized to have access, and the error callback function (
_Status) is
called instead of the standard callback function (
_Result).
Summary
In this chapter you learned how to create a complete Flash Remoting application and how to
handle various details such as role-based user authentication and authorization.
If you’re not a Flash developer, now’s the time to become one. Even if you’re the typical
coder-type who can’t even draw a decent rectangle, you can team up with a designer-type
who can, and the two of you can make beautiful music together.
For further details on coding Flash Remoting applications, download and read the PDF enti-
tled “Using Flash Remoting MX with ColdFusion MX” from
www.Macromedia.com. This docu-
ment is an update that completely replaces Chapter 29 in your Developing ColdFusion MX
Applications with CFML book, which is part of the standard ColdFusion MX documentation
set. Among other things, this PDF shows additional methods for passing complex variables
between ActionScript and ColdFusion.
We wish that we had more space to discuss Flash Remoting applications, as they are fast,
scalable, relatively easy to create, and. most of all. cool, but to do justice to a deeper discus-
sion of the topic would require its own book. Luckily, you will find such a book in Complete
Flash Remoting by Joey Lott (Wiley).
✦✦✦
30546228 ch26.F 1/30/03 12:14 PM Page 589
30546228 ch26.F 1/30/03 12:14 PM Page 590
Using Server-Side

ActionScript
S
erver-side ActionScript is another facet of Flash Remoting
Services, but we wanted to split it out into its own chapter
because we don’t want you to confuse its purpose or its target devel-
oper audience.
Server-side ActionScript (SSAS) is similar in function to ColdFusion com-
ponents in that a single server-side file that declares multiple functions
can be instantiated as a service in the Flash Remoting Gateway, and a
Flash movie may then call functions of this service through the
Gateway. Although SSAS sounds at first like a direct replacement for
ColdFusion components, it is not. SSAS has an extremely limited func-
tion set; in fact, it can perform only the equivalent of
CFQUERY and
CFHTTP calls, and even those are a bit cumbersome.
Most likely, this chapter is not for you, because SSAS was designed
for Flash developers who need access to simple ColdFusion function-
ality. This chapter is included mainly for you to share with your Flash
designer and developer associates so that they can perform these
simple tasks by themselves. For anything more complicated, they
need a ColdFusion developer such as you to implement their solu-
tions by using the techniques that you learn in Chapter 26.
You should, however, learn the ins and outs of SSAS so that you can
make informed decisions and correctly advise your clientele about
the technology.
External ActionScripts as Data
Providers
As you may remember from Chapter 26, the following code shows
how you establish a Flash Remoting Gateway service between your
Flash movie and a ColdFusion component:

gatewayURL =
“http://localhost/flashservices/gateway”;
gatewayConnection =
NetServices.createGatewayConnection(gatewayURL);
companyService =
gatewayConnection.getService(“com.flashremoting.Comp
any”, this);
27
27
CHAPTER
✦✦✦✦
In This Chapter
Understanding the
scope and purpose of
server-side ActionScript
Modifying client-side
ActionScript to interface
with server-side
ActionScript
Performing queries,
POSTs, and GETs by
using server-side
ActionScript
✦✦✦✦
31546228 ch27.F 1/30/03 12:14 PM Page 591
592
Part IV ✦ ColdFusion MX Components, Web Services, and Flash Integration
You can use SSAS files in the same way. Here’s how it works: Whenever a service is requested,
the Flash Remoting Gateway seeks out any file named either
servicename.cfc or

servicename.asr and establishes a service with the file that it finds.
If you declare similar functions in a SSAS file named
CompanySS.asr and place it in the same
directory as the
Company.cfc component that you create in Chapter 26, for example, you
simply change the service name from
Company to CompanySS, as follows:
gatewayURL = “http://localhost/flashservices/gateway”;
gatewayConnection = NetServices.createGatewayConnection(gatewayURL);
companyService =
gatewayConnection.getService(“com.flashremoting.CompanySS”, this);
The remainder of your syntax for calling SSAS functions and utilizing their results is almost
identical to what you learn in Chapter 26.
To use SSAS with the Flash Remoting application that you build in Chapter 26, you need to
make only the following two small changes to the ActionScript in Frame 1 of the
actions
layer:
✦ Change the service name from
Company to CompanySS, as shown in the preceding code
block.
✦ Change argument passing from named to positional syntax.
SSAS seems to balk at having named arguments passed to it, so this is another important
caveat to consider in deciding whether to use SSAS, as optional arguments become a problem
with positional syntax.
Listing 27-1 shows what the ActionScript in Frame 1 of the
actions layer looks like after it’s
modified to work with SSAS.
Listing 27-1: Client-side ActionScript modified to work with
server-side ActionScript
#include “NetDebug.as”

#include “NetServices.as”
#include “DataGlue.as”
gatewayURL = “http://localhost/flashservices/gateway”;
gatewayConnection = NetServices.createGatewayConnection(gatewayURL);
companyService =
gatewayConnection.getService(“com.flashremoting.CompanySS”, this);
function listCompanies_Result(companyListResult) {
DataGlue.BindFormatStrings(companyToShow_cb, companyListResult,
“#CompanyName#”, “#CompanyID#”);
status_txt.text = “”;
}
function getCompany() {
companyService.GetCompany(companyToShow_cb.getSelectedItem().data);
}
31546228 ch27.F 1/30/03 12:14 PM Page 592
593
Chapter 27 ✦ Using Server-Side ActionScript
function getCompany_Result(companyRecord) {
companyName_txt.text = companyRecord.items[0].CompanyName;
address_txt.text = companyRecord.items[0].Address;
city_txt.text = companyRecord.items[0].City;
state_txt.text = companyRecord.items[0].State;
zipCode_txt.text = companyRecord.items[0].ZipCode;
}
function updateCompany() {
companyService.updateCompany(
companyToShow_cb.getSelectedItem().data,
companyName_txt.text,
address_txt.text,
city_txt.text,

state_txt.text,
zipCode_txt.text
);
}
function updateCompany_Result() {
companyService.listCompanies();
}
function updateCompany_Status() {
status_txt.text = “An error occurred.”;
}
companyService.listCompanies();
stop();
Notice the switch from passing named arguments to passing positional arguments.
Now all you need to do is create a file named
CompanySS.asr containing the code in Listing
27-2 and to place it in your
webroot/com/flashremoting/ directory.
Listing 27-2: Server-side ActionScript that duplicates the functionality
of Company.cfc
function GetCompany(CompanyID) {
var sqlString = “SELECT CompanyID, CompanyName, Address, City,
State, ZipCode, Comments FROM Company WHERE CompanyID = “;
newSQL = sqlString.concat(CompanyID);
selectData = CF.query({datasource:”CFMXBible”, sql:newSQL});
if (selectData) {
return(selectData);
} else {
return null;
}
}

Continued
31546228 ch27.F 1/30/03 12:14 PM Page 593
594
Part IV ✦ ColdFusion MX Components, Web Services, and Flash Integration
Listing 27-2 (continued)
function listCompanies(companyFilter) {
if (arguments.length > 0) {
selectData = CF.query({datasource:”CFMXBible”,
sql:”SELECT CompanyID, CompanyName, Address, City, State,
ZipCode, Comments FROM Company WHERE CompanyName LIKE ‘“ +
companyFilter + “%’ ORDER BY CompanyName”});
} else {
selectData = CF.query({datasource:”CFMXBible”,
sql:”SELECT CompanyID, CompanyName, Address, City, State,
ZipCode, Comments FROM Company ORDER BY CompanyName”});
}
if (selectData) {
return(selectData);
} else {
return null;
}
}
function updateCompany (companyID, companyName, address, city, state,
zipCode, comments) {
if (arguments.length = 7) {
selectData = CF.query({datasource:”CFMXBible”,
sql:”UPDATE Company SET CompanyName = ‘“ + companyName +
“‘, Address = ‘“ + address + “‘, City = ‘“ + city + “‘, State = ‘“ +
state + “‘, ZipCode = ‘“ + zipCode + “‘, Comments = ‘“ + comments + “‘
WHERE CompanyID = “ + companyID});

} else {
selectData = CF.query({datasource:”CFMXBible”,
sql:”UPDATE Company SET CompanyName = ‘“ + companyName +
“‘, Address = ‘“ + address + “‘, City = ‘“ + city + “‘, State = ‘“ +
state + “‘, ZipCode = ‘“ + zipCode + “‘ WHERE CompanyID = “ +
companyID});
}
return;
}
Notice how this listing checks the number of arguments passed to the listCompanies() and
updateCompany() functions. This is one of the only ways to check whether an optional argu-
ment (which must be the last argument in the list) is passed. We must formulate completely
different SQL statements depending on whether or not the optional arguments are passed.
Now look at the code stew that we cooked up for the update statement in
updateCompany().
Yuck! But that’s what you must do because of the way that SSAS works. Bon appetit!
Anyway, give your repurposed Flash Remoting application a spin by choosing Control ➪ Test
Movie from the Flash menu bar. If you entered the code correctly, everything should work
exactly as it did when it used the
Company.cfc component. If not, check your code and use
the NetConnection Debugger, as shown in Chapter 26.
31546228 ch27.F 1/30/03 12:14 PM Page 594
595
Chapter 27 ✦ Using Server-Side ActionScript
Do not split SQL statements in SSAS on multiple lines as you often do in ColdFusion, as
doing so throws an error.
Of importance to the more advanced Flash developers who may want to use SSAS is that the
ColdFusion query object returned is automatically converted to an ActionScript
RecordSet
object. So after your Flash movie receives the RecordSet object, you may use any of the

native methods available in ActionScript for manipulating
RecordSet objects, such as
addItem(), removeItemAt(), and so on.
External ActionScripts as Remote Agents
The only other functionality beside CFQUERY available to SSAS is the CFHTTP functionality
found in ColdFusion, but a Flash movie is very limited as to what it can do with the results of
a
CFHTTP call.
The main reason why you would want to use SSAS’s HTTP functionality is to
POST data to an
external server. Listing 27-3, for example, shows how you would
POST to an external server
and send its response data back to the Flash movie.
Listing 27-3: CF.http POST example
function postToURL (firstname, lastname) {
var params = new Array();
params[1] = {name:”firstname”, type:”FormField”, value:firstname};
params[2] = {name:”lastname”, type:”FormField”, value:lastname};
result = CF.http({method:”post”,
url:”http://localhost/com/flashremoting/ActionPage.cfm”,
params:params
});
return result.get(“Filecontent”);
}
The Flash movie’s callback function now has full access to the data returned by the external
server.
Pay special attention to white-space generation in performing HTTP calls, as white space
becomes part of the HTTP response and, therefore, part of result.get(“Filecontent”).
If the Application.cfm file that is called as a part of the HTTP request does not contain
any display elements (such as a graphical page header), wrap all its code within a CFSILENT

tag pair. If the Application.cfm file does contain display elements, create a separate
Application.cfm file for the directory containing your remotely accessed POST pages,
include only functional (nondisplay) code in it, and wrap all its code in a CFSILENT tag pair.
Granted, the HTTP functionality of SSAS is very limited, but it’s there if you need it.
Caution
Caution
31546228 ch27.F 1/30/03 12:14 PM Page 595
596
Part IV ✦ ColdFusion MX Components, Web Services, and Flash Integration
Summary
In this chapter you learned how to make Flash Remoting applications with Server-Side
ActionScript, and why SSAS is most likely not the way a professional ColdFusion developer
would develop Flash Remoting applications.
Your first and best solution is to forego SSAS in favor of its stronger and more handsome
brother, ColdFusion components. Think of all the functionality that you give up by moving
away from the ColdFusion MX technology that you learn in this book!
If you’re working with Flash designers who want to get started using a little ColdFusion, how-
ever, SSAS is perfect for them.
It may seem a bit funny, but we think that SSAS’s biggest benefit is that it brings Flash devel-
opers and ColdFusion developers together in such a way that they often trade skill sets, and
this natural “cross pollination” turns out a better quality development staff overall.
✦✦✦
31546228 ch27.F 1/30/03 12:14 PM Page 596
Integrating
ColdFusion MX with
Other Technologies
✦✦✦✦
In This Part
Chapter 28
Integrating ColdFusion

MX and Java
Chapter 29
Integrating COM
Chapter 30
Integrating ColdFusion
MX with XML and
WDDX
Chapter 31
Communicating via
Mail, FTP, and HTTP
✦✦✦✦
PART
V
V
32546228 PP05.F 1/30/03 12:14 PM Page 597
32546228 PP05.F 1/30/03 12:14 PM Page 598
Integrating
ColdFusion MX
and Java
B
efore you skip this chapter, thinking, “I don’t know Java, so no
point in reading on,” please don’t. Most of the opportunities for
integrating ColdFusion and Java don’t require that you have any Java
language skills. That may seem hard to accept.
One of the great features of Java is a strong focus on reusability — the
opportunity to develop code that can be reused by different pro-
grams and different developers. The converse is that you can use
Java code developed by others. This extends to enabling CF develop-
ers to make use of many interesting Java integration points.
CF MX dramatically extends the Java integration capabilities that

existed in CF 4.5.2 and CF 5. Even for developers still working in those
releases, much of the information in this chapter still applies.
Of course, a Java developer can make even greater use of the integra-
tion possibilities, creating his own Java programs and taking advan-
tage of still more Java and J2EE features. But non-Java developers
also need to be aware of these integration opportunities.
Many aspects of using Java within ColdFusion don’t require writing
and compiling Java programs, and you have ways to employ the Java
libraries, if you know what they are (as we explain later in this chap-
ter), directly from within CFML.
We introduce in this chapter the many Java integration points by
order of the features requiring the least Java language understanding
and ending with those that require the most. Again, any of these can
be used to even greater advantage by a developer with Java language
skills. The topics that we address in this chapter are as follows:
Many, although not all, of these features are newly enabled or
enhanced over those of earlier releases because of CF MX’s underly-
ing J2EE engine. We begin with those features that require the least
amount of Java understanding.
28
28
CHAPTER
✦✦✦✦
In This Chapter
Employing J2EE sessions
Calling JSP custom tags
Using applets
Leveraging the Java API
by using CFOBJECT
Running JavaServer

Pages and Servlets
within CF MX
Exploring interactions
between CFML and
JSPs/Servlets
Calling Java CFX
custom tags
Investigating other Java
integration topics and
learning more
✦✦✦✦
33546228 ch28.F 1/30/03 12:14 PM Page 599
600
Part V ✦ Integrating ColdFusion MX with Other Technologies
Using J2EE Sessions
The first aspect integrating ColdFusion with Java doesn’t really concern the Java language at
all but J2EE sessions. This is an option that you can turn on or not and that comes to you by
way of the underlying J2EE server that sits beneath CF MX.
One of the most powerful new features of CF MX is the fact that it’s built to run atop a J2EE
server. The underlying J2EE engine is Macromedia’s JRun server. This is transparent to CF
developers, and the fact that this integration is something that you needn’t be concerned
with is a testament to the engineering design achievement of CF MX. It does, however, open
the doors to possibilities that simply weren’t available prior to CF MX.
Just before this book went to print, Macromedia announced a new version of ColdFusion MX,
called ColdFusion MX for J2EE, designed to be installed on an already existing J2EE server.
Initially supported environments are IBM WebSphere, Sun One Server, and JRun (for cus-
tomers who already own JRun), with support for BEA WebLogic to follow shortly thereafter
(and likely available by the time that you read this chapter).
The differences between this new version and the basic ColdFusion MX should be relatively
minor regarding the topics covered in this chapter. Still, you should explore the release notes

for these products for compatibility issues that Macromedia identifies.
The J2EE sessions feature is simply an alternative to the built-in session support that’s always
been available in ColdFusion. But it adds several benefits, as follows:
✦ The session identifier used by J2EE sessions,
jsessionid, is more secure.
✦ J2EE sessions are supported by a nonpersistent cookie, so sessions close whenever the
browser closes.
✦ Sessions can be supported for browsers that do not permit persistent cookies.
✦ J2EE sessions can be shared with JSPs and servlets running under CF MX.
Unfortunately, some aspects of working with J2EE sessions can also cause trouble, particu-
larly if the browser visitor doesn’t support cookies. This is explained later in this chapter.
Enabling J2EE Sessions
J2EE sessions are easily enabled and require no changes in coding to use them. You find an
option in the CF MX Administrator under the Server Settings heading, Memory Variables link.
Select the Use J2EE Sessions check box. Although the screen doesn’t say so, you need to
restart the CF MX server before the change takes effect.
After J2EE sessions are enabled, they affect all code in all applications on the server that use
<cfapplication sessionmanagement=”yes”>. No other change to the application code is
necessary. This feature, by the way, works in both the Enterprise and Professional Editions of
ColdFusion MX.
New SessionIDs
After enabling J2EE sessions and restarting the server, you notice (if you have server debug-
ging displayed or use
<cfdump var=”#session#”>, for example) that the values shown for
Note
33546228 ch28.F 1/30/03 12:14 PM Page 600
601
Chapter 28 ✦ Integrating ColdFusion MX and Java
session variables reflect new information. First, without J2EE sessions enabled, the value of
the session variable

sessionid may look as follows:
sessionid=_2704_73826960
This reflects a combination of the cfid and cftoken, which are the keys that have enabled
session support prior to J2EE sessions. With J2EE sessions enabled, it instead appears in the
following format:
sessionid=8030584681031438559214
This reflects a key change from using the old cfid/cftoken pair for supporting sessions to
using a new single 22-digit number. We discuss the security benefits of that later in this chapter.
Second, you observe that the session variable
urltoken also reflects new information.
Without J2EE sessions,
urltoken may look as follows:
urltoken=cfid=2704&cftoken=73826960
But with J2EE sessions enabled, it shows a new jsessionid value (rather than sessionid)
appended to the end of the string, as in the following example:
urltoken=cfid=2704&cftoken=73826960&jsessionid=8030584681031438559214
This urltoken is formed as a query string, and it or jsessionid are used in supporting
browsers that don’t enable cookies. (You find more information about that later in this chapter.).
Finally, yet another difference is that, without J2EE sessions enabled, you also have
cfid and
cftoken variables in the session scope. But if you enable J2EE sessions, those no longer
exist. It makes sense, because the
sessionid is that 22-digit number. The cfid and cftoken
still exist in the cookie scope, but be aware that, if you have code that refers to
session.cfid or session.cftoken, that no longer works with J2EE sessions enabled.
Benefits of J2EE sessions
The change in format of the urltoken and jsessionid variables is key to enabling J2EE ses-
sions, but it’s not really an apparent benefit. Still, a couple aspects of the change are indeed
beneficial.
First, the change to a 22-digit number for the

sessionid has a security benefit. Sessions are
generally supported by way of two cookie variables:
cfid and cftoken. Sessions can also be
supported by passing those variables on the query string in a URL (which, again, is the pur-
pose of the
urltoken). But the value of the cfid and cftoken variables being such small
numbers makes them rather easy to guess.
If your J2EE sessions are using a much longer value for the
sessionid, the chances are
reduced that the
jsessionid or urltoken values can be randomly guessed if presented as
either cookie or URL variables.
You can attain increased security regarding the simplicity of cftoken values, without
enabling J2EE sessions, by using another new feature in CF MX that enables you to ask the
server to generate more elaborate UUIDs (universally unique identifiers) for the cftoken.
This is enabled in the CF Administrator, on the Server Settings page, by selecting the Use
UUID for cftoken check box. As you do in enabling J2EE sessions, you need to restart the
CF MX server for this change to take effect but do not need to change any code to benefit
from the new feature.
Note
33546228 ch28.F 1/30/03 12:14 PM Page 601
602
Part V ✦ Integrating ColdFusion MX with Other Technologies
Another, perhaps more valuable, benefit of J2EE sessions is the fact that the server creates a
nonpersistent cookie that is sent to the browser for supporting sessions. By nonpersistent, we
mean a cookie that is not stored on disk in the browser but instead is stored only in the
browser’s memory. That way, after the browser is closed, the cookie is lost, and that browser,
therefore, no longer has any connection to that session. On the next visit by that user in a
new browser window, he is given a new
jsessionid by the server. (You need to understand

some facets concerning when a browser is really considered “closed.” See the section “When
does a session end?” a little later in this chapter, for more information.)
These nonpersistent cookies are also sometimes referred to as per-session or temporary cook-
ies. This leads to another benefit of using J2EE sessions to those organizations that can’t use
persistent cookies (such as the
cfid and cftoken cookie values set by CF MX and earlier ver-
sions). These organizations can use J2EE sessions much more easily than they can CF-based
sessions, because J2EE sessions use nonpersistent cookies. We should mention that you do
have ways in all releases of CF to force the
cfid and cftoken to become nonpersistent, as
outlined in the Macromedia Technote at
www.macromedia.com/v1/Handlers/index.
cfm?ID=21079&Method=Full. But with J2EE sessions, you don’t need to bother with that
sort of “hack.”
One final benefit of using J2EE sessions, which may not benefit all CF developers, is that using
them enables the sharing of sessions and variables with JSP and servlet programs that also
run in CF MX.
Challenges with J2EE sessions
While J2EE sessions represent a step forward in security and robustness, they leave some
challenges to be dealt with. First, we must deal with the issue of when sessions end — a differ-
ent proposition with ColdFusion MX. Second, we must find a way to provide applications that
do not depend on cookies being enabled. This is particularly true with public sites.
When does a session end?
We mention in the section “Benefits of J2EE sessions,” a bit earlier in this chapter, that under-
standing the “sessions terminate on browser close” notion that’s enabled by J2EE sessions
requires some further discussion. To clarify, the session closes (or, rather, the browser loses
its nonpersistent cookie) after the last browser session that you opened is closed. In
Netscape Navigator 4, for example, if you open multiple browser windows (by using the File ➪
New Navigator Window menu command or the Ctrl+N keystroke), those windows all share the
same sessionid. Only after all these browser windows are closed us the session itself really

“closed.”
Technically, the session isn’t really terminated — on the server at least—even after all browser
windows are closed. The session continues to exist on the server until the server determines
that the sessions must be timed out. But with the nonpersistent cookie now deleted, a new
browser window that returns to the site is given a new sessionid and a new session.
In Internet Explorer, the question of whether one or many browser windows need to be
closed to “close” the session depends on how the windows are opened. If they’re opened by
using the File ➪ New Window menu command or the Ctrl+N keystroke, those windows share a
single
sessionid. But if a new browser window is opened by using Start ➪ Programs ➪
Internet Explorer or by clicking an icon on the desktop or in your system tray’s taskbar
launcher, that new window gets its own
sessionid. This has two ramifications: First, it
Note
33546228 ch28.F 1/30/03 12:14 PM Page 602
603
Chapter 28 ✦ Integrating ColdFusion MX and Java
means that you may be surprised to find that multiple IE windows don’t share the same ses-
sion. Further, you can have sessions for some windows that terminate after their browser
windows closed while still keeping other IE windows — and their sessions — open. But, again,
closing them all should “close” any sessions in which J2EE session variables are enabled. Be
aware, however, that, if you ran the internal browser in ColdFusion Studio, doing so has cre-
ated another instance of a browser window.
Challenges if cookies are not presented
Further challenges arise in respect to J2EE sessions if a visitor’s browser doesn’t support
cookies. This problem doesn’t involve only those browsers that are too old to support cook-
ies but may also arise if organizations force users to disable cookie support in their browsers.
In such a case, you may be attempting to handle noncookie browsers by using the
session.cfid and session.cftoken variables or the session.urltoken variable in either
query strings or forms that you build and send to the browser. As we mention earlier in this

chapter, with J2EE sessions, the
cfid and cftoken variables no longer exist in the session
scope. (They are still in the cookie scope — at least while the CFML is being executed — and
in the client scope if client variables are enabled.)
You may think to use the
session.urltoken variable that we mentioned, [GSL1]but on the
built-in CF MX Web server, that doesn’t persist your session. It doesn’t pay attention to a
jsessionid passed on the query string. Instead, being a Java Web server, it expects it to be
passed in a different format.
Indeed, a new function is available to assist in doing just that sort of processing. The new
URLSessionFormat() function is quite interesting, in that it appends the necessary sessionid
variables to a URL if it detects that the browser requesting the page does not support cookies
(or, more accurately, if it has not presented any cookies). An example may be as follows:
<cfoutput>
<a href=”#urlsessionformat(“mypage.cfm?id=123”)#”>link to mypage</a>
</cfoutput>
If the browser supports cookies (or, more accurately, cookies from this domain are presented
by the browser as this page is executed), the result is simply as follows:
<a href=”mypage.cfm?id=123”>link to mypage</a>
But if the browser doesn’t support cookies (or again, more accurately, cookies from this
domain are not presented by the browser as this page is executed), the result depends on
whether J2EE sessions are enabled. If they are not enabled, the result is as follows:
<a href=”mypage.cfm?id=123&CFID=3004&CFTOKEN=98931500”>link to
mypage</a>
But with J2EE sessions enabled, the result is as follows:
<a href=”mypage.cfm;JSESSIONID=8030472831031469485864?id=123”>link to
mypage</a>
Notice, however, that in the second case, the URL that is formed is not appending the jses-
sionid as a query string; instead, it’s appending it immediately after the file name and exten-
sion, prefaced by a semicolon. That works fine for the built-in Web server that comes with CF

MX (and other Java-based Web servers). But if you’ve integrated CF MX with Microsoft’s
Internet Information Server Web server, such a URL leads to a
404 File Not Found error.
33546228 ch28.F 1/30/03 12:14 PM Page 603
604
Part V ✦ Integrating ColdFusion MX with Other Technologies
If you’re using IIS with J2EE sessions, therefore, you should not use the URLSessionFormat()
to support browsers with cookies disabled — at least until Macromedia (or Microsoft)
addresses this issue. Instead, use code such as the following:
<cfoutput>
<a href=”mypage.cfm?id=123<cfif cgi.http_cookie is
“”>&#session.urltoken#</cfif>”>link to mypage</a>
</cfoutput>
Unfortunately, you can’t use this code fragment with the built-in CF MX Web server. It doesn’t
recognize the
jsessionid that’s being passed as a query string argument. It recognizes only
a
jsessionid being passed after the file name, prefaced by a semicolon.
Along the same lines, you face a similar problem in using the
CFLOCATION tag. In this same
sort of situation, where the tag’s used in a page executed by a browser that doesn’t present
cookies, the tag creates a URL that includes the
jsessionid following the file name and
extension, prepended with a semicolon. That URL fails on IIS servers. Even using the
addto-
ken=”no” attribute with the tag doesn’t change it.
What’s worse, even if you are working on the CF MX Web server, consider what can happen if
you use
CFLOCATION to redirect control to a remote server that’s running IIS. Again, if the
browser executing the page does not support or present cookies, the URL that it generates

fails. Again, perhaps Macromedia will eventually modify the tag so that the
addtoken=”no”
attribute works to prevent this ;jsessionid string from getting appended to the file name if
it’s not desirable for it to be there.
Calling JSP Custom Tags
In ColdFusion MX, you can now use JSP custom tags — in the Enterprise Edition of CF MX,
that is; unfortunately, this feature is not enabled in the Professional Edition. As are CF custom
tags, JSP custom tags are a means by which JSP developers can add new functionality to their
pages. What does that mean to you, as a CFML developer?
Well, as is the case with J2EE sessions, you don’t need to know Java (nor even use or under-
stand JSPs) to use JSP custom tags. They’re very easy to use, and libraries with hundreds of
them are available on the Internet for consumption by the JSP world — and now by CF devel-
opers as well.
Some solutions that you can use in your own CF development may already exist as JSP cus-
tom tags, and they are available to you in CF MX by following just a few simple steps. If you
visit the Web site
for example, and view the
calendar taglib link, you see a discussion of how to use a JSP custom tag to easily create a
calendar for the current month by using the following line of code:
<%@ taglib uri=”taglib.tld” prefix=”cal” %>
<cal:Calendar />
Whoa! What’s that? Well, it is JSP code. But we’re going to show you how to use that same
<cal:Calendar> custom tag in CFML, which is just as easy as using it in JSP. In fact, you can
incorporate this JSP custom tag into your CF MX code in just five simple steps, which we
describe in the following sections.
33546228 ch28.F 1/30/03 12:14 PM Page 604

×