- 浏览: 22591 次
- 性别:
- 来自: 重庆
最新评论
-
三尺寒冰:
是新建flex项目吗?
为什么我的提示:
[SWF] ting ...
Flex简单的Mp3播放器。 -
vinkeychen:
菜鸟飘过,向楼主学习了。
Flex版Mp3播放器----大部分功能版二,后台 -
mercyblitz:
先学XMLHttpRequest
NO.1 AJAX简单实例(用户名校验) struts+AJAX(JQuery) -
66573334:
谢谢楼主啊,最后那个forward是不是指向本页?我刚开始学, ...
NO.1 AJAX简单实例(用户名校验) struts+AJAX(JQuery) -
wptc:
hlw579 写道似乎LZ用的不是struts2呀
是否应该 ...
NO.1 AJAX简单实例(用户名校验) struts+AJAX(JQuery)
转至:http://blog.dreamhui.net/archives/64
今天学习Cairngorm,找了份教程,写了个Demo,以记录并分享学习过程。
Cairngorm的各个部分:
- ModelLocator:在一个地方存储程序中所有的值对象(ValueObjects,数据)并共享变量。它与HTTP Session对象相类似,不过它存储在Flex客户端,而不是存储在一个中间层程序服务器的服务器端。
- View(视图):一个或多个Flex组件(Button,panel,combo Box,Tile等等)绑定到一起形成的一个特定的个体,使用ModelLocator中的数据并且针对用户的交互动作(如点击,鼠标滑过,拖拽等)产生自定义的CairngormEvents。
- FrontController(前端控制器):接受CairngormEvents并且将它们映射到CairngormCommands。
- Command(命令):处理业务逻辑,调用CairngormDelegates或其他的Commands,以及更新ModelLocator中存储的值对象和变量。
- Delegate(委托):由一个Command创建,它将远程过程实例化并且将结果返回给Command。
- Service(服务):定义链接到远程数据库的远程过程调用(HTTP,Web Services等)。
Cairngorm的工作流程大体是这样:
客户端界面由View组成的。View使用Flex的binding(绑定)来显示ModelLocator中包含的数据。View根据诸如鼠标点击,按钮按下以及拖拽之类的用户动作产生Event。这些Event被FrontController“广播”并“监听”,FrontController会将Event映射到Command。Command包括业务逻辑,创建所需的Delegate,处理Delegate的响应,以及更新存储在ModelLocator中的数据。由于View是绑定到ModelLocator中的数据上的,所以当ModelLocator中的数据改变的时候View也会自动更新。Delegate调用Service并且将结果提交给Command,这一步是可选的,但是推荐这么做。Service调用远程数据然后将结果提交给Delegate。
Delegate的最简单的形式就是一个中间人的角色。如果一个Command需要调用webservice来获得一些数据,它将创建一个Delegate来完成这个调用。一个Command创建一个Delegate,Delegate调用一个指定的dataService,Service返回结果给Delegate,Delegate返回结果给Command。
Delegate并不是100%必需的,但是当涉及测试&程序环境的时候它们很有帮助。相对于在Command代码中使用查找替换改变所有的引用来测试,将一个Delegate重映射到一个测试Service更为简单。
下面说我的Demo:完成用户登录在后台进行验证合法性,并反馈给前台。
工具及环境介绍:详见我的上篇文章,BlazeDS实现Flex和Java通信的Demo
版本说明:
Flex:Flex 4;
ActionScript:ActionScript 3;
Java JDK:jdk1.6.0_20
Cairngorm,我用的是版本2.2,好像Cairngorm 3已经发布了,但是官网没提供下载。下载cairngorm2_2_1-bin.zip,我们要用的已经打包好的资源文件Cairngorm.swc,将其拷贝到Flex工程的libs目录下面即可。
- 后台Java服务端项目CairngormDemo工程组成:
- 前台Flex工程CairngormDemo工程组成:
相应代码:
UserVO.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package net.dreamhui.java; public class UserVO { public String userName; public String passWord; //和ActionScript对应得构造方法 public UserVO() { } //getters & setters public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } } |
LoginUser.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package net.dreamhui.java; public class LoginUser { public UserVO currentUser; private String uName; private String pWord; //Flex端要调用的服务 public UserVO login(UserVO par_user) { //UserVO par_user2 = UserVO(par_user); uName = par_user.userName; pWord = par_user.passWord; if(uName.equalsIgnoreCase("wwh")&&pWord.equalsIgnoreCase("wwh")) { return par_user; //return "欢迎用户:"+uName; } else{ return null; //return "用户名或密码错误,请重新输入"; } } } |
配置文件(要添加的内容):
remoting-config.xml
1 2 3 4 5 |
<destination id="loginUser"> <properties> <source>net.dreamhui.java.LoginUser</source> </properties> </destination> |
按照 ValueObjects模型(UserVO.as)——>模型定位(UserModelLocator.as)——>视图(loginView.mxml及主应用视图CairngormDemo.mxml)——>事件(LoginEvent.as)——>前端控制器(LoginController.as)——>Command(LoginCommand.as)——>委派代理(LoginDelegate.as)——>服务定位(LoginServiceLocator.mxml)依次的相应代码如下(因为文件中注释较多,不多写注解):
UserVO.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
package net.dreamhui.vo { /** * 我看的教程里面讲绑定ValueObject到远程Java类的方法是这样的, * public static var registered:Boolean = this.registerClass(); * 可能又是版本问题,在我这儿是通不过的,我到网上找到了如下的解决方法: * [RemoteClass(alias="net.dreamhui.java.UserVO")], * 估计是我看的教程版本太低了,呵呵 * */ import com.adobe.cairngorm.vo.ValueObject; [Bindable] [RemoteClass(alias="net.dreamhui.java.UserVO")] public class UserVO implements ValueObject { private var _userName:String; private var _passWord:String; /** * 为了实现远程Class之间的绑定,构造方法必须形式上完全一致, * 包括参数的个数和类型,否则会出现异常。 * */ public function UserVO() { } //getters & setters public function get userName():String { return _userName; } public function set userName(value:String):void { _userName = value; } public function get passWord():String { return _passWord; } public function set passWord(value:String):void { _passWord = value; } } } |
UserModelLocator.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package net.dreamhui.model { import com.adobe.cairngorm.CairngormError; import com.adobe.cairngorm.CairngormMessageCodes; import com.adobe.cairngorm.model.ModelLocator; import flash.events.Event; import net.dreamhui.vo.UserVO; //绑定全局View数据 [Bindable] public class UserModelLocator implements ModelLocator { private var _currentUser:UserVO; public static const LOGIN_YES:String = "loginYes"; private static var instance:UserModelLocator; //单例模式 public function UserModelLocator() { if(instance == !null) { throw new CairngormError(CairngormMessageCodes.SINGLETON_EXCEPTION,"UserModelLocator"); } instance = this; } public static function getInstance():UserModelLocator { if(instance == null) { instance = new UserModelLocator(); } return instance; } public function get currentUser():UserVO { return _currentUser; } /** * 此赋值操作绑定loginYes事件,当输入数据合法时候,将改变当前的登录状态 * **/ [Bindable("loginYes")] public function set currentUser(value:UserVO):void { _currentUser = value; dispatchEvent(new Event(UserModelLocator.LOGIN_YES)); } } } |
loginView.mxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
<?xml version="1.0" encoding="utf-8"?> <s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" title="请登陆" currentState="initState" creationComplete="lvcreationComplete(event)"> <!--~~~~~~~~~~~~~~~~~~~~~~Script~~~~~~~~~~~~~~~~~~~~~~--> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.events.FlexEvent; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.validators.Validator; import mx.events.ValidationResultEvent; import mx.core.UIComponent; import net.dreamhui.control.LoginEvent; import net.dreamhui.model.UserModelLocator; import net.dreamhui.vo.UserVO; /***************************************************/ private var validObjs:Array; /***************************************************/ protected function lvcreationComplete(event:FlexEvent):void { validObjs = [unSV,pwSV]; } protected function submit(event:MouseEvent):void { var validatorResults:Array; validatorResults = Validator.validateAll(validObjs); if(validatorResults.length == 0) { var user:UserVO = new UserVO(); user.userName = uName.text; user.passWord = pWord.text; var lgEvent:LoginEvent = new LoginEvent(LoginEvent.LOGIN_USER); lgEvent.data = user; lgEvent.dispatch(); //派发事件 /***LoginEvent继承自com.adobe.cairngorm.control.CairngormEvent, * 用父类的方法dispatch派发事件; * 其实CairngormEvent继承自flash.events.Event * dispatch是CairngormEventDispatcher类封装IEventDispatcher * 的dispatchEvent()方法 * **/ } else { //定义校验出错事件 var vEvent:ValidationResultEvent; //取出第一个出错事件 vEvent = validatorResults[0] as ValidationResultEvent; //将光标定位到第一个出错的组件上 (vEvent.target.source as UIComponent).setFocus(); } } ]]> </fx:Script> <!--~~~~~~~~~~~~~~~~~~~~~~states~~~~~~~~~~~~~~~~~~~~~~--> <s:states> <s:State name="initState"/> <s:State name="loginState"/> </s:states> <!--~~~~~~~~~~~~~~~~~~~~~~Declarations~~~~~~~~~~~~~~~~~~~~~~--> <fx:Declarations> <!--定义用户名和密码的输入校验类--> <mx:StringValidator id="unSV" source="{uName}" property="text" required="true" maxLength="10" tooLongError="用户名最长为10位" requiredFieldError="请填写用户名" /> <mx:StringValidator id="pwSV" source="{pWord}" property="text" required="true" maxLength="10" tooLongError="密码最长为10位" requiredFieldError="请填写密码" /> </fx:Declarations> <!--~~~~~~~~~~~~~~~~~~~~~~UI Components~~~~~~~~~~~~~~~~~~~~~~--> <mx:Form includeIn="initState"> <mx:FormItem label="用户名" > <s:TextInput id="uName" /> </mx:FormItem> <mx:FormItem label="密 码" > <s:TextInput id="pWord" displayAsPassword="true" /> </mx:FormItem> <mx:FormItem> <s:Button id="submitBtn" click="submit(event)" label="登陆" right="0" /> </mx:FormItem> </mx:Form> <s:HGroup includeIn="loginState" top="20" left="10" > <s:Label text="欢迎尊贵的用户:"/> <s:Label id="cuName" text="{UserModelLocator.getInstance().currentUser.userName}" /> </s:HGroup> </s:Panel> |
CairngormDemo.mxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:business="net.dreamhui.business.*" xmlns:control="net.dreamhui.control.*" xmlns:view="net.dreamhui.view.*" creationComplete="creationComplete()"> <!--~~~~~~~~~~~~~~~~~~~~~~Script~~~~~~~~~~~~~~~~~~~~~~--> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.events.FlexEvent; import net.dreamhui.model.UserModelLocator; /***************************************************/ protected function creationComplete():void { UserModelLocator.getInstance().addEventListener(UserModelLocator.LOGIN_YES,switchState); } protected function switchState(event:Event):void { lgView.currentState = "loginState"; } ]]> </fx:Script> <!--~~~~~~~~~~~~~~~~~~~~~~Declarations~~~~~~~~~~~~~~~~~~~~~~--> <fx:Declarations> <!--初始化服务,里面含有Command注册 和 远程过程调用的信息--> <business:LoginServiceLocator id="lgService" /> <control:LoginController id="loginContr" /> <!--<commands:LoginCommand id="lCommand" />--> <!--<model:UserModelLocator id="uLocator" />--> </fx:Declarations> <!--~~~~~~~~~~~~~~~~~~~~~~UI Components~~~~~~~~~~~~~~~~~~~~~~--> <view:loginView id="lgView" top="10" horizontalCenter="0" width="30%" height="30%" fontSize="20"/> </s:Application> |
LoginEvent.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package net.dreamhui.control { import com.adobe.cairngorm.control.CairngormEvent; import net.dreamhui.vo.UserVO; public class LoginEvent extends CairngormEvent { //定义事件类型常量 public static const LOGIN_USER:String = "loginUser"; public function LoginEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) { super(type, bubbles, cancelable); } } } |
LoginController.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package net.dreamhui.control { import com.adobe.cairngorm.control.FrontController; import net.dreamhui.commands.LoginCommand; public class LoginController extends FrontController { public function LoginController() { initCommands(); } /**注册Command*/ private function initCommands():void { addCommand(LoginEvent.LOGIN_USER,LoginCommand); } } } |
LoginCommand.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
package net.dreamhui.commands { import com.adobe.cairngorm.commands.ICommand; import com.adobe.cairngorm.control.CairngormEvent; import mx.controls.Alert; import mx.rpc.IResponder; import net.dreamhui.business.LoginDelegate; import net.dreamhui.control.LoginEvent; import net.dreamhui.model.UserModelLocator; import net.dreamhui.vo.UserVO; public class LoginCommand implements ICommand,IResponder { public function LoginCommand() { } public function execute(event:CairngormEvent):void { //Alert.show("execute"); var lgEvent:LoginEvent = LoginEvent(event); var user:UserVO = lgEvent.data; var delegate:LoginDelegate = new LoginDelegate(this); delegate.login(user); } /** * Command实现IResponder接口的两个方法result和fault; * 我看了两份教程,前者是这样的: * 1、Command实现com.adobe.cairngorm.business.Responder接口的onResult和onFault两个方法; * 2、Command实现mx.rpc.IResponder接口的两个方法result和fault; * 因为我在LoginDelegate没能实现将内部变量设置为com.adobe.cairngorm.business.Responder, * 所以,我采用了第二种方案,通过。 * */ public function result(event:Object):void { var cuUser:UserVO = event.result as UserVO; if(cuUser) { UserModelLocator.getInstance().currentUser = cuUser; //此赋值操作绑定loginYes事件,当输入数据合法时候,将改变当前的登录状态 //Alert.show(cuUser.userName); } else { Alert.show("用户名或密码错误,请重新填写"); } } public function fault(event:Object):void { trace("服务调用错误"+event.toString()); } } } |
LoginDelegate.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package net.dreamhui.business { import com.adobe.cairngorm.business.ServiceLocator; import mx.rpc.IResponder; import net.dreamhui.vo.UserVO; public class LoginDelegate { public var responder:IResponder; public var service:Object; public function LoginDelegate(responder:IResponder) { this.service = ServiceLocator.getInstance().getRemoteObject("loginService"); //this.service = ServiceLocator.getInstance().getService("loginService"); //我看的教程里采用下面的做法,程序运行没有问题,只是会有warning this.responder = responder; } public function login(user:UserVO):void { var call:Object = service.login(user); //call.resultHandler = Delegate.create(responder, responder.onResult); //call.faultHandler = Delegate.create(responder, responder.onFault); //注释掉的部分是教程里的写法,可能是版本的问题,在我这儿是不对的 call.addResponder(responder); } } } |
LoginServiceLocator.mxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?xml version="1.0" encoding="utf-8"?> <cairngorm:ServiceLocator xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:cairngorm="http://www.adobe.com/2006/cairngorm"> <!--~~~~~~~~~~~~~~~~~~~~~~D |
相关推荐
《Flex + Cairngorm + BlazeDS 整合详解》 Flex、Cairngorm 和 BlazeDS 是构建富互联网应用(RIA)的三大核心技术。Flex 提供了强大的用户界面组件和图形库,Cairngorm 是一个轻量级的MVC框架,而BlazeDS则是用于...
使用flex 4.5 + Spring 3.0 + Hibernate 3.3 + Cairngorm 2.2.1 + BlazeDS 3.3.0 + Spring BlazeDS Integration 1.0.3整合出的一个登录的小demo·
一个 Flex+J2EE实例(cairngorm+blazeDS+hibernate+spring) 本实例为一个 flex 与 java通信项目。前端采用cairngorm框架,后台 采用hibernate+spring 每个部署 步骤,附详细 图文解释。旨在 采用 一种快速开发 ...
2. **BlazeDS与Flex通信**:BlazeDS提供了一种简单的方法来连接Flex前端与Java后端,使得数据交换变得更加容易。它可以支持AMF (Action Message Format) 格式的序列化,从而提高数据传输效率。 3. **Hibernate与...
### Flex+J2EE 实例(Cairngorm+BlazeDS+Hibernate+Spring)Part 2 #### 一、概述 本文档介绍了一个利用Flex前端技术与J2EE后端技术结合的具体实现案例,主要涉及到的技术栈包括:Cairngorm、BlazeDS、Hibernate ...
### Flex+J2EE 实例(cairngorm+blazeDS+hibernate+spring)Part 4 本文档是关于如何利用Flex与Java EE技术栈构建一个完整的富互联网应用(RIA)项目的系列文章之一。该部分主要介绍了如何集成Cairngorm框架到项目...
### Flex+J2EE 实例(Cairngorm+BlazeDS+Hibernate+Spring)Part 3 #### 概述 本章节主要介绍了如何在已有的Flex+J2EE架构项目中集成Spring框架和Hibernate持久层框架。通过这种方式,我们可以更好地实现业务逻辑...
结合Cairngorm和BlazeDS,开发者可以在Flex前端实现高效的MVC架构,同时利用BlazeDS的Remoting功能轻松与Java后端进行数据交换。在实际开发中,Cairngorm的命令模式可以很好地与BlazeDS的远程调用相结合,使得业务...
### Flex教程核心知识点详解 ...在后续章节中,本教程将详细介绍如何将Flex与Java技术整合,特别是如何使用BlazeDS、Spring、iBatis、Cairngorm 和 pureMVC 这些框架来进行集成开发,从而实现高效、稳定的RIA应用开发。
Flex Cairngorm Java实例是一个基于Adobe Flex的项目,它整合了Cairngorm框架和Java后端服务,用于构建高效且可扩展的 Rich Internet Applications (RIA)。Flex是一种开源的、基于ActionScript的开发工具,用于创建...
标题中的“flex+spring +BlazeDs+spring+ibatis+Cairngorm整合教程”涉及到的是一个基于Adobe Flex前端、Spring后端服务、BlazeDS作为数据通信中间件、Spring框架进行服务管理以及Ibatis作为持久层操作的典型企业级...
标题 "Flex+Cairngorm+J2EE" 暗示了这是一个关于使用Adobe Flex作为前端开发工具,Cairngorm作为MVC框架,并结合Java EE(J2EE)作为后端服务的项目。Flex是一种基于ActionScript和Flash Player的开源框架,用于构建...
Flex+BlazeDS+SpringBlazeDSIntegration+Spring (>=2.5.6)+iBatis+Cairngorm 与第一种架构类似,但使用了 SpringBlazeDSIntegration 来简化 BlazeDS 和 Spring 之间的集成。 ##### 3. Flex+BlazeDS+Spring ()+...
通过使用AMF(Action Message Format)协议,BlazeDs能够实现低延迟、高效率的数据传输,使得Flex应用能够与Java服务进行实时通信。 Spring框架是Java领域中广泛使用的轻量级应用框架,它简化了Java企业级应用的...
【标题】:“一年前整合flex3+cairngorm+spring+hibernate” 这篇文章主要讨论了一年前的一个项目集成,其中涉及到了四个关键的技术组件:Flex3、Cairngorm、Spring和Hibernate。这些技术都是在开发富互联网应用...
这个"Cairngorm+Java EE"的实例展示了如何在前后端之间建立高效的通信,同时利用MVC模式来组织和管理复杂的业务逻辑。对于希望学习跨平台、多层架构开发的开发者来说,这是一个很好的实践案例。