- 浏览: 2674693 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
我素熊猫:
66666666666666
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderL -
jonyzhou94:
1987_ming 写道1987_ming 写道System. ...
CXF框架入门实例 -
davidforit:
你那个“2004年Nutch创始人Doug Cutting基于 ...
《Hadoop基础教程》之初识Hadoop -
masuweng:
我的就是这么弄得,到了页面还是那个格式的 。
JSONObject转换JSON--将Date转换为指定格式 -
masuweng:
∑
JSONObject转换JSON--将Date转换为指定格式
- 关键技术简介
Blaseds是一款开源免费的插件,主要作用是实现flex调用java代码;
puremvc是一款针对flex的开源免费的mvc框架,主要作用是实现Flex代码解耦;
Hibernate框架是java持久层经典框架,帮助程序员更方便安全地访问数据库;
spring是java非常流行的框架,主要作用是管理java对象,其强大的低耦合机制能够与许多框架进行无缝整合(比如前面提到的Blaseds和Hibernate)。
- 实现机制
本实例实现用户管理的增删改查操作,前端完全使用flash展示,后台使用java服务器与mysql数据库交互。
Flex端使用puremvc进行解耦,Mediator监听页面事件和页面数据存取,Command处理页面复杂操作并调用Proxy方法,Proxy实现Java代码调用(使用RemoteObject的形式)。
Java端分为持久层(Dao层)和业务层(Service层),Flex调用的是Service层代码,使用spring mvc捕获flex的调用请求,Service再调用Dao层进行增删改查操作,最后将结果返回给Flex。
- 效果展示
①主页面
②下一页
③添加页面
④编辑页面
⑤详细页面
⑥删除操作
- Java端实现
Java端主要使用spring和Hibernate实现Dao层和Service层代码,具体spring和Hibernate配置网上有很多,在这就不赘述了。
关于Blaseds与spring整合的例子也很多,大家可以到我的博文中参考一下:http://blessht.iteye.com/admin/blogs/1131148。
①下面看Flex远程调用Service的接口定义:
public interface LoginService { //新增 public void insertLoginInfo(Logininfo login); //删除 public void deleteLoginInfo(int id); //修改 public void updateLoginInfo(Logininfo login); //详细 public LoginInfoDto getLoginInfo(int id); //分页查询用户信息(用于显示到表格中) public List<LoginTableDto> findLoginInfo(int pageNo,int pageSize); //获取用户信息表的总数据 public long getLoginInfoTotalCounts(); //进入编辑页面时调用的方法 public Logininfo getLogin(int id); //暂时无用 public List<FlexComboBoxDto> getSexList(); }
②看比较关键的web.xml配置:
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>ssh2model</display-name> <description>ssh2model Application</description> <!-- spring mvc --> <servlet> <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping> <!-- 著名 Character Encoding filter --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <!-- spring IOC --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:com/bless/base/config/spring/springApplicationContext.xml, classpath:com/bless/*/config/spring/spring-*-*.xml </param-value> </context-param> <!-- blaseds监听器:用于获取服务器内置对象(request,application等) --> <listener> <listener-class>flex.messaging.HttpFlexSession</listener-class> </listener> <!--Spring ApplicationContext 载入 ,必须--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring 刷新Introspector防止内存泄露 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!-- session超时定义,单位为分钟 --> <session-config> <session-timeout>20</session-timeout> </session-config> <!--添加远程支持,用于远程数据服务--> <servlet> <display-name>RDSDispatchServlet</display-name> <servlet-name>RDSDispatchServlet</servlet-name> <servlet-class>flex.rds.server.servlet.FrontEndServlet</servlet-class> <init-param> <param-name>useAppserverSecurity</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>messageBrokerId</param-name> <param-value>_messageBroker</param-value> </init-param> <load-on-startup>10</load-on-startup> </servlet> <servlet-mapping id="RDS_DISPATCH_MAPPING"> <servlet-name>RDSDispatchServlet</servlet-name> <url-pattern>/CFIDE/main/ide.cfm</url-pattern> </servlet-mapping> </web-app>
③最后看service的IOC配置文件:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:flex="http://www.springframework.org/schema/flex" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd"> <!-- 为了把请求路由给 MessageBroker,添加以下 tag--> <flex:message-broker /> <bean id="loginServiceBean" class="com.bless.logininfo.service.impl.LoginServiceImpl"> <!-- 指定当前bean被远程调用 --> <flex:remoting-destination /> <property name="loginDao" ref="loginInfoDaoBean"></property> </bean> </beans>
④最后将Java项目部署到服务器上即可。
- Flex端实现
Flex端因为使用了puremvc,关于puremvc我在这不做过多介绍,因为我也是新手,可能很多东西写的都是错误,在以后对它有更深认识之后我会与大家分享使用经验。
整个项目的包结构如下图所示:
上图*.mxml就是flex的页面展示了,功能与jsp和html相似,也是由页面标签、事件等组成。mxml可以像纯jsp一样,将所有代码写在里面,但是这样会造成项目难以维护,所以为了尽量减少耦合度,我在mxml中基本没有写ActionScript代码,而是交给puremvc的Mediator处理。
下面以index.mxml为例,我在index.mxml中定义了一些变量,方便Mediator赋值,也就是说mxml不做逻辑操作,只是为了展示数据:
<?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" minWidth="955" minHeight="600" creationComplete="facade.init_index(this)"> <!--整体布局--> <s:layout> <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/> </s:layout> <!--ActionScript代码块--> <fx:Script> <![CDATA[ import mx.collections.ArrayCollection; //定义puremvc核心Facade private var facade:ApplicatioinFacade = ApplicatioinFacade.getInstance(); //总条数 [Bindable] public var totals:int = 0; //当前页数 [Bindable] public var pageNo:int = 1; //一页显示条数 [Bindable] public var pageSize:int = 6; //表格中的结果集 [Bindable] public var logintablelist:ArrayCollection; //被选中的值id public var selectId:int = 0; protected function table_loginInfo_clickHandler(event:MouseEvent):void { if(table_loginInfo.selectedItem != null){ selectId = table_loginInfo.selectedItem.id; } } ]]> </fx:Script> <!-- <s:HGroup width="70%" height="30" verticalAlign="middle" horizontalAlign="center"> <s:Label text="用户名:"/> <s:TextInput id="txt_loginCode"/> <s:Label text="姓名:"/> <s:TextInput id="txt_name"/> <s:Label text="性别:"/> <s:ComboBox width="100" id="txt_sex"/> <s:Button label="检索" id="btn_search"/> <s:Button label="重置" id="btn_reset"/> </s:HGroup> --> <!--操作区--> <s:HGroup width="70%" height="30" verticalAlign="middle"> <mx:LinkButton label="刷新" id="refresh"/> <mx:LinkButton label="添加" id="insert"/> <mx:LinkButton label="编辑" enabled="{table_loginInfo.selectedIndex==-1?false:true}" id="edit"/> <mx:LinkButton label="详情" enabled="{table_loginInfo.selectedIndex==-1?false:true}" id="detail"/> <mx:LinkButton label="删除" enabled="{table_loginInfo.selectedIndex==-1?false:true}" id="link_delete"/> </s:HGroup> <!--表格区--> <mx:DataGrid width="70%" id="table_loginInfo" dataProvider="{logintablelist}" click="table_loginInfo_clickHandler(event)"> <mx:columns> <mx:DataGridColumn headerText="用户名" dataField="loginCode"/> <mx:DataGridColumn headerText="姓名" dataField="name"/> <mx:DataGridColumn headerText="性别" dataField="sex"/> <mx:DataGridColumn headerText="联系电话" dataField="phone"/> <mx:DataGridColumn headerText="电子邮箱" dataField="email"/> </mx:columns> </mx:DataGrid> <s:HGroup width="70%" height="30" verticalAlign="middle"> <s:Label text="总共"/> <s:Label text="{totals}"/> <s:Label text="条数据"/> <s:Label text=" 第"/> <s:NumericStepper id="curPage" minimum="1" maximum="{(totals%pageSize)!=0?((uint)(totals/pageSize)+1):(totals/pageSize)}" value="{pageNo}"/> <s:Label text="页"/> <mx:LinkButton label="上一页" id="befor_page" enabled="{(pageNo==1)?false:true}"/> <mx:LinkButton label="下一页" id="after_page" enabled="{(totals>((pageNo-1)*pageSize+(logintablelist.length)))?true:false}"/> </s:HGroup> </s:Application>
大家可以看到index.mxml中本应有很多事件的,不然怎么能实现增删改查操作,其实上面所有事件都写到了这里:
public class IndexMediator extends Mediator { public static const NAME:String = "IndexMediator"; public function IndexMediator(viewComponent:Object=null) { super(IndexMediator.NAME, viewComponent); var indexApp:index = viewComponent as index; //刷新 indexApp.refresh.addEventListener(MouseEvent.CLICK,function click():void{ sendNotification(LoadLoginCommand.NAME,indexApp); }); //上下页选择事件 indexApp.curPage.addEventListener(Event.CHANGE,function change():void{ loadTable(indexApp.curPage.value); }); //上一页事件 indexApp.befor_page.addEventListener(MouseEvent.CLICK,function click():void{ loadTable(indexApp.pageNo - 1); }); //下一页事件 indexApp.after_page.addEventListener(MouseEvent.CLICK,function click():void{ loadTable(indexApp.pageNo + 1); }); //打开添加操作事件 indexApp.insert.addEventListener(MouseEvent.CLICK,function click():void{ sendNotification(LoginAddOpenCommand.NAME,indexApp); }); //打开编辑操作事件 indexApp.edit.addEventListener(MouseEvent.CLICK,function click():void{ sendNotification(LoginEditCommand.NAME,indexApp); }); //打开详细操作事件 indexApp.detail.addEventListener(MouseEvent.CLICK,function click():void{ sendNotification(LoginDetailCommand.NAME,indexApp); }); //执行删除操作事件 indexApp.link_delete.addEventListener(MouseEvent.CLICK,function click():void{ Alert.show("你确定该条数据吗?","删除提示",Alert.OK|Alert.NO,indexApp,function alert(e:CloseEvent):void{ //如果点击Cancel则不执行任何操作,否则执行删除操作 if(e.detail == Alert.OK){ sendNotification(LoginDeleteCommand.NAME,indexApp); } }); }); } public function get indexApp():index{ return viewComponent as index; } //列举监听事件 override public function listNotificationInterests() : Array { return [ SearchLoginProxy.findLoginInfo, SearchLoginProxy.getLoginInfoTotalCounts, SearchLoginProxy.deleteLoginInfo ]; } //处理监听事件 override public function handleNotification( note : INotification ) : void{ switch (note.getName()){ case SearchLoginProxy.findLoginInfo: indexApp.logintablelist = note.getBody() as ArrayCollection; break; case SearchLoginProxy.getLoginInfoTotalCounts: indexApp.totals = note.getBody() as int; break; case SearchLoginProxy.deleteLoginInfo: sendNotification(LoadLoginCommand.NAME,indexApp); break; default: break; } } private function loadTable(pageNo:int):void{ indexApp.pageNo = pageNo; sendNotification(LoadLoginCommand.NAME,indexApp); } }
那么上面IndexMediator类的构造方法就是关键了,构造方法必须传入index.mxml的实现对象,其实实现步骤很简单:
①index.mxml页面启动是触发creationComplete事件,该事件调用facade的init_index方法并且将当前对象作为参数传过去
②在facade类中注册一个名叫InitCommand的类,通过sendNotification向InitCommand发送通知
public class ApplicatioinFacade extends Facade { public static const INIT:String = "init"; //得到ApplicationFacade单例的工厂方法 public static function getInstance() : ApplicatioinFacade { if ( instance == null ) instance = new ApplicatioinFacade( ); return instance as ApplicatioinFacade; } //注册Command,建立Command与Notification之间的映射 override protected function initializeController( ) : void{ super.initializeController(); registerCommand(InitCommand.NAME,InitCommand); } public function init_index(index_:index):void{ sendNotification(InitCommand.NAME,index_); } }
③InitCommand接到通知后运行execute方法,execute方式内完成MVC的注册(当然也包括IndexMediator的注册)。其实到这IndexMediator就已经开始监听index.mxml的事件了。
public class InitCommand extends SimpleCommand { public static const NAME:String = "InitCommand"; override public function execute(notification:INotification):void{ var index_:index = notification.getBody() as index; //向facade中注册mvc facade.registerMediator(new IndexMediator(index_)); facade.registerProxy(new SearchLoginProxy()); //注册command facade.registerCommand(LoadLoginCommand.NAME,LoadLoginCommand); facade.registerCommand(LoginDetailCommand.NAME,LoginDetailCommand); facade.registerCommand(LoginDeleteCommand.NAME,LoginDeleteCommand); facade.registerCommand(LoginEditCommand.NAME,LoginEditCommand); facade.registerCommand(LoginAddReturnCommand.NAME,LoginAddReturnCommand); facade.registerCommand(LoginEditSubmitCommand.NAME,LoginEditSubmitCommand); facade.registerCommand(LoginAddOpenCommand.NAME,LoginAddOpenCommand); facade.registerCommand(LoginEditCloseCommand.NAME,LoginEditCloseCommand); //发送通知初始化页面 sendNotification(LoadLoginCommand.NAME,index_); } }
- puremvc运行流程简介
以打开新增页面为例,我简单介绍一下puremvc的调用原理:
①首先IndexMediator负责index.mxml的事件监听,当用户点击“新增”链接时向LoginAddOpenCommand发送通知,并且将index.mxml对象传给该command使用:
//打开添加操作事件 indexApp.insert.addEventListener(MouseEvent.CLICK,function click():void{ sendNotification(LoginAddOpenCommand.NAME,indexApp); });
②发送通知后,facade调用LoginAddOpenCommand的execute方法,该方法创建一个insert.mxml对象,同时创建LoginAddMediator(该Mediator用于监听insert.mxml页面),并且以模式弹出窗的形式显示在界面中,这时需要初始化“性别”下拉列表,所以必须调用SearchLoginProxy的getSexList方法:
public class LoginAddOpenCommand extends SimpleCommand { public static const NAME:String = "LoginAddOpenCommand"; override public function execute(notification:INotification):void{ //新建添加窗口 var i:insert = new insert(); PopUpManager.addPopUp(i,notification.getBody() as index,true); PopUpManager.centerPopUp(i); facade.registerMediator(new LoginAddMediator(i)); (facade.retrieveProxy(SearchLoginProxy.NAME) as SearchLoginProxy).getSexList(); } }
③SearchLoginProxy的getSexList方法主要封装“性别”下拉列表的数据,封装完成后会发出一个通知
//查询性别列表 public static const getSexList:String ="getSexList"; public function getSexList():void{ var list:ArrayCollection = new ArrayCollection([ {label:"保密",data:0}, {label:"男",data:1}, {label:"女",data:2} ]); sendNotification(SearchLoginProxy.getSexList,list); }
④在LoginAddMediator中会注册并收听到Proxy发过来的通知,最后通过LoginAddMediator将值赋给insert.mxml的combox组件:
//列举监听事件 override public function listNotificationInterests() : Array { return [ SearchLoginProxy.insertLoginInfo, SearchLoginProxy.getSexList ]; } //处理监听事件 override public function handleNotification( note : INotification ) : void{ switch (note.getName()){ case SearchLoginProxy.insertLoginInfo: (insertApp.parentDocument as index).pageNo = 1; sendNotification(LoginAddReturnCommand.NAME,insertApp); break; case SearchLoginProxy.getSexList: //给“性别”combox赋初始值 insertApp.sexList = note.getBody() as ArrayCollection; insertApp.cb_sex.selectedIndex = 0; default : break; } }
- 尚未实现的功能
- 项目环境
评论
发表评论
-
red5+flex实现超简易群聊天功能
2011-08-07 18:22 6293要说这个聊天功能有多简单,大家看图就知道真相了: ... -
red5简介及基础知识
2011-08-06 23:46 4658简介 Red5的主要功能和Macromed ... -
Flex通信-与Java实现Socket通信实例
2011-07-31 22:30 13900环境准备 【服务器 ... -
Flex通信-Java服务端通信实例
2011-07-26 11:44 10275Flex与Java通信的方式有很多种,比较常用的有以下方式: ... -
JAVA(spring/hibernate/blaseds)+Flex整合方案
2011-07-23 07:50 4497实现flex与java通信的 ... -
JAVA(ssh2框架)+Flex实现权限控制方案分析
2011-07-22 14:37 5867目前项目使用的是Struts2+Hibernate+Sp ... -
Flex4基础-组件定位和容器布局
2011-07-22 11:15 21537以下资料部分来自Adobe中文网,但资料年代已久,根据我自己的 ... -
Flex4基础-ActionScript语法
2011-07-21 21:23 4610简介 Flex ... -
blazeds实现java到flex类映射
2011-07-02 14:28 4566最近在学习flex与java交互的技术,其中flex可以通过r ... -
Flex4消息提示框Alert
2011-06-28 20:57 12445在任何BS项目中,消息提示框都是非常常见的功能组件,flex在 ...
相关推荐
标题中的“PureMVC+Flex+BlazeDS+Spring+Hibernate.doc”指的是一项整合了多种技术的Web应用开发方案,这些技术包括PureMVC、Flex、BlazeDS、Spring和Hibernate。这篇文档可能是指导读者如何将这些技术结合在一起...
根据提供的文件信息,本文将详细介绍如何一步步搭建PureMVC+Flex+BlazeDS+Spring+Hibernate的技术栈。这个过程涉及到了多个技术领域的整合,包括前端的Flex开发、后端的Java开发以及数据库交互等多个方面。 ### 一...
标题中的“PureMVC+Flex+BlazeDS+Spring+Hibernate”是一个常见的技术栈组合,用于构建企业级的 Rich Internet Applications (RIA)。这个技术栈包括前端开发框架、后端服务通讯、应用服务器、服务端架构和数据持久化...
你需要实现这些层的接口,处理数据的增删改查操作,并通过Spring进行依赖注入。 6. **配置BlazeDS和Flex客户端通信**:在Tomcat中部署blazeds.war,配置Flex Messaging Context,使Flex客户端可以通过AMF与服务器端...
以上步骤中,每一步都涉及到对特定技术的深入理解和操作,例如MyEclipse的使用、Flex与BlazeDS的集成、Spring和Hibernate的配置以及PureMVC架构的实现。这些知识点构成了整个搭建过程的基础,为开发者提供了一条清晰...
标题中的"FLEX4+Gilead+BlazeDS+pureMVC+spring2.5 MVC+hibernate3.3+SLF4J+CXF2.3.0"涉及了多个关键技术和框架,这些都是在构建分布式、企业级Web应用程序时常用的技术组件。下面将逐一解析这些技术的核心概念和...
在IT行业中,构建高效、可扩展的企业级应用是一项复杂任务,而"Flex pureMVC blazeDS j2ee Spring3.0+Hibernate3.0"这个主题涵盖了前端开发、后端架构以及数据持久化等多个关键领域。下面将详细介绍这些技术及其在...
本实例采用了一个强大的组合:PureMVC作为前端框架,BlazeDS作为通信服务器,Spring和Hibernate作为后端框架,以及MySQL作为数据库系统,构建了一个完整的应用程序,实现了基本的数据操作功能,如增删改查。...
《pureMVC范例解析:Flex前端与Spring+Hibernate后端集成》 纯MVC(PureMVC)是一个轻量级的设计模式框架,主要用于构建可维护性和可扩展性高的应用程序。在本例中,它被应用于一个Flex项目,展示了如何在前端使用...
8. **PureMVC**:一种轻量级的MVC(Model-View-Controller)框架,用于提高Flex应用的结构和可维护性。 接下来,我们将逐步创建项目: A. **新建Flex项目**:在MyEclipse中,通过File > New > Flex Project创建一...
(4) **框架支持**:Cairngorm和Pure MVC等Flex开发框架提高了开发效率和代码复用性,Spring ActionScript框架更是为Java程序员提供了类似Spring的开发体验,如依赖注入功能。 (5) **成熟的技术生态**:自Flex 1.0...
### 前端技术:Flex3 + pureMVC **Flex3** 是Adobe公司推出的一款用于构建富互联网应用程序(RIA)的开源框架,它基于ActionScript 3.0,能够创建高度交互式的用户界面。在VideoShare中,Flex3被用来构建前端界面,...
Spring框架负责业务逻辑层的管理,而Hibernate则被用来处理数据库操作。这样的架构不仅保证了系统的稳定性和安全性,还提高了开发效率。 ##### 3. 客户端设计与实现 客户端部分选择了PureMVC框架来组织代码结构。...