|
在笔记一中,忘记介绍一下Iteration::two和Cairngorm的背景了。 Iteration::two是一家致力于RIA开发的公司。 详情请看:http://www.iterationtwo.com/index.html
Macromedia Acquires iteration::two in creation of Macromedia Consulting Europe.
Macromedia acquires iteration::two, an industry-leading software consultancy, to create a European Rich Internet Application consulting organisation based in Edinburgh , Scotland. Cairngorm是Iteration::two的开源项目之一。下载和更新地址是http://www.iterationtwo.com/open_source_cairngorm.html
好,现在继续开始我的学习笔记: 1. 在Control中有Command.as定义了Command接口,笔记一中FrontController中addCommand的调用添加的Command都必须实现此接口。Command接口只定义一个唯一的需要实现的方法execute(); 这是一个典型的命令模式, 所有后续的命令都实现此接口, 对外统一提供一个单点入口execute(), 其他的人都可以进行调用,但不需要了解命令具体的实现方式.
2. 在Model中定义了ModelLocator接口,ModalLocator是所有数据绑定的接口,也就是说应用中所有需要进行绑定的数据都需要通过此接口进行定位。在实际的应用中需要实现此接口,并提供所有的绑定数据。
3. 在business中定义了两个类 ServiceLocator和Responder。 ServiceLocator这是伪单例类, 应用开发者用于定义并获得服务. 之所以是伪单例类, 是因为ServiceLocator是定义在mxml中的, 它需要一个无参数的Public构造函数. 使用中必须定义一个ServiceLocator的子类, 并在其中定义需要的服务.
代码示例:首先在Services.mxml中进行如下定义:
* <cairngorm:ServiceLocator xmlns:mx="http://www.macromedia.com/2003/mxml" * xmlns:cairngorm="org.nevis.cairngorm.business.*" > * * <mx:RemoteObject id="customerDelegate" source="org.nevis.cairngorm.samples.login.CustomerDelegate" * result="event.call.resultHandler( event )" * fault="event.call.faultHandler( event )"> * </mx:RemoteObject> * * </cairngorm:ServiceLocator>
在Flex主应用中添加一行: <business:Services id="services" /> 其中business命名空间在应用头部进行申明 xmlns:business="org.nevis.cairngorm.samples.store.business.*" ServiceLocator使用方法: 在业务代理类(Delegate)中通过如下方式进行调用: * var service = ServiceLocator.getInstance().getService( "customerDelegate" );
在View中,定义了两个类 ViewLocator和ViewHelper ViewHelper:用于隔离Command命令类和View视图的具体实现. 为了执行业务功能, Command类需要查询并更改视图, 在执行业务逻辑前, 命令类需要从视图中获得用户输入的数据; 业务逻辑结束后又经常需要更改视图, 显示执行结果. 通过将查询和更改视图的操作封装到单独ViewHelper类中, 命令类完全不需要了解视图类的任何信息. ViewHelper属于一种特殊的视图, 当ViewHelper创建后, 就被注册到指定的视图. ViewHelper继承自MXMLObject, 在重写的初始化函数(initialized)中, 调用ViewLocator进行注册, 并指定unload方法的监听函数unregister, 在unload时, 调用unregister, 使用ViewLocator的取消注册.
ViewLocator是一个单例类, 用于获取ViewHelper操作视图. 命令类需要通过ViewHelper的方法来查询更改视图, 而ViewLocator即用于让命令类取得需要的ViewHelper. 命令类不需要知道ViewHelper的名称, ViewLocator会返回需要的ViewHelper实例.
现在Cairngorm的基础框架已经介绍完毕,将在以后继续介绍如何在实际应用中使用上面提及的基础框架。
Flex是一个面向服务的框架, 借用了异步完成标记(Asynchronous Completion Token)设计模式, 代码以异步的方式运行. 此模式将用户的操作完成信号以及数据以异步的方式返回给用户, 这种做法的效率比较高, 用户不需要同步等待运行结果. 可以在服务运行的同时进行其他操作. 使用ACT模式时, 需要将服务返回的动作和数据绑定到一个异步的处理操作. ACT必须在服务调用前进行指定. 服务调用时,用户可以进行其他操作, 当服务结束, 用户使用ACT接收响应并进行相应的处理. 当调用HTTP Service, RemoteObject, WebService时, Flex会返回一个数据服务调用(Data Service Call)的实例. 你可以使用 webService.send()返回的调用对象(Call Object)来进行结果处理. 你可以在调用对象中添加信息, 并在结果事件的处理函数中通过event.call得到调用对象.这就是ACT的实现机制. 代码举例如下:
<mx:HTTPService id="MyService" url="" result="myHandler(event)" />
<mx:Script> <![CDATA[
function storeCall() { // Create a variable called call to store the instance // of the service call that is returned. var call = MyService.send(); // Add a variable to the call object that is returned. // You can name this variable whatever you want. call.marker = "option1";
} // In a result event handler, execute conditional // logic based on the value of call.marker. function myHandler(event) { var call = event.call if (call.marker == "option1") { //do option 1 } else
} ]]> </mx:Script>在调用服务(MyService.send())时, 返回了调用对象 call 可以给调用对象添加信息 call.marker = "option1"; 在服务完成的处理函数中可以使用 event.call 获得调用对象, 从而获得信息(call.marker).
Cairngorm是Iteration::two的开源项目, 是使用macromedia Flex的RIA开发的最佳实践(best-practice)框架. 在Cairngorm基础上开发RIA, 将会在Iteration::two的专家体系和现有的灵活可维护企业解决方案中达到平衡. Cairngorm本身并不是一个完整的企业应用, 它只是提供了一个开发的骨架, Iteration::two称之为体系. 在这个体系中包括以下几个部分: 1. Business(业务逻辑部分) 2. Command(命令部分) 3. Control(控制部分) 4. Model(数据模型) 5. View(界面视图) 6. VO(ValueObject)
我们从Control说起: 在Control中, 定义了3个基类: Event, EventBroadcaster, FrontController. Event用于在应用不同的层之间传递事件, 并携带事件的数据. 包含type和data两个成员. type存放一个区别不同事件的名称,将会在FrontController中进行注册. 而在命令(Command)类中, 会对事件进行响应.
EventBroadcaster是一个单例类(singleton), 用于广播用户动作对应的事件. 使用方法: EventBroadcaster.getInstance().broadcastEvent( ... )
FrontController稍微复杂一点点. 用于将特定的用户动作分发到指定的命令类. FrontConroller是请求处理的核心类. 整个体系中遍布的EventBroadcaster.getInstance().broadcastEvent( ... )这样的调用, 都是用来通知监听控制器: 用户发出了请求. 在实际应用中, 开发者应该生成一个FrontContoller的子类, 并在构造函数中调用addCommand()注册预期事件的处理命令. FrontController的具体实现类应该创建一次而且只能创建一次. 通常的做法是这样的: 在主应用中, 将FrontController的子类作为一个Tag进行申明, * <p> * <code> * <mx:Application xmlns:control="com.domain.project.control.LoginController" ... > * * <control:LoginController id="controller" /> * * ... * * </code> * </p> FrontController的处理实质上是这样的, 在调用addCommamd时, 将处理命令保存在数组中, 将与之对应的事件处理对象注册为FrontController本身, 在事件触发, 调用FrontController的handleEvent时, 调用executeCommand, 在executeCommand中, 先在数组查找出事件对应的命令, 调用命令的execute方法. 这就要求所有的命令都实现Command接口
(内容较多, 未完待续)
摘要: 在Java5.0中对于RMI的使用发生了一些改变, 使得RMI的使用更加容易方便.一. 定义RMI接口, 这一步最简单, 与以前相比, 也没有变化.
import java.rmi.Remote;import java.rmi.RemoteException;public interface Payment extends Remote... 阅读全文
一. 事件简介 事件可以由外设触发, 比如:键盘,鼠标, 也可能是外部输入, 比如:web service的返回. 事件还能由组件的外观和生命周期发生变化时触发, 比如:组件的创建或者改变大小. 所有用户与应用交互都会产生事件.用户没有直接与应用交互也可能产生事件, 比如:数据装载完毕. 你可以在程序中使用事件监听器监听这些事件. 事件监听器是函数方法用于响应指定的事件. 有时也称之为事件处理器. Flex的事件模型基于DOM3事件模型. 组件产生派发事件并消费(监听)其他事件.如果一个对象想要了解其他对象事件的信息, 可以注册一个监听器. 当事件发生时,对象派发此事件到所有注册过的监听器中. 组件有Flex提供的内建事件. 也可以使用派发-监听模型定义自己的事件监听器, 并指定监听器监听何种事件. 二. 事件流简介 当一个事件被派发出来时, 事件对象从根节点开始自上而下开始扫描display list, 一直到目标对象, 检查每个节点是否有相应的监听器. 目标对象指的是display list中产生事件的对象. 比如: <mx:Panel> <mx:HBox> <mx:VBox> <mx:Button /> </mx:VBox> </mx:HBox> </mx:Panel> 如何此时 resize了VBox, 则会从根(Application)开始, 下来检查Panel, HBox, 直到目标对象-产生resize事件的VBox为止.
三. 事件的派发 Flex中可以通过dispatchEvent()方法手工派发事件, 所有UIComponent的子类都可以调用此方法. 语法: objectInstance.dispatchEvent(new Event("event_type"):Boolean 参数event_type是Event对象的type属性. 函数的返回值总是True. 可以使用此方法派发任意事件, 而不仅仅是用户自定义事件, 比如: 可以派发一个Button的Click事件. var result:Boolean = buttonInstance.dispatchEvent(new Event(MouseEvent.CLICK));
在Flex应用中不是必须对新派发的事件进行处理, 如果触发了一个事件, 而没有对应的Listener时,Flex忽略此事件. 如果想给Event对象添加新属性, 就必须继承Event类,然后定义新属性
四.事件的传播: 事件触发后, Flex有3个检测事件监听器的阶段, 3个阶段的发生的顺序如下: 1. 捕获 2. 目标 3. 上浮 在任意一个阶段, 节点们都有机会操作事件. 比如: 用户点击了一个在VBox中的Button, 在捕获阶段, Flex检查Application对象(根节点)和VBox是否有监听器处理此事件. Flex然后在目标阶段触发按钮的监听器. 在上浮阶段, VBox和应用以与捕获阶段相反的顺序再次获得机会处理事件. 在ActionScript3.0中,你可以在任意目标节点上注册事件监听器. 但是部分事件会被直接传给目标节点,比如Socket类. 捕获阶段的节点顺序是从父节点到子节点的, 而上浮阶段刚好相反. 捕获事件缺省是关闭的,也就是说如果要捕获事件, 必须显式指定在捕获阶段进行处理. 每一个Event都有target和currentTarget属性, 帮助跟踪事件传播的过程.
捕获阶段: 在捕获阶段,Flex在显示列表中检查事件的祖先是否注册了事件的监听器. Flex从根节点开始顺序而下. 大多数情况中, 根节点是Application对象. 同时, Flex改变事件的currentTarget值. 缺省情况下, 在此阶段,没有容器监听事件. use_capture参数的值是False,在此阶段添加监听的唯一方法是在调用add_listener时, 传入一个为True值的use_capture参数, 比如: myAccordion.addEventListener(MouseEvent.MOUSE_DOWN, customLogEvent, true); 如果是在Mxml中添加监听, Flex设置此参数为False, 没有办法进行修改. 如果设置了use_capture为True, 那么事件将不会上浮. 如果既想捕获又想上浮就必须调用 addEventListener两次. 一次use_capture参数为true, 一次为false; 捕获很少使用, 上浮的使用更为普遍.
目标阶段: 在目标阶段, Flex激发事件的监听程序, 不检查其他的节点.
上浮阶段: 事件只在bubbles属性为True时才进行上浮. 可以上浮的事件包括: change, click, doubleClick, keyDown, keyUp, mouseDown, mouseUp. 在上浮阶段, Flex改变事件的currentTarget属性, 而target属性是初始派发事件的对象.
查询事件阶段: 使用事件的eventPhase可以获得事件当前的阶段, 1: CAPTURE_PHASE 2: AT_TARGET 3: BUBBLING_PHASE 示例: private function determineState(event:MouseEvent):Void { Debug.trace(event.eventPhase + ":" + event.currentTarget.id); }
停止传播: 使用下面两个函数停止事件的传播: stopPropagation() stopImmediatePropagation()
表单认证是Asp.net中最Cool的功能之一,一般来说应用都会要求输入认证信息(典型的是用户名和密码)。 在Web.config的设置项中,可以指定登录页面和哪些资源需要保护。当用户第一次访问被保存的资源时,应用会自动定向到指定的登录页面。 如果成功登录,ASP.NET会转到用户初始请求的页面。 以往的应用需要在每个页面的顶部判断用户是否成功登录,手工定向到登录页面,而现在这个工作由表单认证简单地完成了。
举个简单的例子来说明开发过程: 一个应用中有两个页面PublicPage.aspx是向公众开放的,PrivatePage.aspx只允许登录用户才能访问。 第3个页面是登录页面,要求输入用户名和密码。 步骤如下: 1、把PublicPage.aspx, login.aspx, web.config拷贝到一个IIS的虚拟目录下。 2、创建一个子目录Secret,将PrivatePage.aspx, web.config拷贝到子目录中。 3、在web.config中添加以下代码, 实现访问保存页面自动跳转登录页面的功能 <authentication mode="Forms"> <forms loginUrl="LoginPage.aspx"> .... </forms> </authentication> 4、另外有一个<credentials>小节列出合法用户和密码 <credentials passwordFormat="Clear"> <user name="Jeff" password="imbatman" /> <user name="John" password="redrover" /> <user name="Bob" password="mxyzptlk" /> <user name="Alice" password="nomalice" /> <user name="Mary" password="contrary" /> </credentials> 此例子中关掉了的加密选项,缺省是开的。 5、在Secret子目录的web.config中添加以下代码,实现保护功能。 <authorization> <deny users="?" /> </authorization> 这是用于通知权限管理模块System.Web.Security.UrlAuthorizationModule阻止未登录用户的访问。"?"代表匿名用户,也可以说是未登录用户。 实际的权限验证是由Login.aspx完成的。下列语句 if(FormsAuthentication.Authenticate(UserName.Text,Password.Text)) 把用户名和密码传给System.Web.Security.FormsAuthentication,如果验证成功,返回True。并且执行页面跳转语句 FormsAuthentication.RedirectFromLoginPage(UserName.Text,false);
6、真实环境的表单认证比上面的例子要复杂的多,真实应用不大可能把用户和密码保存在文本文件中,比较常见的是存放在数据库中。 假定用户表Users有3个字段UserName, password, Role. 对于这种情况,我们需要在刚才的基础上进行2个地方的修改:Login.aspx、web.config(根目录下的) 在web.config中不再需要<credentials>小节了。 login.aspx也不再使用 FormsAuthentication.Authenticate 来验证密码,而使用CustomAuthenticate替代。 在这个方法中使用Sql查询语句来判断用户是否合法。
Flex2.0不再仅仅是Web应用或者显示服务器。它是一个框架。
你不再需要象Flex1.5那样需要一个Server,不需要在浏览器的URL中输入mxml后缀的请求来查看。可以直接把SWF文件放到Web目录下即可。这一句话是重点啊。
这意味着什么呢? Flex开始免费了!! 因为Flex将免费发布Flex SDK,即可以免费将mxml编译生成swf 在Flex2.0不需要再象1.5那样需要Flex的Server了。
Don't think of Flex as a web application or a presentation server any more. It isn't. Flex 2 is a lot more. And the heart of Flex 2 is the framework. Flex Framework 2, as it's officially called, is a programming model, a set of components and class libraries that make building Rich Internet Applications easy. This framework is included with the all new Eclipse-based Flex Builder 2 IDE. There is still a server component in the Flex 2 product line, Flex Enterprise Services 2, but its capabilities are focused around messaging and enterprise data services.
You read that right. With Flex 2 you won’t need to purchase a server to build applications that use Flex Framework. This might take a little getting used to, because you've been putting MXML files into a web directory and requesting them with a browser to see how they run. Well, you don't need to do that anymore. What you do now is either run them from within Flex Builder 2 or use the command-line compiler mxmlc.
The end result is a SWF file that you deploy inside your favorite web server.
修改分为以下几个部分: 一.使用方法上2.0与1.5是不同的, 比如: Application.alert() 修改为 Alert.show() 二.增加了存取限制符, 即public, private, ... 更加强化了OO的概念 三.添加了类型限定. 所有的变量,属性,方法,返回值都必须指定类型, 在1.5中: var s = "page"; 是可以的, 但是在2.0中必须写成: public var s:String = "page"; 四.事件的修改 派发自定义事件时必须new Event而不是使用通用对象, 比如: click="dispatchEvent(new Event('checkOut'))" 监听器不再需要Delegate了, 1.5中 b1.addEventListener(“click”, mx.utils.Delegate.create(this,myListener)); 在2.0中可以改为:b1.addEventListener(MouseEvent.CLICK, myListener); 五. 所有的ActionScript组件都要封装到package中, 可以使用匿名package, 但是package语句必须是组件定义文件的第一行. package { public class MyClass { // Class definition } } // Close package 六. RemoteObject在2.0中不能继续使用了. 七. 图形组件, 在2.0中如果要使用图形,必须下载单独的swc
八. ActionScript由2.0升级为3.0 九. Flex Framework进行了升级修改, 部分类被新类所代替, 比如:MediaDisplay被VideoDisplay取代.
<%@ page session="true" %> <%@ taglib uri="FlexTagLib" prefix="mm" %> <% Integer num = new Integer(22100); session.putValue("num",num); %> <html><body> <h3>Introduction</h3> <p>This is an example of writing MXML in a JSP.</p> <h3>My App</h3> <mm:mxml border="1"> <mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" creationComplete="myService.send();"> <mx:HTTPService url="test.jsp;jsessionid=<%=session.getId()%>" id="myService"/> <mx:Label text="<%= session.getAttribute("num") %>"/> <mx:Label text="<%= session.getId() %>"/> </mx:Application> </mm:mxml><br> </body> </html>
I've been looking at sending and receiving data asyncronously using Flex's HTTPService and native Flash data loading capabilities. One thing that tripped me up with that xml.load() was an asyscronous data call -- which means you cannot use the result/return object until it is completly loaded. One way around this is to use the AS delegate to invoke a function which uses the result. Below is some code.
http://www.macromedia.com/2003/mxml">
function LoadRequest() { var myXML = new XML(); myXML.ignoreWhite = true; myXML.load ("tree.xml"); myXML.onLoad = mx.utils.Delegate.create(this, function() { myService.send(myXML) }); }
function ProcResult(event) { txtDebug.text = event.result; }
function ProcFault(errorString, code) { txtIssuerList.text = errorString + " " + code ; }
http://localhost:8700/flex/servlet/test.MyServletPrintln" contentType="application/xml" method="post" id="myService" fault="ProcFault(event.fault.faultstring, event.fault.faultcode)" result="ProcResult(event)">
<destination id="SampleEmployeeRO"> <properties> <source>samples.explorer.EmployeeManager</source> <stateful>true</stateful> </properties> <adapter ref="java-object" > </destination>
Remoting Object一共有两个属性:source和stateful 其中stateful是用于设置Flex创建目的对象实例方法的布尔量 如果设置为True,则在此Session中只创建唯一的一个实例。否则,每次调用都创建一个新的对象实例。 默认值是False;
|