<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Li Guoliang &#187; BlazeDS</title>
	<atom:link href="http://liguoliang.com/tag/blazeds/feed/" rel="self" type="application/rss+xml" />
	<link>http://liguoliang.com</link>
	<description>ActionScript Flex Java JEE PHP...</description>
	<lastBuildDate>Mon, 21 May 2012 17:04:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>基于Athena framework快速创建Java Flex应用入门教程</title>
		<link>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-index/</link>
		<comments>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-index/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 14:05:17 +0000</pubDate>
		<dc:creator>Guoliang</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Athena Framework]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[Flex企业级框架]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-index/</guid>
		<description><![CDATA[本教程简要介绍基于Athena框架的Flex应用开发. 假定你已具备基本的Flex + Java开发技能. 我们将使用Athena框架快速创建一个类似与Adobe Flex Test Drive的小应用(<a href="http://www.adobe.com/devnet/flex/testdrive.html" target="_blank">链接</a>), 该应用与Adobe Flex Test Drive的不同之处在于: Flex端采用了A<p class='read-more'><a href='http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-index/'>More...</a></p><p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></description>
			<content:encoded><![CDATA[<p>本教程简要介绍基于Athena框架的Flex应用开发. 假定你已具备基本的Flex + Java开发技能. 我们将使用Athena框架快速创建一个类似与Adobe Flex Test Drive的小应用(<a href="http://www.adobe.com/devnet/flex/testdrive.html" target="_blank">链接</a>), 该应用与Adobe Flex Test Drive的不同之处在于: Flex端采用了Athena Framework, 并基于Athena Framework增加了服务器端的支持. </p>
<p>由于时间有限, 本例仅展示环境配置,&nbsp; 基于Athena Console管理数据结构并自动生成Java, Flex代码,&nbsp; 通过简单编程实现基本功能. </p>
<p>所有的代码均可通过: <a title="http://code.google.com/p/athenahelloworld/" href="http://code.google.com/p/athenahelloworld/">http://code.google.com/p/athenahelloworld/</a> checkout(不含lib).</p>
<p>本文分三部分:</p>
<ol>
<li><a href="http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-1/">基于Athena框架的Flex入门教程(1) 环境配置</a>
<li><a href="http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-2/">基于Athena框架的Flex入门教程(2)配置Entity, 自动生成Java端, Flex端代码</a>
<li><a href="http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-3/">基于Athena框架的Flex入门教程(3) 编写Java Flex两端代码,运行程序</a></li>
</ol>
<p>下图为Athena framework官方提供的Test Drive最后效果图, 可进行Employ的CRUD, 并列出Department的所有employ.</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb22.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image_thumb2" border="0" alt="image_thumb2" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb2_thumb.png" width="628" height="499"></a></p>
<p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-index/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>基于Athena框架的Flex入门教程(3) 编写Java Flex两端代码,运行程序</title>
		<link>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-3/</link>
		<comments>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-3/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 12:04:00 +0000</pubDate>
		<dc:creator>Guoliang</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Athena Framework]]></category>
		<category><![CDATA[BlazeDS]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-3/</guid>
		<description><![CDATA[<a href="http://liguoliang.com/2011/get-start-with-ahtena-flex-framework/" target="_blank">在教程1中</a>已经创建好了Java工程及Flex工程;
<a href="http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-2/" target="_blank">在教程2中</a>已经使用AthenaConsole及metadata workbench配置好了数据库,并进行了建模及代码生成;
本节我们将编写Java端及Flex端代码, 并最终运行程序;
服务器端编程 &#8211; 创建被配置Service
在At<p class='read-more'><a href='http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-3/'>More...</a></p><p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></description>
			<content:encoded><![CDATA[<p><a href="http://liguoliang.com/2011/get-start-with-ahtena-flex-framework/" target="_blank">在教程1中</a>已经创建好了Java工程及Flex工程;<br />
<a href="http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-2/" target="_blank">在教程2中</a>已经使用AthenaConsole及metadata workbench配置好了数据库,并进行了建模及代码生成;</p>
<p>本节我们将编写Java端及Flex端代码, 并最终运行程序;</p>
<h2>服务器端编程 &#8211; 创建被配置Service</h2>
<p>在Athena框架下, Flex可以直接呼叫Java端的Service.  除了Service Class本身之外, 还需要在xml文件中声明该类, 以便Flex端呼叫使用.</p>
<h4>创建Service &#8211; DeptService.java</h4>
<p>Athena框架下的ServiceClass负责响应Flex端的请求, 与数据库进行交互. 我们可继承org.athenasource.framework.eo.web.service.AbstractService类以快速创建Service.</p>
<pre class="java" name="code">
package com.liguoliang.helloworld.service;

import java.util.List;

import org.athenasource.framework.eo.core.EOContext;
import org.athenasource.framework.eo.query.EJBQLSelect;
import org.athenasource.framework.eo.web.service.AbstractService;

public class DeptService extends AbstractService {

	/**
	 * 加载Department列表
	 * @return
	 */
	public List&lt;Object&gt; loadDepts() {
		EOContext eoContext = createEOContext(); // 创建Athena EoContext;

		String strEJBQL = "SELECT dept FROM Department dept"; // 加载所有Department;
		EJBQLSelect select = eoContext.createSelectQuery(strEJBQL);

		return select.getResultList(); // 执行EJBQL, 并返回所有数据;
	}
}</pre>
<p>&nbsp;</p>
<h4>在Service配置文件中声明Service</h4>
<p>为了便于Flex端呼叫Service, 我们需要事先创建eo-services.xml配置文件, 该文件位于: WEB-INFO 根目录下, 该目录下有我们在教程1中介绍的eo-config.xml, flex-services.config.xml文件.</p>
<p>我们需要创一个专门存放Service的xml文件: eo-services.xml, 该文件的样例请参考<a href="http://athenasource.org/flex/basic-tutorial.php?part=3" target="_blank">官方文档</a>, 我们增加刚才创建的DeptService:</p>
<p>&lt;service class=&#8221;com.liguoliang.helloworld.service.DeptService;&#8221; name=&#8221;deptService&#8221; description=&#8221;AthenaFramework HelloWorld&#8221; /&gt;</p>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;">Java端工程目录见文末附图;</span></p>
<p>至此, 我们已经创建并配置好了DeptService, 万事俱备, 只等Flex端来Call了!</p>
<h2>Flex端编程</h2>
<p>在Flex端工程中需要将athena-flx-2.0.0.swc放入labs目录.</p>
<p>将在Application创建完毕后立即初始化EoService, 基于EoService可呼叫Java端定义的Service.</p>
<pre class="java" name="code">			import com.liguoliang.helloworld.Department;

			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
			import mx.events.FlexEvent;

			import org.athenasource.framework.eo.core.EOService;
			import org.athenasource.framework.eo.core.ioc.EOServiceLocator;
			import org.athenasource.framework.eo.remoting.event.EventEOService;
			import org.athenasource.framework.eo.remoting.event.EventRemoteOperationError;
			import org.athenasource.framework.eo.remoting.event.EventRemoteOperationSuccess;

			/** EOService */
			protected var eoService:EOService;

			/**
			 * 创建完毕后响应, 初始化EOService(将会加载Metadata基础数据)
			 */
			protected function onCreationComplete(event:FlexEvent):void {
				// Initialize eoService
				eoService = new EOService("http://localhost:8080/AthenaHelloWorld/messagebroker/amf", "eo", 2, true, onEoServiceEvent);
				// Set Service Locator
				EOServiceLocator.getInstance().eoService = eoService;
			}

			/**
			 * EoService初始化完毕, 如果成功则立即加载Department列表.
			 */
			protected function onEoServiceEvent(event:EventEOService):void {
				if(event.kind == EventEOService.KIND_LOGIN_SUCCESS) {
					trace("Metadata 加载成功");
					loadDepts(); // 加载列表
				}else if(event.kind == EventEOService.KIND_LOGIN_ERROR || event.kind == EventEOService.KIND_META_LOAD_ERROR) {
					Alert.show("ERROR: " + event.errorMessage);
				}
			}

			// 加载Department列表 - EoService已初始化完毕, 在任意位置使用EOServiceLocator.getInstance().eoService即可拿到eoService实例;
			// 使用eoService呼叫Java端创建的Service.
			private function loadDepts():void {
				// 注意首个参数serviceName - 需要与Java端eo-service.xml中配置的Service name相同.
				EOServiceLocator.getInstance().eoService.invokeService("deptService", "loadDepts", [], onLoadDeptsSuccess, onLoadDeptsError);
			}

			// 加载成功后响应.
			private function onLoadDeptsSuccess(e:EventRemoteOperationSuccess):void {
				var deptsAC:ArrayCollection = e.data as ArrayCollection;
				trace("加载到的Dept列表长度: " + deptsAC.length);
				datagirdDepts.dataProvider = deptsAC; // deptsAC中数据为Department类的实例.
			}

			private function onLoadDeptsError(e:EventRemoteOperationError):void {
				Alert.show(e.exceptionDetails, "加载失败!");
			}</pre>
<p>&nbsp;</p>
<h2>启动Java服务器, 运行Flex应用</h2>
<p>枯燥的配置只是为了更简单流畅的开发, 终于到了真正运行的时刻了</p>
<p>(在运行之前, 为了方便演示, 我已在数据库中插入了两条测试记录)</p>
<ol>
<li>启动Java端服务器</li>
<li>运行Flex端应用</li>
</ol>
<p>运行成功:</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image12.png"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb13.png" border="0" alt="image" width="185" height="244" /></a></p>
<h2>服务器端都做了什么? EJBQL被翻译成了什么SQL?</h2>
<p>可通过配置Java端src根目录下log4j.properties文件以查看更多debug信息(如不存在请创建)</p>
<p>[http-8080-1] INFO  uery.EJBQLSelect &#8211; EJBQL: SELECT dept FROM Department dept<br />
[http-8080-1] INFO  uery.EJBQLSelect &#8211; SQL: SELECT dept.department_ID, dept.version, dept.status, dept.ORG_ID, dept.deptName FROM Department dept WHERE dept.status &lt;&gt; 4</p>
<h2>下载本例代码 &amp; 走的更远</h2>
<p>本例代码可通过Google code checkout: http://code.google.com/p/athenahelloworld/</p>
<p>其中包含: Java, Flex工程文件(均不含lib), 数据库sql文件(包含在Java工程中),</p>
<p>可下载Athena framework官方示例程序进一步体验: <a href="http://athenasource.org/flex/basic-tutorial.php">http://athenasource.org/flex/basic-tutorial.php</a></p>
<p>附录: helloworld最终目录结构:</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image13.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb14.png" border="0" alt="image" width="607" height="744" /></a></p>
<p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>基于Athena框架的Flex入门教程(2)配置Entity, 自动生成Java端, Flex端代码</title>
		<link>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-2/</link>
		<comments>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-2/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 07:50:39 +0000</pubDate>
		<dc:creator>Guoliang</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Athena Framework]]></category>
		<category><![CDATA[BlazeDS]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-2/</guid>
		<description><![CDATA[使用Athena Console(控制台)管理数据库, 管理Entity, 生成代码
基于Athena Console可快速创建并管理数据库, 维护数据库结构, 并自动生成代码.
使用Athena Console创建并管理数据库
控制台基于前文所述的eo-config.xml文件运行, 因此启动后应<p class='read-more'><a href='http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-2/'>More...</a></p><p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></description>
			<content:encoded><![CDATA[<h2>使用Athena Console(控制台)管理数据库, 管理Entity, 生成代码</h2>
<p>基于Athena Console可快速创建并管理数据库, 维护数据库结构, 并自动生成代码.</p>
<h4>使用Athena Console创建并管理数据库</h4>
<h4>控制台基于前文所述的eo-config.xml文件运行, 因此启动后应选择配置文件</h4>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb41.png"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image_thumb[4]" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb4_thumb.png" border="0" alt="image_thumb[4]" width="757" height="404" /></a></p>
<p>由于数据库并不存在, 因此&#8221;Check database&#8221;时会提示未知数据库, 此时可点击&#8221;Create database&#8221;自动创建数据库:<br />
&#8220;Creating database: helloWorld &#8230;<br />
Database created successfully.&#8221;</p>
<p>helloWorld数据库被创建, 但没有任何table. 点击&#8221;Initialize database&#8221;, 会自动创建框架用于存储数据库结构的内置Table:</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb61.png"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image_thumb[6]" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb6_thumb.png" border="0" alt="image_thumb[6]" width="635" height="406" /></a></p>
<p>这些Table用于存储MetaData, 如: Entity存储Table信息, attribute存储Table中字段信息, relationship存储entity关系信息(如department.employees)</p>
<p>此时数据库已初始化完毕, 点击控制台上方按钮进行建模:</p>
<p><img src="http://athenasource.org/flex/images/2-get-started/launch-workbench.png" alt="" /></p>
<h4>数据建模 Entity Modeling</h4>
<h4>点击Launch metadata workbench后会自动启动浏览器, 打开基于Flex创建的Metadata管理器. 通过该管理器可快速创建Entity, 配置Entity的Attribute及RelationShip.</h4>
<p><strong>基于Metadata workbench可直接将程序员从数据库处理中解脱处理, 所有操作均在workbench中操作即可达成Table创建, 字段维护等操作.</strong></p>
<p>我们会创建一个Department的Table(Entity), 其中包含有deptName 字段(Attribute)</p>
<p><strong>创建Entity:</strong><a href="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb15.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image_thumb[15]" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb15_thumb.png" border="0" alt="image_thumb[15]" width="606" height="404" /></a></p>
<p>System name将作为Entity生成代码后的Class名称;<br />
Table name指Table名称(该Table会自动创建, 无需手动操作)<br />
Package name配置了代码生成时的Package路径;<br />
Display name为默认的显示名称; i18n name可自动进行i18n国际化.</p>
<p><strong>为Department增加Attribue:</strong></p>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb12.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image_thumb[12]" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb12_thumb.png" border="0" alt="image_thumb[12]" width="584" height="472" /></a></p>
<p>值得一提的是:</p>
<p>System name会作为Java及Flex两端代码的属性名称; 在命名时会禁止使用各数据库的保留字段;<br />
Column type内置几乎所有的类型, 可根据具体数据库自动创建字段;</p>
<p>配置完毕后保存Entity, 返回控制台程序.</p>
<h4>生成代码</h4>
<h4>控制台会根据eo-config.xml配置的代码生成路径, 自动生成Java ActionScript代码:</h4>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb17.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image_thumb[17]" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb17_thumb.png" border="0" alt="image_thumb[17]" width="613" height="229" /></a></p>
<p>代码生成完毕, 刷新Java与Flex工程, 可以看到代码已生成:</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb19.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image_thumb[19]" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb19_thumb.png" border="0" alt="image_thumb[19]" width="592" height="320" /></a></p>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb21.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image_thumb[21]" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb21_thumb.png" border="0" alt="image_thumb[21]" width="589" height="367" /></a></p>
<p>每个Entity会为每种语言自动生成两个Class, 如: Department_EO, Department;</p>
<p>Department_EO:  当metadata有变化, 再次生成代码时, 将会覆盖本类, 因此不建议对本类进行任何手工改动;<br />
Department: 该类继承自: Department_EO仅当第一次生成代码时产生该类, 以后再次生成将不会进行任何覆盖操作; 因此可对重写父类Method或增加其他Method;</p>
<p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>基于Athena框架的Flex入门教程(1) 环境配置</title>
		<link>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-1/</link>
		<comments>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-1/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 07:44:58 +0000</pubDate>
		<dc:creator>Guoliang</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Athena Framework]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[Flex企业级框架]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2011/get-start-with-ahtena-flex-framework/</guid>
		<description><![CDATA[环境搭建
在服务器端, 我们采用MySql数据库;
除了开发必须的IDE, MySql之外, 需要先下载或安装以下文件: <a href="http://athenasource.org/downloads/index.php" target="_blank">下载页面</a>
<ul>
<li>Athena Framework SDK (Java and Flex) 2.0.0 &#8211; 包含Java端及Flex端的SDK及文档
</li><li>Athena Cons</li></ul><p class='read-more'><a href='http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-1/'>More...</a></p><p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></description>
			<content:encoded><![CDATA[<h2>环境搭建</h2>
<p>在服务器端, 我们采用MySql数据库;</p>
<p>除了开发必须的IDE, MySql之外, 需要先下载或安装以下文件: <a href="http://athenasource.org/downloads/index.php" target="_blank">下载页面</a></p>
<ul>
<li>Athena Framework SDK (Java and Flex) 2.0.0 &#8211; 包含Java端及Flex端的SDK及文档
<li>Athena Console 2.0.0 &#8211; 控制台程序, 用于配置Java端数据库及管理Metadata.</li>
</ul>
<p><a href="http://liguoliang.com/wp-content/uploads/2011/04/image4.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 5px 0px 3px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://liguoliang.com/wp-content/uploads/2011/04/image_thumb4.png" width="238" height="221"></a></p>
<p>docs: 存放文档, 与Flex文档类似, 有HTML及PDF;<br />lib: 存放程序运行依赖的jar, 如mysql-connector, BlazeDS等jar包;<br />src: 目录存放程序源代码</p>
<p>athena打头的jar供Java端使用;<br />athena打头的swc供Flex端使用; sdk的具体使用在后文有介绍;</p>
<p>&nbsp;</p>
<h2>服务器端配置</h2>
<h3>创建Java Project</h3>
<ol>
<li>File -&gt; New -&gt; Dynamic Web Project
<li>复制所有jar到PROJECT_ROOT/WebContent/WEB-INF/lib
<li>配置web.xml, 用以启动Athena及BlazeDS服务;
<li>创建两个配置文件: eo-config.xml 与 flex-services.config.xml;<br />eo-config.xml中配置了数据库类型, 数据库连接信息, 以及代码存放位置(供Athena控制台工具使用), 该xml中java-source-local-dir属性为Java src的根目录, flex-source-local-dir为Flex src的根目录(待Flex工程创建完毕后配置); <br />flex-services.config.xml为MessageBrokerServlet(BlazeDS)的配置文件;</li>
</ol>
<p>配置可参见<a href="http://athenasource.org/flex/basic-tutorial.php?part=1">http://athenasource.org/flex/basic-tutorial.php?part=1</a></p>
<p>至此, 服务器端已基本配置完毕;</p>
<h2>Flex端配置</h2>
<p>使用FlashBuilder创建工程:</p>
<p><img src="http://athenasource.org/flex/images/2-get-started/fb-project.png"></p>
<p>注意: server type选择None/Other, 我们使用编程方式链接服务器;</p>
<p>复制src目录地址, 配置到flex-services.config.xml中, 为下一步的代码生成做好准备;</p>
<p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2011/get-start-with-ahtena-flex-framework-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BlazeDS Flex端常用方法总结 及 ResultEvent分析</title>
		<link>http://liguoliang.com/2009/blazeds-flex%e7%ab%af%e5%b8%b8%e7%94%a8%e6%96%b9%e6%b3%95%e6%80%bb%e7%bb%93-%e5%8f%8a-resultevent%e5%88%86%e6%9e%90/</link>
		<comments>http://liguoliang.com/2009/blazeds-flex%e7%ab%af%e5%b8%b8%e7%94%a8%e6%96%b9%e6%b3%95%e6%80%bb%e7%bb%93-%e5%8f%8a-resultevent%e5%88%86%e6%9e%90/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 12:24:54 +0000</pubDate>
		<dc:creator>Guoliang</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[ResultEvent]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2009/02/803/</guid>
		<description><![CDATA[<strong>1 .基本使用:</strong>
	private var op:AbstractOperation;
	public function loadEmployees():void {
		op = AppContext.getRemoteObject().getOperation("loadEmployees");<p class='read-more'><a href='http://liguoliang.com/2009/blazeds-flex%e7%ab%af%e5%b8%b8%e7%94%a8%e6%96%b9%e6%b3%95%e6%80%bb%e7%bb%93-%e5%8f%8a-resultevent%e5%88%86%e6%9e%90/'>More...</a></p><p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></description>
			<content:encoded><![CDATA[<p><strong>1 .基本使用:</strong></p>
<pre class="java">	private var op:AbstractOperation;
	public function loadEmployees():void {
		op = AppContext.getRemoteObject().getOperation("loadEmployees");	//获得Operation
		 op.arguments = [id];	//设定参数
		 var at:AsyncToken = op.send();	//Send
		 at.addResponder(this);	//为本实例增加responder

      }

//---------------------实现 IResponder-------------------------------
	public function result(responderResult:Object):void {
		var resultEvent:ResultEvent = responderResult as ResultEvent;
		var ac:ArrayCollection = resultEvent.result as ArrayCollection;//result为服务器返回的数据
		log.debug("已读取到 " + this + "的职员列表, 职员数目为: " + ac.length);
	}

	public function fault(data:Object):void {
		throw new Error("远程操作失败");
	}</pre>
<p><strong>2. 另外可通过外置Responder实例来响应结果, 同时在实例中dispatch Event, 可实现在当前类中响应服务器端返回数据.</strong></p>
<pre class="java">	//Listener - onButtonDelClicked
	private function onButtonDelClicked(e:MouseEvent):void {
		var op:AbstractOperation = AppContext.getRemoteObject().getOperation("delEmp");
		log.info("Deleteing...");
			 op.arguments = [datagridEmpList.selectedItem as Employee];
			 var at:AsyncToken = op.send();
			 var rs:OperationResponder = new OperationResponder();//增加Responder实例
			 rs.addEventListener(OperationResultEvent.OPERATION_COMPLETE, onOperationSuccess);//监听由Responder派发的Custom Event
			 at.addResponder(rs);//为AsyncToken增加Responder
	}

//-----------------------on RemoteOperationSuccess - SaveNew - UPdate - Delete - load Department- 监听多个操作的Event-----------------
	private function onOperationSuccess(e:OperationResultEvent):void {
		var resultEvent:ResultEvent = e.resultData as ResultEvent;
		var resultEventATMessage:RemotingMessage = resultEvent.token.message as RemotingMessage;
		var operationName:String = resultEventATMessage.operation;
		if(operationName == "saveEmpToDB") {//新建保存
			//....
		}else if(operationName == "updateEmp"){	//更新
			//....
			}
		}else if(operationName == "delEmp") {//删除
			var deletedEmp:Employee = resultEventATMessage.body[0];
			log.info("已成功删除职员: " + deletedEmp.name);
		}else if(operationName == "loadDepartments") {	//加载部门信息
		//...
		}
	}</pre>
<p>OperationResponder类:</p>
<pre class="java">package com.insprise.dept.view
{
/**
 * Select Departments Responder
 */
 [Event(name = "OperationComplete", type="com.insprise.dept.event.OperationResultEvent")]
public class OperationResponder  extends EventDispatcher implements IResponder
{
	public function OperationResponder() {
		super();
	}

	public function result(data:Object):void {
//		var resultEvent:ResultEvent = data as ResultEvent;
//		var ac:ArrayCollection = resultEvent.result as ArrayCollection;
		dispatchEvent(new OperationResultEvent(data));
	}

	public function fault(info:Object):void {
		throw new Error("服务器出错 - 调用服务器端方法失败" +  ErrorMessage);
	}
}//end of class
}//end of package</pre>
<p>OperationResultEvent类:</p>
<pre class="java">package com.insprise.dept.event
{
/**
 * when Operation Success, and it's responder can dispatch this event
 */
public class OperationResultEvent extends Event
{
	public static const OPERATION_COMPLETE:String = "OperationComplete";
	private var _resultData:Object;

	/**
	 * Constructor
	 */
	public function OperationResultEvent(resultData_:Object) {
		super(OPERATION_COMPLETE, false, false);
		_resultData = resultData_;
	}

	/**
	 * Getter
	 */
	 public function get resultData():Object {
	 	return _resultData;
	 }

	/**
	 * Override - MUST
	 */
	 override public function clone():Event {
	 	return new OperationResultEvent(_resultData);
	 }

	/**
	 * OPTIONAL
	 */
	 override public function toString():String {
	 	return formatToString(OPERATION_COMPLETE, "_resultData");
	 }
}//end of class
}//end of package</pre>
<p><strong>3: ResultEvent常用操作:</strong></p>
<p>ResultEvent由AsyncToken的applyResult方法派发, 将该Event传递至Responder的result方法中.</p>
<p>ResultEvent的属性:</p>
<pre class="java">    /**
     * Creates a new ResultEvent.
     * @param type The event type; indicates the action that triggered the event.
     * @param bubbles Specifies whether the event can bubble up the display list hierarchy.
     * @param cancelable Specifies whether the behavior associated with the event can be prevented.
     * @param result Object that holds the actual result of the call.
     * @param token Token that represents the call to the method. Used in the asynchronous completion token pattern.
     * @param message Source Message of the result.
     */
    public function ResultEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = true,
                                result:Object = null, token:AsyncToken = null, message:IMessage = null)
    {
        super(type, bubbles, cancelable, token, message);

        if (message != null &amp;&amp; message.headers != null)
            _statusCode = message.headers[AbstractMessage.STATUS_CODE_HEADER] as int;

        _result = result;
    }</pre>
<p><a href="http://liguoliang.com/wp-content/uploads/2009/02/image11.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="image" src="http://liguoliang.com/wp-content/uploads/2009/02/image-thumb10.png" border="0" alt="image" width="664" height="351" /></a></p>
<p>resultEvent.result存放有当前op返回值, 可通过ObjectUtils.toString(resultEvent.result)来查看其类型及信息</p>
<p>其中token中存放有如下具体信息:</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2009/02/image12.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="image" src="http://liguoliang.com/wp-content/uploads/2009/02/image-thumb11.png" border="0" alt="image" width="656" height="305" /></a></p>
<p><strong>Message中的内容:</p>
<p>body中存放有当前Operation的很多参数, 可使用如下方法调用Message:</strong></p>
<p><strong>var resultEventATMessage:RemotingMessage = resultEvent.token.message as RemotingMessage;</strong></p>
<p><strong>然后可通过resultEventATMessage.operation / desination/body[*]等来调用op/destination名字及op的参数.</strong></p>
<p>在Operation中定义了message的内容:</p>
<p>以下代码来自mx.rpc.remoting.Operaiton</p>
<pre class="java">    override public function send(... args:Array):AsyncToken
    {
        if (!args || (args.length == 0 &amp;&amp; this.arguments))
        {
            if (this.arguments is Array)
            {
                args = this.arguments as Array;
            }
            else
            {
                args = [];
                for (var i:int = 0; i &lt; argumentNames.length; ++i)
                {
                    args[i] = this.arguments[argumentNames[i]];
                }
            }
        }

        var message:RemotingMessage = new RemotingMessage();
        message.operation = name;
        message.body = args;
        message.source = RemoteObject(service).source;

        return invoke(message);
    }

}</pre>
<p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2009/blazeds-flex%e7%ab%af%e5%b8%b8%e7%94%a8%e6%96%b9%e6%b3%95%e6%80%bb%e7%bb%93-%e5%8f%8a-resultevent%e5%88%86%e6%9e%90/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex BlazeDS Java JDBC MySql 快速配置</title>
		<link>http://liguoliang.com/2009/flex-blazeds-java-jdbc-mysql-%e9%80%9f%e9%85%8d%e5%bf%ab%e9%80%9f%e9%85%8d%e7%bd%ae/</link>
		<comments>http://liguoliang.com/2009/flex-blazeds-java-jdbc-mysql-%e9%80%9f%e9%85%8d%e5%bf%ab%e9%80%9f%e9%85%8d%e7%bd%ae/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 08:48:27 +0000</pubDate>
		<dc:creator>Guoliang</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[JDBC]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2009/02/793/</guid>
		<description><![CDATA[从下往上:<a href="http://liguoliang.com/wp-content/uploads/2009/02/image9.png"><img style="display: inline; margin-left: 0px; margin-right: 0px; border-width: 0px;" title="image" src="http://liguoliang.com/wp-content/uploads/2009/02/image-thumb9.png" border="0" alt="image" width="330" height="540" align="right" /></a>
<strong>1. Java – JDBC – MySql</strong>
1. 装好MySql, 启动服务.
2. 将mysql-connector-java-5.1.7-bin.jar 拖入WEB-INF/lib下.
搞定.
<a href="http://liguoliang.com/wp-content/uploads/2009/02/image10.png"></a>
<strong>2. Java端BlazeDS配置</strong>
1. Java端:
将BlazeDS压缩包内的WE<p class='read-more'><a href='http://liguoliang.com/2009/flex-blazeds-java-jdbc-mysql-%e9%80%9f%e9%85%8d%e5%bf%ab%e9%80%9f%e9%85%8d%e7%bd%ae/'>More...</a></p><p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></description>
			<content:encoded><![CDATA[<p>从下往上:<a href="http://liguoliang.com/wp-content/uploads/2009/02/image9.png"><img style="display: inline; margin-left: 0px; margin-right: 0px; border-width: 0px;" title="image" src="http://liguoliang.com/wp-content/uploads/2009/02/image-thumb9.png" border="0" alt="image" width="330" height="540" align="right" /></a></p>
<p><strong>1. Java – JDBC – MySql</strong></p>
<p>1. 装好MySql, 启动服务.</p>
<p>2. 将mysql-connector-java-5.1.7-bin.jar 拖入WEB-INF/lib下.</p>
<p>搞定.</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2009/02/image10.png"></a></p>
<p><strong>2. Java端BlazeDS配置</strong></p>
<p>1. Java端:</p>
<p>将BlazeDS压缩包内的WEB-INF里面的东西拷贝工程内的WEB-INF下的相应位置中.[ Flex目录下有四个xml配置文件, lib下是需要使用的jar] 包括web.xm</p>
<p>2. 配置services-config.xml中channels标签中的内容:</p>
<pre class="xml">

                false

true
4
</pre>
<p>其中, http://localhost:8080/DepartmentManagement/ 是该Web工程的地址 [可在web-content下建立一空index.html, 运行后查看地址便可]</p>
<p>3. 编写Java类, 并配置remoting-config.xml文件的&lt;service&gt;标签下, 增加服务, 如下:</p>
<pre class="xml">

         com.insprise.guoliang.DepartmentManagement
</pre>
<p><strong>3. Flex端建立工程</strong></p>
<p>1. 建立 Flex与Java通信载体RemoteObject</p>
<p>为方便在整个工程中使用, 可建立一个Singleton &#8211; 关于AS中的Singleton可见: <a title="http://liguoliang.com/2008/10/128/" href="http://liguoliang.com/2008/10/128/">http://liguoliang.com/2008/10/128/</a></p>
<p>在该类中建立RemoteObject.</p>
<p>首先需要确定RemoteObject的destination, 在本例中 为&#8221;DepartmentManagement&#8221;; &#8211; 在<strong>remoting-config.xml中已配置.</strong></p>
<p>其次需要确定ro的channel &#8211; 本例中为:&#8221;http://localhost:8080/DepartmentManagement/messagebroker/amf＂； － 在<strong>services-config.xml中已配置</strong></p>
<p>代码:</p>
<pre class="java">	public static const DEFAULT_DEST:String = "DepartmentManagement";
	public static const DEFAULT_CHANNEL_URL:String = "http://localhost:8080/DepartmentManagement/messagebroker/amf";
	private static var _ro:RemoteObject;

	/**
	 * Constractor - Singleton
	 */
	 public function AppContext():void {
	 	throw new Error("AppContext is Singleton!");
	 }

	/**
	 * Get RemoteObject
	 */
	public static function getRemoteObject():RemoteObject {
		if(_ro == null) {
			_ro = createRemoteObject(DEFAULT_DEST, DEFAULT_CHANNEL_URL);
		}
		return _ro;
	}

	/**
	 * Constructs a new remote object with new channel.
	 * @param roDestination Destination of the RemoteObject; should match a destination name in the services-config.xml file.
	 * @param channelURI the URI used to create the whole endpoint URI for this channel; this uri can be relative uri (to the folder containing the SWF).
	 * @param channelId the id of the channel, if set to null, a random Id will be assigned.
	 */
	protected static function createRemoteObject(roDestination:String, channelURI:String, channelId:String = null):RemoteObject {
		var channelSet:ChannelSet = new ChannelSet();
		var channel:AMFChannel = new AMFChannel(channelId == null ? "channel-" : channelId, channelURI);	//Create new Channel
		channelSet.addChannel(channel);	

		var ro:RemoteObject = new RemoteObject(roDestination);
		ro.channelSet = channelSet;

		return ro;
	}</pre>
<p><strong>4 配置完成,.</strong></p>
<p>在Java端建立相关的Class,</p>
<p>启动服务器.</p>
<p>在Flex端通过 Appcontext.getRemoteObject.getOperation(“方法名称”)来调用服务器端方法.</p>
<p>具体实例:</p>
<p><strong>Java端的Class &#8211; 通过JDBC 读取 MySql中数据:</strong></p>
<pre class="java">	/**
	 * Load all Department and return an ArrayList
	 * @return
	 */
	public ArrayList loadDepartments() {
		ArrayList departmentsAL = new ArrayList();
		log.info("Loading Departments...");
		try {
			//Get Connection
			Connection conn = JdbcUtilities.getConnection();
			//Create statement
			String sql = " SELECT * FROM Department d ORDER BY d.Department_ID";
			PreparedStatement ps = conn.prepareStatement(sql);

			ResultSet res = ps.executeQuery();
			log.debug("Exectuing: " + sql);
			while (res.next()) {
				int id = res.getInt("Department_ID");
				String name = res.getString("name");

				Department dp = new Department();
				dp.setId(id);
				dp.setName(name);
				departmentsAL.add(dp);
				log.debug("从数据库获得部门:  " + dp);
			}
			JdbcUtilities.closeConn(res, ps, conn);
			log.info("加载部门信息结束, 共加载部门: " + departmentsAL.size());
		} catch (Exception e) {
			log.error("SQL Error", e);
			throw new Error(e);
		}
		return departmentsAL;

	}</pre>
<p>Flex端的代码:</p>
<pre class="java">		/**
	 * Load the Department's Employee
	 */

	private var op:AbstractOperation;
	public function loadEmployees():void {
		op = AppContext.getRemoteObject().getOperation("loadEmployees");	//获得Operation
		 op.arguments = [id];	//设定参数
		 var at:AsyncToken = op.send();	//Send
		 at.addResponder(this);	//为本实例增加responder

      }</pre>
<p>Flex端responder剩余代码见:http://liguoliang.com/2009/02/777/</p>
<p>运行Flex工程, Flex取得RemoteObject, 然后通过channel建立到destination的连接,由Java读取数据库中信息, 并返回给Flex.</p>
<p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2009/flex-blazeds-java-jdbc-mysql-%e9%80%9f%e9%85%8d%e5%bf%ab%e9%80%9f%e9%85%8d%e7%bd%ae/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Flex端调用Java服务的过程</title>
		<link>http://liguoliang.com/2009/flex%e7%ab%af%e8%b0%83%e7%94%a8java%e6%9c%8d%e5%8a%a1%e7%9a%84%e8%bf%87%e7%a8%8b/</link>
		<comments>http://liguoliang.com/2009/flex%e7%ab%af%e8%b0%83%e7%94%a8java%e6%9c%8d%e5%8a%a1%e7%9a%84%e8%bf%87%e7%a8%8b/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 03:14:35 +0000</pubDate>
		<dc:creator>Guoliang</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2009/02/777/</guid>
		<description><![CDATA[1. get Operation
2. set arguments
3. AddResponder, Send();
如下:

	private var op:AbstractOperation;
	public function loadEmployees():void {
		op = AppC<p class='read-more'><a href='http://liguoliang.com/2009/flex%e7%ab%af%e8%b0%83%e7%94%a8java%e6%9c%8d%e5%8a%a1%e7%9a%84%e8%bf%87%e7%a8%8b/'>More...</a></p><p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></description>
			<content:encoded><![CDATA[<p>1. get Operation</p>
<p>2. set arguments</p>
<p>3. AddResponder, Send();</p>
<p>如下:</p>
<pre class="java" name="code">
	private var op:AbstractOperation;
	public function loadEmployees():void {
		op = AppContext.getRemoteObject().getOperation("loadEmployees");	//获得Operation
		 op.arguments = [id];	//设定参数
		 op.send();
		 var at:AsyncToken = op.send();	//Send
		 at.addResponder(this);	//为本实例增加responder
      }
//使用当前类响应, 则应实现IResponder接口, 要实现两个方法, 如下:
//---------------------Responder-------------------------------
	public function result(responderResult:Object):void {
		var resultEvent:ResultEvent = responderResult as ResultEvent;//转换
		var ac:ArrayCollection = resultEvent.result as ArrayCollection;//获得Result
		log.debug("已读取到 " + this + "的职员列表, 职员数目为: " + ac.length);
	}

	public function fault(data:Object):void {
		throw new Error("远程操作失败");
	}
</pre>
<p>原先的错误方法:</p>
<pre class="java" name="code">
	private var op:AbstractOperation;
	public function loadEmployees():void {
		op = AppContext.getRemoteObject().getOperation("loadEmployees");	//获得Operation
		 op.arguments = [id];	//设定参数
		 op.addEventListener(ResultEvent.RESULT, onSqlResult,false, 0, true);
		 op.send();
		// var at:AsyncToken = op.send();	//Send
		 //at.addResponder(this);	//为本实例增加responder
      }

	private function onSqlResult(e:ResultEvent):void {
		var ac:ArrayCollection = e.result as ArrayCollection;
		for each(var emp:Employee in ac) {
			emp.department = this;
			employeeAC.addItem(emp);
		}
		log.debug("已读取到 " + this + "的职员列表, 职员数目为: " + ac.length);
		op.removeEventListener(ResultEvent.RESULT, onSqlResult);//更错误的方法是没有remove Listener
	}
</pre>
<p>这样导致该方法被呼叫时, op都会被监听, 成功后取消监听, 如果不取消监听, 则会出现如下输出信息:<br />
第一次调用:<br />
[DEBUG] Department 已读取到 Dep1的职员列表, 职员数目为: 2</p>
<p>第二次调用:<br />
[DEBUG] Department 已读取到 Dep1的职员列表, 职员数目为: 2<br />
[DEBUG] Department 已读取到 Dep2的职员列表, 职员数目为: 2</p>
<p>第三次调用:<br />
[DEBUG] Department 已读取到 Dep1的职员列表, 职员数目为: 0<br />
[DEBUG] Department 已读取到 Dep2的职员列表, 职员数目为: 0<br />
[DEBUG] Department 已读取到 Department3的职员列表, 职员数目为: 0</p>
<p>在此情况下, op可视为一类操作, 这样在使用op[他会有很多个实例, 会有很多个对应的监听函数]监听之后, 每个实例的Result的返回都会引发所有实例的Listener运行. 因此会出现上面的状况.</p>
<p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2009/flex%e7%ab%af%e8%b0%83%e7%94%a8java%e6%9c%8d%e5%8a%a1%e7%9a%84%e8%bf%87%e7%a8%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BlazeDS配置实例</title>
		<link>http://liguoliang.com/2008/blazeds%e9%85%8d%e7%bd%ae%e5%ae%9e%e4%be%8b/</link>
		<comments>http://liguoliang.com/2008/blazeds%e9%85%8d%e7%bd%ae%e5%ae%9e%e4%be%8b/#comments</comments>
		<pubDate>Sat, 30 Aug 2008 15:55:52 +0000</pubDate>
		<dc:creator>Guoliang</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://myxju.com/?p=20</guid>
		<description><![CDATA[[小站博客均为原创, 转载请保留以下信息:
作者:<a href="http://liguoliang.com" target="_blank">http://liguoliang.com</a> 欢迎访问:Adobe上海用户组: <a href="http://riashanghai.com " target="_blank">http://riashanghai.com </a>]

1.什么是BlazeDS
BlazeDS is the server-based Java remoting and w<p class='read-more'><a href='http://liguoliang.com/2008/blazeds%e9%85%8d%e7%bd%ae%e5%ae%9e%e4%be%8b/'>More...</a></p><p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></description>
			<content:encoded><![CDATA[<blockquote><p>[小站博客均为原创, 转载请保留以下信息:</p>
<p>作者:<a href="http://liguoliang.com" target="_blank">http://liguoliang.com</a> 欢迎访问:Adobe上海用户组: <a href="http://riashanghai.com " target="_blank">http://riashanghai.com </a>]</p></blockquote>
<div class="content clear-block">
<h3>1.什么是BlazeDS</h3>
<p>BlazeDS is the server-based Java remoting and web messaging technology that enables developers to easily connect to back-end distributed data and push data in real-time to Adobe® Flex® and Adobe AIR™ applications for more responsive rich Internet application (RIA) experiences.</p>
<p>BlazeDS consists of three key services:<br />
1.<span style="text-decoration: underline;">The Remoting Service</span> allows your Flex application to directly invoke methods of Java objects deployed in your application server.<br />
2.<span style="text-decoration: underline;">The Message Service</span> provides a publish/subscribe infrastructure that allows your Flex application to publish messages and subscribe to a messaging destination, enabling the development of real-time data push and collaborative applications.<br />
3.<span style="text-decoration: underline;">The Proxy Service </span>allows your Flex application to make cross-domain service requests in a secure and controlled manner. In other words, it allows your Flex application to access a service available on a different domain than the domain from where the application was downloaded (without having to depl</p>
<p>oy a crossdomain.xml policy file on the target domain).[Christophe Coenraets Adobe <a title="http://www.adobe.com/devnet/livecycle/articles/blazeds_gettingstarted.html" href="http://www.adobe.com/devnet/livecycle/articles/blazeds_gettingstarted.html">http://www.adobe.com/devnet/livecycle/articles/blazeds_gettingstarted.html</a>]</p>
<h3>2.配置BlazeDS,并使之正常运作</h3>
<p>2.1 准备工作<br />
FlexBuilder,Tomcat,Eclipse.<br />
在此之前,你至少需要学会启动或停止Tomcat服务器,并了解它的一些大致情况,同时你需要学会编写一个简单的java类,并编译它.<br />
BlazeDS:<br />
BlazeDS首页:<a title="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS" href="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS">http://opensource.adobe.com/wiki/display/blazeds/BlazeDS</a>,有关于BlazeDS的详细介绍与相关文档,下载地址.<br />
BlazeDS下载地址:<a title="http://download.macromedia.com/pub/opensource/blazeds/blazeds_turnkey_3-0-0-544.zip" href="http://download.macromedia.com/pub/opensource/blazeds/blazeds_turnkey_3-0-0-544.zip">http://download.macromedia.com/pub/opensource/blazeds/blazeds_turnkey_3-0-0-544.zip</a><br />
BlazeDS开发指南下载地址:<a title="http://livedocs.adobe.com/blazeds/1/blazeds_devguide/blazeds_devguide.pdf" href="http://livedocs.adobe.com/blazeds/1/blazeds_devguide/blazeds_devguide.pdf">http://livedocs.adobe.com/blazeds/1/blazeds_devguide/blazeds_devguide.pdf</a><br />
2.2 配置BlazeDS<br />
将zip包内的blazeds.war文件解压到应用服务器的部署目录下,如:[tomcat-home]\webapps.<br />
<span style="text-decoration: underline;">重启Tomcat</span><br />
简要介绍下blazeds文件夹:<br />
\WEB-INF配置文件包,内有:<br />
\classes      用来放置Flex应用程序需要使用到的Java class<br />
\flex           有四个XML格式的配置文件,现在我们只需要了解remoting-config.xml,在该文件中添加destination来配置Flex应用程序 与Java class的连接,通过这个文件,架起Flex程序与Java Class之间的桥梁.</p>
<p>3.测试<br />
3.1创建一个新的Java项目来配置BlazeDS，向web应用中添加Java类。</p>
<p>在Eclipse中创建新工程,选择从现有资源中创建,命名为“HelloWorld_server” ，使用先前部署的BlazeDS.WAR的WEB_INF文件夹路径，如:[tomcat-home]\webapps\blazeds\WEB-INF \,在build路径下添加src目录 ,将WEB-INF/classes目录作为输出目录,创建一个名为HelloWorld.java的新Java类，类的定义为：</p>
<div class="dp-highlighter">
<ol class="dp-j">
<li class="alt"><span><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> HelloWorld { </span></span></li>
<li><span><span class="keyword">public</span><span> String sayHello(String name) { </span></span></li>
<li class="alt"><span><span class="keyword">return</span><span> </span><span class="string">&#8220;hello, &#8221;</span><span> + name; </span></span></li>
<li><span>} </span></li>
<li class="alt"><span>} </span></li>
</ol>
</div>
<pre class="java" style="display: none;">public class HelloWorld {
public String sayHello(String name) {
return "hello, " + name;
}
}</pre>
<p>如果你不太熟悉这一步操作,也可以手工编写该java文件,使用javac命令编译为java class文件.<br />
但不论如何,产生的HelloWorld.class必须在WEB-INF/classes目录中.</p>
<p>3.2配置BlazeDS</p>
<p>配置BlazeDS，使它支持Flex与Java进行远程通信。配置WEB-INF/flex文件夹下的config.xml文件,具体配置可参照如下代码：</p>
<div class="dp-highlighter">
<ol class="dp-xml">
<li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">destination</span><span> </span><span class="attribute">id</span><span>=</span><span class="attribute-value">&#8220;HelloWorld&#8221;</span><span class="tag">&gt;</span><span> </span></span></li>
<li><span> <span class="tag">&lt;</span><span class="tag-name">properties</span><span class="tag">&gt;</span><span> </span></span></li>
<li class="alt"><span> <span class="tag">&lt;</span><span class="tag-name">source</span><span class="tag">&gt;</span><span>HelloWorld</span><span class="tag">&lt;/</span><span class="tag-name">source</span><span class="tag">&gt;</span><span> </span></span></li>
<li><span> <span class="tag">&lt;/</span><span class="tag-name">properties</span><span class="tag">&gt;</span><span> </span></span></li>
<li class="alt"><span><span class="tag">&lt;/</span><span class="tag-name">destination</span><span class="tag">&gt;</span><span> </span></span></li>
</ol>
</div>
<pre class="xml" style="display: none;">		HelloWorld</pre>
<pre>重新启动Tomcat;</pre>
<h3>3.3新建一个Flex应用程序,测试连接</h3>
<p>创建一个新Flex项目,将项目命名为“HelloWorld_client”，应用服务器类型则选择“J2EE” ,ProjectLocation指用于存放工程文件的目录,指定为你想存放的位置即可.</p>
<p>选择“Use remote object access service”和LiveCycle Data Services</p>
<p>Next:</p>
<p><a href="http://riashanghai.com/sites/default/files/image_6.png"><img style="border: 0pt none;" src="http://riashanghai.com/sites/default/files/image_6.png" border="0" alt="image" /></a></p>
<p>将根ULR声明为：<a href="http://localhost:8080/blazeds">http://localhost:8080/blazeds</a>（端口号由应用服务器配置决定）</p>
<p>在Tomcat运行的情况下,检查配置的结果应为:The web root folder and root URL are valid.</p>
<p>确定配置并点击“完成”</p>
<p>将HelloWorld_client.mxml修改为如下:</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><a onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;" href="http://riashanghai.com/node/33#">view plain</a><a onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://riashanghai.com/node/33#">copy to clipboard</a><a onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;" href="http://riashanghai.com/node/33#">print</a><a onclick="dp.sh.Toolbar.Command('About',this);return false;" href="http://riashanghai.com/node/33#">?</a></div>
</div>
<ol class="dp-xml">
<li class="alt"><span><span class="tag">&lt;?</span><span class="tag-name">xml</span><span> </span><span class="attribute">version</span><span>=</span><span class="attribute-value">&#8220;1.0&#8243;</span><span> </span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">&#8220;utf-8&#8243;</span><span class="tag">?&gt;</span><span> </span></span></li>
<li><span> <span class="tag">&lt;</span><span class="tag-name">mx:application</span><span> </span><span class="attribute">xmlns:mx</span><span>=</span><span class="attribute-value">&#8220;http://www.adobe.com/2006/mxml&#8221;</span><span class="tag">&gt;</span><span> </span></span></li>
<li class="alt"><span> <span class="tag">&lt;</span><span class="tag-name">mx:remoteobject</span><span> </span><span class="attribute">id</span><span>=</span><span class="attribute-value">&#8220;ro&#8221;</span><span> </span><span class="attribute">destination</span><span>=</span><span class="attribute-value">&#8220;HelloWorld&#8221;</span><span class="tag">&gt;</span><span> </span></span></li>
<li><span> <span class="tag">&lt;</span><span class="tag-name">mx:textinput</span><span> </span><span class="attribute">id</span><span>=</span><span class="attribute-value">&#8220;n&#8221;</span><span> </span><span class="attribute">change</span><span>=</span><span class="attribute-value">&#8220;ro.sayHello(n.text)&#8221;</span><span class="tag">&gt;</span><span> </span></span></li>
<li class="alt"><span> <span class="tag">&lt;</span><span class="tag-name">mx:label</span><span> </span><span class="attribute">text</span><span>=</span><span class="attribute-value">&#8220;{ro.sayHello.lastResult}&#8221;</span><span class="tag">&gt;</span><span> </span></span></li>
<li><span> <span class="tag">&lt;/</span><span class="tag-name">mx:label</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">mx:textinput</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">mx:remoteobject</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">mx:application</span><span class="tag">&gt;</span><span> </span></span></li>
</ol>
</div>
<pre class="xml" style="display: none;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</pre>
<p>运行该应用，在文本框中输入内容，随着文本框内容改变,显示的内容也随着改变.如下图：</p>
<p><a href="http://riashanghai.com/sites/default/files/image_8.png"><img style="border: 0pt none;" src="http://riashanghai.com/sites/default/files/image_8.png" border="0" alt="image" /></a></p>
<p>解说:</p>
<p>该Flex应用使用RemoteObject来与服务器通信。当用户在文本框中输入内容时,文本框的触发并广播 change事件,从而通过已配置的RemoteObject向服务器发出请求。服务器向已经配置的的远程Java类发送请求，返回 “Hello,”+发送值的字符串。在对象返回值的时候，这个返回值会系列化到AMF中，进而返回给Flex应用。RemoteObject将该值赋值给 ro.lastResult,该过程完成后,Label通过RemoteObject上的result事件获得Hello riashanghai.com,并打印出来.</p>
<h3>4.实际应用</h3>
<p>在之前发布的<a href="http://riashanghai.com/node/27" target="_blank">&lt;完整Flex程序+详细解释之便条管理系统(Tree/回溯/XML/Event) Annotated Flex Sample Application: Note Management&gt;</a>中,我们简要的介绍了将数据存储于SharedObejct中的简单便条管理系统,现在我们开始着手开发存储与服务器端的应用.</p>
<p>简要描述:通过分析,只需要修改先前程序的loadXML与SaveXML两个函数即可实现存储于服务器端.</p>
<p>简单起见,服务器端仍旧使用XML存储数据.</p>
<p>在server端,编写一个xmlserver类,该类将实现loadxml与savexml的功能.</p>
<p>在client端,使用RemoteObject与Java进行通信.</p></div>
<p><p>

----------Post from: <a href="http://liguoliang.com">@LiGuoliang.com, 欢迎回来~</a>----------</p></p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2008/blazeds%e9%85%8d%e7%bd%ae%e5%ae%9e%e4%be%8b/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

