iBATIS&Spring合奏(2)-Flex前端融合
iBATIS&Spring合奏(二)--Flex前端融合
iBatis和Spring的进度依然如昨。回馈社区的时间到了,今天是Flex的时间。以前用Java+Flex做一般用LCDS的dataservice组件,其实就是偷懒。因为最近研究了下Spring+iBATIS,也是出于项目需要,决定勤奋一回,用LCDS的RPC服务吧。RPC在FlexLCDS中支持三种服务——WebService,HttpService以及本文用的RemotingObject。LCDS官方文档是一手资料,虽然没人翻译,依然一个人孤独和单词作战到底吧。依然用比较清晰的思路和模式为童鞋们呈现集成环境下开发一下简单web程序的过程。另,最近总是看到分布式之类的讨论,RPC也是一种分布式技术啊,后面再加上SpringAOP中管理MemCache也蛮好。不多扯了,越扯越跑题……
1)前面的可以参看上一篇文章。这里要注意的是搭建集成环境myeclipse+flexbuilder。为了大家不走弯路,myeclipse7.0以后不支持Flex插件啦,可以下载插件版的flexbuilder也可以。我用的是老版(myeclipse6.5+flexbuilder3.0)若说,不用什么集成开发环境也一样,只是懒得开两个编译器,反正都是Web程序,都要部署滴嘛。tomcat6.x。spring,ibatis随便啦。
2)配置RemotingObject——remoting-config.xml如下:
以上的路径就指向需要调用的服务器端的服务。当然了解的童鞋知道,底层也是用序列化反序列化来实现的。这里UserService要extends AbstractAssembler。这里有个装配器的概念,可以参看官方文档解释。
3)值对象ValueObject与持久化对象PersistenceObject的遥相呼应
这里简单提一下,RemotingObject指的是服务器端的要请求服务的对象。大家可以理解为javaRMI服务中的 服务器存根(stub)。而VO啦就是与PO相对应的客户端对象。序列化也得告诉人家传神马对象吧。VO如下,在Flex的src下,其实就是个ActionScriptClass。源码如下:
4)Flex强有力的MXML客户端界面。这里可以看到,调用远程对象的方法是非常容易的一件事情。这里的消息协议采用的是服务自带的amf。基于http轮询建立的。当然可以采用nio的相关协议,可以在配置文件中修改协议。还有这里的Channel配置必不可少。这里多一句,LCDS的四大项服务——Remoting,Messaging,DataService,Proxy都是基于Messaging的。换句话说,只是实现方式不同,但是底层都是通过调用Messaging服务来实现的。所以有兴趣的可以先了解下Messaging,可以自己写通信协议,木有问题。这里不介绍那方面的了。至于DataService就是以前用的比较多的,前面几篇文章有提到。
5)在这里,我想说,就是部署服务了。然后运行吧。弄点效果图吧,今天没有兴致写神马界面,只为简单介绍吧。主界面如下:

下面这张是添加User的小图

