flex有多种与后台交互的方法,(/Files/xingluzhe/Flex与Web服务的交互.ppt)这里有个不错的介绍。我之前用的是python的django做后台,有些许的收获,先奉献出来与大家分享。
首先是Django后台的搭建,这个在我的一篇博文中有介绍,这里我便不再赘述。
其次是flex前台与python后台的交互。
1. 新建一.xml配置文件(放在与mxml文件同目录下)。配置文件中的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
<services>
<service id="webblogService" class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="webblogapp">
<channels>
<channel ref="webblogChannel"/>
</channels>
<properties>
<source>*</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="webblogChannel" class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://localhost:8080/webblog/gateway/" class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>
2. 在主mxml文件中添加如下语句:
<mx:RemoteObject
id="djangoService"
destination="webblogapp" //注意这里的destination是我用python manage.py startapp webblogapp生成的文件夹,没试过用的名称行不行
showBusyCursor="true">
</mx:RemoteObject>
另外需要注意的是,我的整个工程都只有用到一个RemoteObject。在别的component中应用主页面中定义的RemoteObject主要使用Application.application.djangoService;就行了。
3. 与后台交互
private var token: AsyncToken;//定义一个token
token = remoteObj.echo(remotefunc, arg); //调用后台数据库提供的接口echo
token.addResponder(new AsyncResponder(onResultHandle,faultHandler)); //为token添加responder
然后在onResultHandle中做你对后台返回的结果的处理
private function onResultHandle(re:ResultEvent, token:Object=null):void
{
resultHandle(re); //这里做相应的处理
}
private function faultHandler(fe:FaultEvent, token:Object=null):void
{
trace(fe.fault.faultDetail); //这个函数可以原封照抄,因为当你的后台出错时,它会在flex console窗口中打印出错的位置和原因
}
4. 从上面的介绍可以看出,每次调用后台的一个方法都会重复执行大致相同的操作,除了调用的方法不一样。所以为了达到代码的重用,我写了个简单类来负责与后台的通信:/Files/xingluzhe/KCommunication.txt(这个类的代码)
/////////////////////////////////////////////////////////
// FileName: KCommunication.as
// creator : David(蔡海滨)
// Date : 2009-8-20
// Commment: 主要用于负责前段与后台的通信
/////////////////////////////////////////////////////////
package com.wps
{
import flash.events.EventDispatcher;
import mx.core.Application;
import mx.rpc.AsyncResponder;
import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
public class KCommunication extends EventDispatcher
{
/**
* @brief 类构造函数
*
*/
public function KCommunication()
{
}
/**
* 设置Token和相应的处理函数
* @param remotefunc 想要调用的远程函数
* @param arg 要给远程函数传递的参数(都放进一个字符串中)
* @param func 与后台交互完后的响应事件
*
*/
public function setTokenAndHandle(remotefunc:String, arg:String, func:Function):void
{
resultHandle = func;
token = remoteObj.echo(remotefunc, arg); //注意,这里我让后台的接口统一为echo,传递的参数都是一个字符串
token.addResponder(new AsyncResponder(onResultHandle,faultHandler));
}
/**
* @brief 与后台交互完后的响应事件
* @param re
* @param token
*
*/
private function onResultHandle(re:ResultEvent, token:Object=null):void
{
resultHandle(re);//注意,这里的这个处理函数,可以在类外提供
}
private function faultHandler(fe:FaultEvent, token:Object=null):void
{
trace(fe.fault.faultDetail);
}
private var remoteObj: RemoteObject = Application.application.djangoService;;
private var resultHandle:Function = null;
private var token: AsyncToken;
}
}
举个例子吧:
比如要实现登陆的功能
1. import com.KCommunication;
2. private var comm:KCommunication = new KCommunication();
3. private function onConfirm(evt:Event):void
{
//getUser是我在后台定义好的接口,用于返回用户的用户名,和密码,这里validateUserInfo就是对返回结果的处理
comm.setTokenAndHandle("getUser", username.text, validateUserInfo);
}
4. private function validateUserInfo(re:ResultEvent):void
{
if(re.result.length > 0)
{
_name = re.result[0].username.toString();
_pw = re.result[0].password.toString();
_nick = re.result[0].nickname.toString();
if (_name === username.text && _pw === password.text)
{
kgv._username = _name;
kgv._password = _pw;
kgv._nickname = _nick;
username.text = "";
password.text = "";
}
else
{
errorMessage();
}
}
else
{
errorMessage();
}
}
这样便可以实现通信。
现在就剩下最后一个疑问了:后台统一接口的实现^_^
def getUser(name):
#return the user
user = Users.objects.filter(username = name[0])
return user
//这是我定义的后台的统一的接口
def echo(request, requestFunc, requestArg)://第一个参数是必须的,调用时不用指定,requestFunc是提供给前台的方法,requestArg是字符串的参数,
以|->!!!!<-|分隔
#seperate the arguments out at first
arg = requestArg.split('|->!!!!<-|') //分割出所需的参数(这里所有的参数都是字符串,可以安装需要将字符串转换成所需的参数的类型
return FuncMap[requestFunc](arg) //调用函数,这里FuncMap是一个Map容器
FuncMap定义如下:
FuncMap = {"getUser": getUser, #when add an interface, register here
}
当添加新的接口时,只需在这里注册即可。
----David Cai 2009-08-31 晚于金山公司