Flex Project 需要指定 Server 端的配置文件地址:
图 4. 新建 Flex 工程 - 第二步因此,需要填入 EmployeeMgmt-Server 项目的 web 根目录,该目录下必须要存在 /WEB-INF/flex/
。点击“Validate Configuration”验证配置文件是否正确,只有通过验证后,才能继续。默认地,Flex Builder 将会把生成的 Flash 文件放到 EmployeeMgmt-Server 项目的 web/EmployeeMgmt-Flex-debug
目录下。
一个 Flex Project 的目录结构如下:
图 5. Flex 工程的目录结构用 Flex Builder 做出漂亮的用户界面非常容易。Flex Builder 提供了一个可视化的编辑器,通过简单的拖拽,一个毫无经验的开发人员也能够设计出漂亮的布局。如果熟悉一点 XML 的知识,编辑 MXML 也并非难事。我们设计的 Employee Management 系统界面的最终效果如下:
图 6. 用 Flex Builder 的可视化编辑器设计界面本文不打算讨论如何编写 Flex 界面,而是把重点放在如何实现远程调用。
为了能在 Flex 中实现远程调用,我们需要定义一个 RemoteObject 对象。可以通过 ActionScript 编码创建该对象,也可以直接在 MXML 中定义一个 RemoteObject 对象,并列出其所有的方法:
清单 13. 定义 flexServiceRO<mx:RemoteObject id="flexServiceRO" destination="flexService"> <mx:method name="queryAll" result="handleQueryAll(result : ResultEvent)"/> </mx:RemoteObject> |
现在,就可以调用这个名为 flexServiceRO 的 RemoteObject 对象的方法了:
清单 14. 调用 FlexServiceRO.queryAll()flexServiceRO.queryAll(function(result : ResultEvent) { var employees = result.result as Array; }); |
运行该 Flex Application,雇员信息已经被正确获取了:
图 7. 在浏览器中运行 Flex application增强 RemoteObject 对象
通过 RemoteObject 进行调用虽然简单,但存在不少问题:首先,RemoteObject 是一个 Dynamic Class,Flex Builder 的编译器无法替我们检查参数类型和参数个数,这样,在编写 ActionScript 代码时极易出错。此外,接口变动时(这种情况常常发生),需要重新修改 RemoteObject 的定义。此外,Flex 团队需要一份随时修订的完整的 FlexService 接口文档才能工作。
因此,最好能使用强类型的 RemoteObject 接口,让 Flex Builder 的编译器及早发现错误。这个强类型的 RemoteObject 最好能通过 Java EE 应用的 FlexService 接口自动生成,这样,就无需再维护 RemoteObject 的定义。
为了能完成自动生成 RemoteObject 对象,我编写了一个 Java2ActionScript 的 Ant 任务来自动转换 FlexService 接口以及相关的所有 JavaBean。JavaInterface2RemoteObjectTask 完成一个 Java 接口对象到 RemoteObject 对象的转换。使用如下的 Ant 脚本:
清单 15. 生成 ActionScript class 的 Ant 脚本<taskdef name="genactionscript" classname="org.expressme.ant.JavaBean2ActionScriptTask"> <classpath refid="build-classpath" /> </taskdef> <taskdef name="genremoteobject" classname="org.expressme.ant.JavaInterface2RemoteObjectTask"> <classpath refid="build-classpath" /> </taskdef> <genactionscript packageName="org.expressme.employee.mgmt" includes="Employee" orderByName="true" encoding="UTF-8" outputDir="${gen.dir}"/> <genremoteobject interfaceClass="org.expressme.employee.mgmt.flex.FlexService" encoding="UTF-8" outputDir="${gen.dir}" destination="flexService"/> |
转