Using_FOD
Written by LeeFJ
详见上篇压缩包内文档
一、概 述
FDO是一套可以在Flash和服务端之间进行数据库操作的组件,它把Flash客户端和服务端整合在一起,并使用XML来完成数据交换。你可以使用FDO进行查询、更新等操作。FDO还可以进行一定的扩展,哪怕不是作数据库操作也可以使用FDO,比如说返回服务端的一些信息等。由于服务端可以采用多种技术,这样只要符合规定的数据交换格式,服务端功能就可以采用多种技术实现,当前这个版本是使用ASP实现的,仅具备一些最简单的功能。在FDO调试时,采用了一种比较简单、相对常用的模式:Flash+ASP+Access。另外服务端的程序除了主模块外,都是可以进行一定程度的修改的,以适应不同业务的需求。当然FDO还可以实现一些扩展功能,以适应不同业务逻辑的需要。
在安全性上,FD并不是把SQL传输到服务端,它只可以发送一个命令字符串和相关的参数。服务端接受这些数据,并根据命令字符串查找已经在服务器定义好的SQL,代入参数执行SQL并返回结果。另外FDO对SQL注入也做了一定的防范,SQL注入。
这里我将逐步介绍如何在您的Flash应用中使用ASP版本的FDO。另外您还可以在另外的参考文档中查看FDO的部分技术参数和用户接口。在FDO_ASP.rar压缩包中已经给出了FDO的所以原程序以及相关注释,您可以按照自己的要求修改和扩充。
二、使用FDO
下面介绍一下如和在您的应用中使用FDO,我将一步一步的详细讲解。
[1] 搭建调试环境
在你的硬盘创建你的站点目录,我这里命名为mySite。解压缩FDO压缩包,里面包括四个文件夹:
·FDO_SERVER:服务端FDO目录,根据实际的需要可以修改目录名称。
·CLIENT:客户端FDO类文件,组件文件。
·DATABASE:调试用的数据库目录。
·DOC:FDO的相关文档。
把他们拷贝到mySite你的站点目录下,同时在你的Dreamweaver建立对应的mySite站点。现在打开IIS,建立一个mySite的虚拟目录。
然后根据你的实际需要修改FDO服务器FDO_SERVER文件夹的名称,我把它修改为:myFDO_sv_1,入图所示。当然如果你不觉得要修改也可以不修改它。
完成这些以后,可以进行一下进行数据库连接的测试,在IIS中,浏览FDO_conn_test.asp文件,对数据库连接进行测试。当然你可能会使用其他的数据库,这需要另外的配置,等一下在说。
IIS会打开IE运行FDO_conn_test.asp,如果运行结果如图所显示,则说明连接成功,可以进行接下来的操作。
这样,调试环境就差不多搭建好了,着几乎也是在本地建立ASP站点的基本步骤。
接着建立Flash工程myFl,并创建addnew_Test.fla的Flash文档。在站点根目录建立myFl_Prj文件夹,用于存放Flash文件,如图建立一个我自己的工程。
把类文件加入到你的工程,这里有两种方法。先说第一中方法。把CLIENT目录下的FDO文件夹拷贝至myFl_Prj文件夹下,CLIENT目录下的as文件都是FDO的源文件,这个不说,大家也知道了。如图:
接着需要为Flash添加一个类路径,在EditàPreferencàActionscriptàActionscript 2.0 Settings如图添加一条./FDO的类路径:
这样就可以进行调试了。第二种方法是把FDO以组件的方式发布,拷贝CLIENT目录下的FDO.swc到Flash安装目录下的en/Configuration/Components/Data Components下,然后重新启动Flash,调出组件面板就可以看到FDO组件了。
然后,把这个组件加入到当前的Flash文件,在库面板出现FDO的库项目。做完这些以后就可以和服务端配合调试FDO了。但需要注意的是第一种方法和第二种
现在在addnew_Test.fla Flash文档的第一帧加入如下代码并测试。
var baseUrl:String="http://127.0.0.1/mySite";
var fdo_sv1_name:String="myFDO_sv_1";
var myfdo_1:FDO=new FDO(baseUrl,fdo_sv1_name) ;
在Output面板中输出:
[debug] Create FDO;FDO_ServerNane:myFDO_sv_1; SiteUrl:http://127.0.0.1/mySite
这里需要解释一下,baseUrl是指你的站点URL,我电脑上的IIS由于和其他软件冲突使用了88端口,您电脑上的一般都是80端口在URL中无须指明端口。这个baseUrl在IE地址栏中直接截取粘贴就可以了。fdo_sv1_name也就是FDO服务器的名称,也就是刚才把文件夹名由FDO_SERVER修改为myFDO_sv_1的那个文件夹的当前名称。
好了,这样基本的架构就搭好了,可以进行数据库配置。
[2] 配置数据库
这里还是以Access数据库为例来说名数据库的配置。数据库不一定要放在DATABASE目录下,为了安全起见,你完全可以修改DATABASE文件夹的名称或把数据库方在其他什么地方。这里我另外建立文件夹在放置数据库。如图,我建立了LeeFJ_db文件夹作为数据库的文件夹。
然后,建立名为myData.mdb的Access数据库。我建立一个News表,包括ID,title,content,EnterTime字段。如图
数据库建立以后,需要修改数据库连接配置文件:FDO_conn.asp,在这个文件中,定义了数据库连接配置信息,如果你需要使用其他类型的数据库,请修改其中的数据库连接字符串。现在打开这个文件,修改第二行代码:database="../database/fdo.mdb"为database="../LeeFJ_db/myData.mdb",然后浏览FDO_conn_test.asp文件再次进行数据库测试。如果浏览器中空白或没有连接成功的提示则说明连接错误,需要调整你的代码。另外如果浏览器是空白的你可以查看网页源代码,查看错误提示信息。
另外还需要提一句,FDO支持多数据库连接,你可以更改FDO的数据库连接,在FDO_conn_test.asp的13至17行已经给出了更改数据库连接的代码:
dim connstr
connstr="Driver={Microsoft Access Driver (*.mdb)};dbq=" & server.MapPath("../database/fdo2.mdb")
call myfdo.changeBD (connstr)
response.Write("数据库连接被更改...<br>")
[3] 配置FDO服务器
FDO服务器的参数需要在不同的文件中配置,这个稍微麻烦了一点。但是不是很多,对于稍微了解ASP的朋友来说这个一点都不难。首先找到FDO_init.asp文件。查看其第20七行: call myfdo.init (cmd_len,parm_len,con), FDO的init包括三个参数。第一个参数指定命令字符串的最多个数,命令字符串就是等一下要在FDO_cmd_list.asp文件中定义的。第二个参数指定命令字符串附带的最多参数个数。这两个参数都是数字型的,最后一个是布尔型的,指明FDO初始化时是否需要连接数据库。
然后就可以定义FDO_cmd_list.asp中的命令了。在正式操作之前需要了解FDO的命令模式。这有点像暗号。关于这个我以前在Flash8发过贴子的。这里我在罗嗦一遍。
我们经常听到SQL注入之类的东西,Flash也可以被拆开来查看其内部的一些东西,所以可以这样认为,Flash是不安全的。就像你不会把你的密码写在javascript那样,你也不会(也不可以)把你的密码放在swf文件中。那么在你的swf文件中透露你的SQL也是致命的,他似乎比SQL注入更加糟糕,至少那些坏人可以少花点工夫了。基于这样一个原因,你不可以把SQL留在你的swf中!那么要怎么办呢?所以FDO中建立了一种映射,即一个命令字符串对应一个SQL这样在你的swf中就看不到半点SQL了。例如命令字符串是:tell me the fact可以对应一个SQL:select * from News。在执行时,swf把命令字符串外加若干参数发送到服务端,服务端程序查找与该命令字符串匹配的SQL并把参数代入SQL执行,然后返回执行结果。这样SQL除了开发者外,对其他人就隐藏了。也就在一定程度上保证了FDO的安全性。
现在我们看一下FDO_cmd_list.asp文件,我们可以修改原有的SQL语句,我修改列表为:
<%
redim cmd_list(cmd_len),sql_list(cmd_len)
'按顺序添加,如果存在同名命令则,下标小的命令优先执行
cmd_list(0)="getAllnews"
sql_list(0)="select * from News"
cmd_list(1)="addNews"
sql_list(1)="insert into News (title,content) values ('?','?')"
cmd_list(2)="updateNews"
sql_list(2)="update News set Content='?',Title='?' where id=?"
cmd_list(3)="deleteNews"
sql_list(3)="delete from News where id=?"
%>
这里有两个数组cmd_list和 sql_list相同下标的数组元素有对应关系,问号是参数所要代入的位置。这里需要区别是文本型参数还是数字性参数,大家看一下例子就明白了。当然不同的数据库可以有不同的SQL语句。需要提一下的是FDO的查询命令仅支持返回记录集的简单查询。另外,映射列表中有相同的命令字符串,则优先匹配优先执行,后面的同名命令将被忽略,命令匹配的查找方式是升序的,也就是位于数组后面的同名命令将始终被忽略。所以建议使用不同的命令字符串。命令字符串区分大小写。
这样我们就完成了服务端的基本配置,可以把年个精力集中在客户端Flash中了。当然FDO服务器还可以根据业务逻辑的需要进行扩展,这个等一下再说。
[4] 在Flash中调试FDO
刚才在客户端的代码中已经建立了FDO客户端对象,现在将详细介绍FDO客户端程序的编写。FDO的目的就是在于封装数据通信过程和复杂的服务端程序。这样你就可以集中精力对付客户端了。
刚才已经建立了数据库并建立了news表,里面是没有数据的。所以我先执行一个Addnew看看,但首先还是先介绍一下基本的原理。
客户端FDO构造函数包括两个参数:站点URL和FDO服务器名称。建立FDO对象后,需要创建一个Command对象与FDO对象进行绑定。这样Command就可以向FDO发送命令了。客户端FDO的执行实际上包括了两个过程,数据通信和服务端执行。所以FDO的执行是需要耗时的,这个到底要多少时间根据网络和服务器状况而定。所以当一个FDO对象正在执行时任何对他的命令都是无效的,直到他执行结束。基于这样一种情况,实际上在客户端可以创建多个FDO对象,同时执行不同的命令。
那么,要如何知道FDO命令执行是否已经结束、FDO命令执行的状态(百分比)呢?使用FDO还需要知道FDO的三个事件。
·onLoading:按照一定频度被FDO调用,这个频度可以使用FDO的setFreq方法进行设置,默认是50ms。它包括两个参数,依次是cmd:当前正在执行的命令字符串;percent:当前执行进度的百分比,这个值可以用于驱动进度条。
·onData:在查询数据到达后被调用。依次传入两个个参数,cmd:当前执行完毕的命令字符串;rcd:一个装有记录集的RecordSet对象。
·onResult:当FDO操作失败或当执行插入、更新、删除操作后,返回操作结果时被调用。依次传如三个参数,cmd:当前执行完毕的命令字符串;suc:反映操作结果的一个逻辑值,true则操作成功;rst:从服务器返回的操作结果。
好,现在我们可以开始了。先在library面板创建一些简单的图形界面,这个不细说了,大家看我的附带压缩包中fla文件的库项目。这是addnew_Test.fla文件的第一帧代码以及注释:
//创建FDO对象,并确定基路径,也就是FDO服务器所在的位置,或是相对于swf文件所在的位置,
//所以这里也可以使用相对路径
var baseUrl:String="http://localhost/mySite";
var fdo_sv1_name:String="myFDO_sv_1";
var myfdo_1:FDO=new FDO(baseUrl,fdo_sv1_name) ;
//设置FDO的onLoading事件调用频度,单位ms,FDO对象创建时默认100ms
myfdo_1.setFreq(5);
//创建Command对象,并与myfdo_1绑定
var cmd_1:Command=new Command(myfdo_1);
//更改Command对象的FDO帮定
//cmd_1.setFdo(myfdo_1);
//创建参数数组
var parm_1:Array=new Array();
//按照SQL中的问号次序,依次是新闻标题,新闻内容
parm_1.push("这是FDO的一个添加测试。");
parm_1.push("新闻内容...");
//Command的Addnew方法包括三个参数:命令字符串,参数列表、请求页面
//关于请求页面的在FDO扩展业务逻辑中进行介绍,Addnew方法的默认页面是FDO_addnew.asp,
//但必须在参数中指定
//如果有过多的参数,则后面的则被忽略
cmd_1.Addnew("addNews",parm_1,"FDO_addnew.asp");
//在onLoading函数中驱动进度条
myfdo_1.onLoading=function(cmdstr,pct)
{
exe_bar(pct);
}
//onResult事件中告诉用户操作已经完成、是否成功
myfdo_1.onResult=function(cmdstr,suc)
{
trace(cmdstr+";"+suc);
if(suc)
{
if(cmdstr=="addNews")
{
trace("新闻已经添加完成。")
info_txt.text="新闻已经添加完成。";
}
}
}
//进度条驱动函数
function exe_bar(pct)
{
bar_mc._width=200*pct/100;
info_txt.text="正在添加新闻...["+pct+"%"+"]"
}
执行结果如图:
再看看数据库中的数据,因为你在表面很难看出到底执行了什么,看一下数据表中的数据,很显然数据已经添加进去了。数据表如图:
下面可以了解一下FDO_addnew.asp的内容,这个文件中,只有一个方法:myfdo.addnew(),另外还有一个myfdo.log("服务端Addnew的返回值:"&rst)这是服务端调试,它会在Output面板中输出。这个在FDO扩展业务逻辑中再细说。
复制addnew_Test.fla重命名为ctn_addnew_Test.fla做一个连续添加的测试,只需要在onResult事件中添加一行cmd_1.Addnew("addNews",parm_1,"FDO_addnew.asp");就可以了。
既然已经添加了那么多数据,我们现在就可以把这些数据取出来,在复制addnew_Test.fla,命名为:query_Test.fla,把第一帧的代码修改为:
//设置FDO调试模式
debug.isDebug=true;
//创建FDO对象,并确定基路径,也就是FDO服务器所在的位置,或是相对于swf文件所在的位置,
//所以这里也可以使用相对路径
var baseUrl:String="http://localhost/mySite";
var fdo_sv1_name:String="myFDO_sv_1";
var myfdo_1:FDO=new FDO(baseUrl,fdo_sv1_name) ;
//设置FDO的onLoading事件调用频度,单位ms
myfdo_1.setFreq(5);
//创建Command对象,并与myfdo_1绑定
var cmd_1:Command=new Command(myfdo_1);
//更改Command对象的FDO帮定
//cmd_1.setFdo(myfdo_1);
//创建参数数组
var parm_1:Array=new Array();
//按照SQL中的问号次序,依次是新闻标题,新闻内容
parm_1.push("这是FDO的一个添加测试。");
parm_1.push("新闻内容...");
//Command的Addnew方法包括三个参数:命令字符串,参数列表、请求页面
//关于请求页面的在FDO扩展业务逻辑中进行介绍,Addnew方法的默认页面是FDO_addnew.asp,
//但必须在参数中指定
//如果有过多的参数,则后面的则被忽略
cmd_1.Addnew("addNews",parm_1,"FDO_addnew.asp");
//在onLoading函数中驱动进度条
myfdo_1.onLoading=function(cmdstr,pct)
{
exe_bar(pct);
}
//onResult事件中告诉用户操作已经完成、是否成功
myfdo_1.onResult=function(cmdstr,suc)
{
trace(cmdstr+";"+suc);
if(suc)
{
if(cmdstr=="addNews")
{
trace("新闻已经添加完成。")
info_txt.text="新闻已经添加完成。";
}
}
}
//进度条驱动函数
function exe_bar(pct)
{
bar_mc._width=200*pct/100;
info_txt.text="正在添加新闻...["+pct+"%"+"]"
}
调试输出:
[debug] Create FDO;FDO_ServerNane:myFDO_sv_1; SiteUrl:http://localhost/mySite
[debug] request_url:http://localhost/mySite/myFDO_sv_1/FDO_query.asp?fdolee
[server_debug] FDO已经创建...
[server_debug] FDO初始化完成...
[server_debug] 获取132条记录
[debug] ServerData Loaded....
数据已经获取
记录集长度:132
标题:这是FDO的一个添加测试。
这里涉及了RecordSet类,这个类中存储了从服务器返回的数据,并通过其方法可以轻松访问数据,在FDO_Ref.pdf中有详细介绍。我这里就不多说了。删除和更新操作基本与插入类似。给出范例大家自己看好了。
[5] FDO业务逻辑扩展
当然,FDO的初衷是进行数据库操作,但是它也可以执行一些扩展功能,这些扩展功能能够实现一定的业务逻辑,以实现一般网站的需要。FDO的这个扩展是非常重要的,这个扩展几乎可以替代前面提到过的FDO功能。下面我用一个具体的例子来演示一下FDO扩展的功能。
在正式开始之前,我觉得还是要先要了解一下比较重要的函数。通常情况下,一张页面只可以放Addnew,Query,Update,Delete函数中的一个,当然你也可以把他们放在一起,但这个需要特殊的技巧。
前面的例子中已经使用过FDO.log函数,使用这个函数可以使信息输出到Output面板。Addnew,Query,Update,Delete函数,都有一个参数,指定是否输出结果。如果True则自动输出结果返回给Flash。否则,用户需要自定义输出结果,使用FDO.setResult()就可以。也就是说,运行结果可以由FDO给出也可以用户自定义,但结果只可以有一次,不论是系统或是用户自定义的。FDO.setResult() 只可以用在有Addnew,Query,Update,Deletex参与的页面中。如果要在执行FDO扩展中返回执行结果,就必须使用exeFinish函数,该函数停止服务器响应并返回结果。
下面我来演示一个用户登陆,并在登陆后执行一个加法程序,返回结果。先在myData.mdb中建一个user表,录入一条记录。然后在myFl_Prj目录下新建一个Flash文档,名为logon. fla
接着在myFDO_sv_1目录新建logon.asp、getsum.asp和logout.asp文件,他们的代码请在例子中,自己找找啊。
总之代码是很简单的,只要程序不出错就可以了。
FDO做了好几天,挺累的,不想弄了,我把原文件都发给大家了,大伙漫漫研究改进啊,明天开始要看其他书了,没办法公司要求,Flash只是爱好而已了。有什么问题一起讨论的请联系我
QQ:190868487;
msn:tianmazhixing@hotmail.com
email:tianmazhixing@ hotmail.com
LeeFJ
3/6/2005 5:42:17 PM