flex与python后台的交互(原创)

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 晚于金山公司
原文地址:https://www.cnblogs.com/xingluzhe/p/1557524.html