总算写完收工。坐得腰疼……程序员真的是短寿又令人激动的职业。我只能说,不能怪代码了,该去运动一下,少吃夜宵和零食。生活在世界上很美好,不是因为世界有多美好而是因为我们活着,活着就会有好事发生,就要珍惜和感激。
下面依旧一段猿类们的冷笑话,轻松一下氛围:
孩子哭闹的时候就在边上打开吸尘器,然后拍小孩的背,一会儿小孩子就睡着了,理论依据是小孩子最多同时关注2件事情,如果有三件事情需要同时关注,他就只能睡觉了…结论:所有小孩都是单核处理器,一旦多线程,就自动挂起..——这爹是个程序员
(把源码spritis奉上吧,果真加了Flex就是大了不少。WebContent\WEB-INF\lib里面的jar包麻烦大家自己搞定吧实在超过10M啦)
iBatis和Spring的进度依然如昨。回馈社区的时间到了,今天是Flex的时间。以前用Java+Flex做一般用LCDS的dataservice组件,其实就是偷懒。因为最近研究了下Spring+iBATIS,也是出于项目需要,决定勤奋一回,用LCDS的RPC服务吧。RPC在FlexLCDS中支持三种服务——WebService,HttpService以及本文用的RemotingObject。LCDS官方文档是一手资料,虽然没人翻译,依然一个人孤独和单词作战到底吧。依然用比较清晰的思路和模式为童鞋们呈现集成环境下开发一下简单web程序的过程。另,最近总是看到分布式之类的讨论,RPC也是一种分布式技术啊,后面再加上SpringAOP中管理MemCache也蛮好。不多扯了,越扯越跑题……
1)前面的可以参看上一篇文章。这里要注意的是搭建集成环境myeclipse+flexbuilder。为了大家不走弯路,myeclipse7.0以后不支持Flex插件啦,可以下载插件版的flexbuilder也可以。我用的是老版(myeclipse6.5+flexbuilder3.0)若说,不用什么集成开发环境也一样,只是懒得开两个编译器,反正都是Web程序,都要部署滴嘛。tomcat6.x。spring,ibatis随便啦。
2)配置RemotingObject——remoting-config.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <service id="remoting-service" class="flex.messaging.services.RemotingService"> <adapters> <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true" /> </adapters> <default-channels> <channel ref="my-amf"/> </default-channels> <destination id="userservice"> <properties> <source>com.qiyun.spritis.service.UserService</source> <scope>application</scope> </properties> </destination> </service>
以上的路径就指向需要调用的服务器端的服务。当然了解的童鞋知道,底层也是用序列化反序列化来实现的。这里UserService要extends AbstractAssembler。这里有个装配器的概念,可以参看官方文档解释。
3)值对象ValueObject与持久化对象PersistenceObject的遥相呼应
这里简单提一下,RemotingObject指的是服务器端的要请求服务的对象。大家可以理解为javaRMI服务中的 服务器存根(stub)。而VO啦就是与PO相对应的客户端对象。序列化也得告诉人家传神马对象吧。VO如下,在Flex的src下,其实就是个ActionScriptClass。源码如下:
package vo { [Bindable] [RemoteClass(alias="com.qiyun.spritis.pojo.User")] public class User { public function User() { } public var id:int; public var username:String; public var password:String; public var company:String; } }
4)Flex强有力的MXML客户端界面。这里可以看到,调用远程对象的方法是非常容易的一件事情。这里的消息协议采用的是服务自带的amf。基于http轮询建立的。当然可以采用nio的相关协议,可以在配置文件中修改协议。还有这里的Channel配置必不可少。这里多一句,LCDS的四大项服务——Remoting,Messaging,DataService,Proxy都是基于Messaging的。换句话说,只是实现方式不同,但是底层都是通过调用Messaging服务来实现的。所以有兴趣的可以先了解下Messaging,可以自己写通信协议,木有问题。这里不介绍那方面的了。至于DataService就是以前用的比较多的,前面几篇文章有提到。
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" backgroundGradientColors="[0x000000,0x323232]" > <mx:Script> <![CDATA[ import vo.User; import mx.collections.ArrayCollection; import mx.rpc.events.ResultEvent; import mx.rpc.events.FaultEvent; import mx.utils.ArrayUtil; import mx.controls.Alert; [Bindable] private var users:ArrayCollection; [Bindable] private var myUser:User=new User(); private function selectedDGrid():void{ userName.text=userdg.selectedItem.username; password.text=userdg.selectedItem.password; company.text=userdg.selectedItem.company; } private function getAllUsers_resultHandler(event:ResultEvent):void { users = event.result as ArrayCollection; } private function getUserByCompanyName_resultHandler(event:ResultEvent):void { users = event.result as ArrayCollection; } private function insertUser():void{ myUser.username=userName.text; myUser.password=password.text; myUser.company=company.text; user.insertUser(myUser); Alert.show("save a user named : "+userName.text,"SAVE!"); } private function updateUser():void{ var uu:User=userdg.selectedItem as User; uu.username=userName.text; uu.password=password.text; uu.company=company.text; user.updateUser(uu); Alert.show("update a user!","UPDATE!"); } private function deleteUser():void{ user.deleteUser(userdg.selectedItem.id); Alert.show("delete a user named : "+userdg.selectedItem.username,"DELETE!"); } private function faultHandler(event:FaultEvent):void { Alert.show(event.fault.faultString, "Error"); } ]]> </mx:Script> <mx:RemoteObject id="user" destination="userservice" channelSet="{channelSet}" fault="faultHandler(event)" source="com.qiyun.spritis.pojo.User"> <mx:method name="getAllUsers" result="getAllUsers_resultHandler(event)"/> <mx:method name="getUserByCompanyName" result="getUserByCompanyName_resultHandler(event)"> <mx:arguments> <arg1> {companies.selectedItem.data}</arg1> </mx:arguments> </mx:method> <mx:method name="updateUser" > <mx:arguments> <arg1> {myUser} </arg1> </mx:arguments> </mx:method> <mx:method name="insertUser"> <mx:arguments> <arg1> {myUser} </arg1> </mx:arguments> </mx:method> <mx:method name="deleteUser" > <mx:arguments> <arg1> {userdg.selectedItem.id} </arg1> </mx:arguments> </mx:method> </mx:RemoteObject> <mx:ChannelSet id="channelSet"> <mx:AMFChannel id="amfChannel" url="http://localhost:8080/spritis/messagebroker/amf" /> </mx:ChannelSet> <mx:DataGrid id="userdg" itemClick="selectedDGrid()" editable="false" dataProvider="{users}" width="100%" height="100%"> <mx:columns > <mx:DataGridColumn dataField="id" headerText="id"/> <mx:DataGridColumn dataField="username" headerText="username"/> <mx:DataGridColumn dataField="password" headerText="password"/> <mx:DataGridColumn dataField="company" headerText="company" textAlign="right"/> </mx:columns> </mx:DataGrid> <mx:HBox> <mx:Button label="Get All Users" click="user.getAllUsers()"/> <mx:Button label="Get User By CompanyName" click="user.getUserByCompanyName(companies.selectedItem.data);"/> <mx:ComboBox id="companies" width="150" text="company" > <mx:dataProvider> <mx:ArrayCollection> <mx:source> <mx:Object label="TB" data="TB"/> <mx:Object label="IBM" data="IBM"/> <mx:Object label="alibaba" data="alibaba"/> <mx:Object label="MS" data="MS"/> <mx:Object label="TX" data="TX"/> </mx:source> </mx:ArrayCollection> </mx:dataProvider> </mx:ComboBox> </mx:HBox> <mx:Panel title="Add User" > <mx:Form id="myForm" color="black" > <mx:FormItem label="username:"> <mx:TextInput id="userName" width="100"/> </mx:FormItem> <mx:FormItem label="password:"> <mx:TextInput id="password" color="black" width="100" /> </mx:FormItem> <mx:FormItem label="company:"> <mx:TextInput id="company" width="100" /> </mx:FormItem> <mx:HBox> <mx:Button label="clear" click="userName.text='';password.text='';company.text=''"/> <mx:Button label="Save" click="insertUser();user.getAllUsers()"/> <mx:Button label="Delete" click="deleteUser();user.getAllUsers()"/> <mx:Button label="Update" click="updateUser();user.getAllUsers()"/> </mx:HBox> </mx:Form> </mx:Panel> </mx:Application>
5)在这里,我想说,就是部署服务了。然后运行吧。弄点效果图吧,今天没有兴致写神马界面,只为简单介绍吧。主界面如下:
下面这张是添加User的小图
总算写完收工。坐得腰疼……程序员真的是短寿又令人激动的职业。我只能说,不能怪代码了,该去运动一下,少吃夜宵和零食。生活在世界上很美好,不是因为世界有多美好而是因为我们活着,活着就会有好事发生,就要珍惜和感激。
下面依旧一段猿类们的冷笑话,轻松一下氛围:
孩子哭闹的时候就在边上打开吸尘器,然后拍小孩的背,一会儿小孩子就睡着了,理论依据是小孩子最多同时关注2件事情,如果有三件事情需要同时关注,他就只能睡觉了…结论:所有小孩都是单核处理器,一旦多线程,就自动挂起..——这爹是个程序员
(把源码spritis奉上吧,果真加了Flex就是大了不少。WebContent\WEB-INF\lib里面的jar包麻烦大家自己搞定吧实在超过10M啦)