整合Macromedia Flex和Java

elevenxl發表於2008-02-27
 現今我們用J2.EE 伺服器開發網際網路應用,通常包括一個表示層譬如Struts, Tapestry, WebWork, or Spring。 這些工具一般按照Model-View-Controller (MVC)結構並以HTML的形式輸出 到瀏覽器。 Web開發典型的程式設計模式是允許使用者在應用中為每一次action向一個應用伺服器釋出請求。 為每次action使用者 發出請求, 伺服器會生成一個新的應答,這個應答允許使用者為了更多資訊遞交一個新請求。 瀏覽器一般被用作提交給使用者的使用者介面。 但是, 瀏覽器是瘦客戶機,它有影響擴充套件和終端使用者體驗的侷限性。

Rich Internet Application (RIA) 技術的湧現解決了表示層的限制。 這篇文章實實在在地介紹了什麼是RIA,怎麼把RIA 整合到你自己的系統結構中去。 並且將識別當跟一些現在普遍的公開的框架結合時所存在的潛在的挑戰。

版權宣告:任何獲得Matrix授權的網站,轉載時請務必保留以下作者資訊和連結
作者:Mark Eagle;molecule
原文:http://www.onjava.com/pub/a/onjava/2004/12/01/flexjava.html
譯文:http://www.matrix.org.cn/resource/article/44/44195_Macromedia+Flex+Java.html
關鍵字:Macromedia;Flex;Java

瀏覽器的侷限性

那麼當前的解決方法有什麼問題嗎?如果應用程式運轉正確且允許使用者是有生產力的,那麼可能沒什麼錯誤。但是曾經有很多web開發員抱怨當使用瀏覽器作為客戶機時會限制效能。 這是一些當前開發web應用程式時遇到的問題:

1.瀏覽器以不一致的方式解釋scripting 語言, 譬如Java 語言。 這迫使開發員多次寫同樣的程式碼來調節各個瀏覽器。
2.簡單使用者介面會影響到譬如選中, 基於嚮導的表單, 和大表格資料集的處理,這使得在瀏覽器上需要更多額外的程式碼。
3.HTML 是有限的,靜態的標記語言是無法是擴充套件的。
4. 在使用者介面之內進行事件處理可能是富挑戰性的。 因為被反饋的HTML 頁一次只能被顯示一頁, 而事件沒有回到伺服器之前又是無法更新其它頁的。
5. 只能通過Cookie來達到連續的應用狀態,Cookie它是不支援物件的。
6.使用瀏覽器開發偶爾連線的客戶機幾乎是不可能。

很多Web開發員都知道這個事實: 當前工具設定有侷限性。當在瀏覽器上工作時開發員必須查詢解決方法。 對於開發員和使用者來說用一臺瘦客戶機是承受不了當前的效能的。

Rich Internet Applications

為 了克服這些侷限性, 考慮用RIA來開發。 如今RIA給使用者一臺胖客戶機來擴充套件瀏覽器所承受不了的效能。 最普遍應用的J2.EE 的RIA 客戶機是Java 和Flash。 當開發大型的資料中心的應用程式時, RIAs 真的是很強的。開發RIA的幾個可行方法是JDNC (JDesktop Network Components), Laszlo, Thinlet, Java Web Start, 和Macromedia Flex。
RIA能解決問題前面已經說過了。 下面是RIAs的一些特徵:
1.        RIAs提供了和瀏覽器一樣的UI元件, 而且它還提供新的本地的更加豐富的元件。 比如包括一個數字步進, 滑動控制, 一個軸向資料網格要素和選單欄。
2.        成熟的RIA應用允許佈局管理器由如下構成,譬如製表符瀏覽器, 摺疊,樹結構和其它能和AWT and Swing開發相媲美的佈局控制。
3.        RIAs 提供拖放能力。
4.        RIA 裡的語言是一致的,它貫穿於所有客戶機, 不必為不同的實施而重寫。
5.         在使用者介面,不必每個action都是請求/回應模式。通過富網際網路應用,使用者與UI 相互對話,如果需要也只需要向伺服器發出請求。 RIAs 會運用HTTP 協議方法把資料提交給應用伺服器。但是, 通常更好的用RIAs的機制是遠端, 它會根據RIA 來支援不同的方式。RIAs提供擴充套件的與HTTP進行通訊的協議。
6.        事件處理橫跨多個元件是可能的。
7.        RIAs 允許您不使用HttpSession就可以在客戶機儲存更多資訊。 這減少了在應用伺服器裡所佔的記憶體。
8.        狀態的連續廣播, 通常是以物件的形式,它提供了建立偶爾連線的客戶機的可能性。

RIA 是相當新的技術,它介紹了開發時涉及到的應用。 它不能解決所有應用, 它是要依賴某種實現。 但是, 如果您認為您的應用可受益於一個更加富有的UI 設計, 那麼RIA 也許就可以為您服務。 本文現在將集中於一個RIA 解決方法, Macromedia Flex, 並且集中討論一下。

Macromedia Flex

Macromedia Flex是RIA的一臺商業表示層伺服器。因為這是Flex applications.用的環境,所以必需要安裝Flash外掛。 多數瀏覽器已經裝備了Flash外掛,對於RIA來說這也有助於正當使用Flex。 我們來討論一下不用Java 外掛而使用Flash外掛來與J2.EE 應用伺服器通話的意義所在。

開發員使用二個核心語言建立Flex應用。 第一核心語言是MXML, 即Macromedia Flex Markup Language,它擁有一套豐富的XML 標籤,這些標籤允許開發員設計使用者介面。 MXML 也可以被認為是XUL, 或XML UI 語言。不同於HTML,這些標籤是可以擴充套件的, 它擁有應用程式所需要的額外能力。 其他MXML 結構可以被叫做遠端物件, 在model中儲存返回的資料, 並且對MXML 構件可以自定義您自己的感觀。

第二個Flex開發核心語言是ActionScript 2.0, 它是一個ECMA 支援的語言,與JavaScript 語言類似。 ActionScript 原理是被編碼在MXML 頁裡面的。 這是較強的物件導向的語言,這對於java開發者來說是比較熟悉的。 ActionScript 而且有很大的事件處理能力,它允許應用程式回應動態使用者互動。 由於ActionScript 執行在Flash外掛裡面,所以它不同於在瀏覽器裡進行JavaScript編碼,不需要重寫幾個同樣編碼的版本來支援不同的瀏覽器。MXML 和ActionScript 是基於文字的語言, 可以寫在一個簡單文字編輯器或 一個IDE 工具譬如Eclipse, 或一個更加老練的工具象由Macromedia 公司的Flex Builder裡。 如果您接觸過Java, XML, 和scripting 語言譬如JavaScript 語言的話, 那麼您在學習Flex時就要稍微轉下彎了。

Flex伺服器負責把MXML 和ActionScript 元件轉換成以.SWF 檔案的形式的Flash位元組碼。這個過程類似於用Java Web應用容器把JSP 檔案編譯成servlets。在Flash執行環境下,SWF 檔案被執行在客戶機裡。 Flex伺服器提供其它服務譬如快取, 併發, 和處理遠端物件請求。

給您現有的結構介紹一個RIA 框架

現 在你對RIA 概念的已經有些瞭解了, 讓我們看看怎麼把RIA 引入到您現有的結構中去。 其中我們也將著重論述怎樣把RIA表現在一個層狀應用中。 此外, 也會講到當用Flex與一些普遍的公開的框架的結合開發時存在的一些潛在的問題。 這些例項將有助於引入RIA 到您的結構中去。

就讓我們先由辨認層狀結構開始。一個結構可能包括以下幾層: 表示層, 業務代表層,業務綜合服務層, 和持久層。 這是各自層的基本實現:

Flex + Business Delegates + Spring Framework + Hibernate

接下去的內容將集中講解每一層。

我現有的MVC 表示層是怎麼樣的?

在Web 應用程式中表示層是用來給使用者傳遞使用者介面, 處理後端服務請求, 並且儲存資訊資料模型用的。對剛接觸RIA的開發員最初可能會傾向於重新使用現有的Struts。 但是, 象Flex這些開發產品都提供了他們自己的MVC 結構。 難道您真地需要維護一個包括二個MVC 結構的表示層嗎?

以下是當Flex客戶機通過Struts元件向Java 伺服器作出請求時的例項。在被更高層接收之前,Flex客戶機的請求會先被髮送到Struts表示框架。 圖1 顯示了哪些是不做的:




圖1 。怎樣不整合Flex and Struts和其它Java元件。

表 示框架譬如Struts是由HTTP傳送HTML 請求來執行的。 當用Flex客戶機來使用HTTP 協議時, 開發員就會出於對效能和麵向物件的優點考慮,通過HTTP來使用遠端物件而反對提交請求的方式。 所以, 有序化的使用這兩個表示框架會提供協議配錯。 除非您有特定需要直接地用RIA來整合Strut ,這樣才可以避免。 圖2 顯示一個當使用Flex 和 Struts時更好的解決方法




圖2 。 介紹Flex 和 Struts與其它Java 元件

圖2 建議怎麼安排分離的Flex元件 和 Struts元件共存。 但這是有條件的,這需要在當應用程式請求並行RIA 元件和輕量Struts元件的時候。

開發員應該運用RIA 客戶機來做點什麼。對於那些熟悉頁面請求應答模式的傳統Web開發員來說,這是一個明確的思想上的轉變。象Flex這樣的RIA 產品並非像Struts一樣是請求或回應驅動。 RIA 客戶機負責在任何情況下更新UI而不必回到伺服器。
當使用RIA時Struts不只是您唯一想的事了。 熟悉這型別技術需要時間。 在經歷這些曲折以後, 最大的問題是Java伺服器端元件的綜合化。 這也並非是針對RIA概念。

Flex與業務層整合

前面我們已經討論了一些表示層相關的,下面我們討論其它層在我們的應用結構是怎麼受影響的。我們已經重置了我們的表示層元件; 我們怎麼把它與業務層整合在一起呢?

Flex 是一個可擴充套件的RIA 框架,它提供了很多方式與您的J2.EE 元件通訊。Flex提供了HTTP 通訊,全球資訊網服務通訊,還有Macromedia 的私有的AMF (ActionScript 傳訊格式化) 閘道器。AMF 閘道器是一個高效能二進位制協議,它近似於Flash remoting協議。遠端物件運用HTTP 協議被髮送到AMF 閘道器。Flex為每個這些通訊協議提供MXML 標籤, 這樣一來極大的減少編制程式複雜度。 此外, Flex允許您以或非同步或同步方式對您的企業等級啟用遠端呼叫。 通過使用一種非同步遠端購買權, 使用者就能夠對客戶機進行一些操作並且即使當發生在傳統全球資訊網應用中時也不被攔截。 您能阻攔使用者與使用同步呼叫的UI交涉。

讓我們來 考慮一下怎麼讓Flex和我們的業務綜合化層整合呢。 為這我們將使用Spring框架作為我們的綜合化層, 但這對您選擇實施什麼綜合化層並沒有限制。讓我們假設一下您有您的服務執行在Spring microcontainer裡, 並且您需要由Flex呼叫遠端物件。

因為Flex對Spring完全不瞭解,您也許可以考慮新增一個separate, 即一個薄層作為代表您的service components。 並且, 因為Spring對Java介面起到了很大作用,所以我們可以建立一個代表物件,這個代表物件實施著和Spring服務一樣的Java 介面。 這些代表物件將提供一個減弱了的閘道器,它從Flex和綜合化層中分離。 您需要做的唯一的事是在Flex配置檔案中配置這些物件因此他們能與AMF 閘道器共同操作。 這裡有一個例項將說明代表物件是怎樣被配置在server-side flex-config.xml Flex配置檔案裡的:

<object name="OrderBusinessDelegate">
   <source>
      com.meagle.flexro.FlexBusinessDelegate
   </source>
   <type>stateless-class</type>
   <use-custom-authentication>
      true
   </use-custom-authentication>
   <allow-unnamed-access>
      false
   </allow-unnamed-access>
   <roles>
      <role>OrderUser</role>
      <role>Admin</role>
   </roles>
</object>


初 看Flex你會發現它一些有附加能力,類似於像設定安全性啦,決定委派物件是否申明啦。當Flex發一個遠端的物件呼叫到內層時,它將會干擾一個Flex 的委派Java物件.委派物件將會負責對呼叫內層或者服務層 (比如Spring).作為結果的物件將通過AMF閘道器返回到Flex客戶端,這個物件被稱為ActionScript物件.這裡是一個MXML程式碼的例 子, Flex客戶端用MXML程式碼來遠端呼叫並將結果儲存到一個資料模式中.

<mx:RemoteObject id="soapro"
   named="OrderBusinessDelegate"
   protocol="https"
   showBusyCursor="true">
   <mx:method name="saveNewOrder"
              result="saveNewOrder_result(event)"
              fault="faultHandler(event.fault)"/>
   <mx:method name="findOrderById"
              result="findOrderById_result(event)"
              fault="faultHandler(event.fault)"/>
   <mx:method name="updateOrder"
              result="updateOrder_result(event)"
              fault="faultHandler(event.fault)"/>
</mx:RemoteObject>

<mx:Model id="roModel" >
   <!-- The object graph for the Order object
           will be stored here -->
   <Order/>
</mx:Model>


用ActionScript equivalents寫的Java的域物件在AMF閘道器裡來回傳遞。這個過程開始於一個請求,這個請求是從Flex伺服器通過AMF閘道器到應用程式的其 他層。一個返回物件的圖,將會被通過其他Java層,最後通過一個AMF閘道器返回到伺服器。一旦這個物件通過閘道器他們就將被轉變為 ActionScript equivalents。圖3詳細說明了這一過程:




圖3. Overview of the AMF gateway.

更 多關於在Flex 和Java tier之間的來回傳遞物件的說明是: 因為ActionScript 2.0 是一種物件導向的語言, 它是可能生成有Java equivalents的ActionScript 物件的。這使在AMF閘道器之間來回地傳遞物件變得比較容易和一致。被送回到Flash 外掛的 ActionScript 物件類似資料傳送物件(DTO) 。這是必要的因為這個Flash 外掛沒有任何Java 執行時間構成要素。下面是一個用Java寫成的一個Order domain object的一個熟悉例子:

package com.meagle.bo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* This object represents an order.
* @hibernate.class table="TestOrder"
* @author meagle
*/
public class Order {
   private int id;
   private double total;
   private int version;
   private String userName;
   private List orderLineItems = new ArrayList();

  // other fields and getter/setter methods not
  // shown to save space
}
Here is the ActionScript equivalent:

/**
* Generated Action Script Object
* for com.meagle.bo.Order. Do not edit!
*/
class com.meagle.bo.Order extends Object {

   public function Order(){}

   public static var regClass =
      Object.registerClass("com.meagle.bo.Order",
                            com.meagle.bo.Order);

   var id : Number;
   var orderLineItems : Array = new Array();
   var total : Number;
   var userName : String;
   var version : Number;

   // other fields and getter/setter methods not
   //shown to save space
}


在ActionScript Order物件裡你應該注意Object.registerClass這個特別方法。AMF 閘道器用這個Object.registerClass  方法在Java 和 ActionScript之間來拆整物件。這個方法把客戶端的ActionScript 類註冊到對伺服器端的Java 類。因 為這些物件是很相似的,所以你在一個稍微不同的格式裡不想重寫你的域物件也是可理解的。像XDoclet 和螞蟻之類的工具允許你自動地產生這 些ActionScript  物件而不是手動地編碼。現在你能像在Flex客戶裡的ActionScript equivalents操作你的Java物件了

Flex與持久層整合

在 使用一個在web上定義好的耦合的體系結構的應用程式中,你不直接和你的持久層對話。使用Flex不應該改變這個體系結構。在大部分情況下,整合層將代替 你和你的持久層對話。通常是使用Data Access Object (DAO)來完成的. Data Access Object (DAO) 是用來連線諸如資料庫的永久儲存的資料的。Flex客戶端不直接訪問整合層甚至不直接瞭解這個層,因為它構築了一個緊密的聯結。讓我們用 Hibernate來作為持久層的一個例子。

當在Macromedia's AMF gateway環境下使用Hibernate和遠端物件時,會有一對錯誤。Hibernate使用者知道你不能訪問一個不含有已初始化Hibernate會 話物件的集合。訪問一個沒有被初始化的動態代理物件的集合會導致執行時錯誤。The AMF 閘道器不知道如何特定的去尋找Hibernate動態代理物件。一個潛在的方法是面向方面的程式設計(AOP)。即將一個即將傳送給AMF閘道器的物件作為委代對 象,移除動態代理。這是一個包含傳遞結果物件給攔截器,反覆尋找使用對映並沒有被初始化的代理物件的過程。如果找到什麼無用的代理物件或集合,將他們設定 為null。這是一個cross-cutting關注,可以作為一個方面,進而使用AOP語言,比如JBoss AOP, AspectJ, Spring AOP等等。AOP攔截器應該被應用於業務代理層的物件。

圖4顯示的一個應用架構:




圖4在代理物件傳入AMF閘道器之前介紹了AOP攔截器 這進一步在高層減少了重複元件,比如整合層,持久層等等。
值 得慶幸的是AMF閘道器不知道快取雙向物件,所以無限的遞迴迴圈不會在傳送物件時發生。因此,在AMF閘道器上互相傳遞物件時,你可以完全保持這種關係。同 時,因為物件是非連線的,並且會有拷貝,你需要使用Session.saveOrUpdateCopy(Object object)方法去儲存一個物件。這個方法必須使用,因為被傳回到AMF閘道器的物件不會在位元組碼資訊上加入對Hibernate有益的資訊。

驗證

典 型的J2EE web應用程式有許多種身份驗證模式。它有可能是基於容器的身份驗證模式,或者是一些自定義密碼的使用者驗證。像Flex之類的RIA 伺服器允許你在大多數的應用程式伺服器上使用Flash客戶端的自定義身份驗證格式和基於容器的身份驗證。此外,如果你看一看上面的業務授權結構的例子的 話,你會發現,為了安全起見你可以分配任務給這些物件。甚至在AMF閘道器中還有很多異常分支,允許開發者們獲取HttpRequest、 HttpResponse和ServletConfig物件來改進您想使用的、帶有授權物件的安全性。

總結

這 篇論文引入了一些概念,目的是為了讓您瞭解當您使用諸如Flex之類的RIA時的權衡和潛在的缺陷。不論你使用的是Flex還是其它的RIA工具,在構築 應用程式的時候都會考慮最重要的是什麼。當評估一個RIA框架時,要確定它有足夠的可擴充性來對應應用程式的需求。此外,在RIA和Java之間傳送物件 時,需要注意要謹慎的構築綜合性的問題。



注:以上內容來自網路,本人不承擔任何連帶責任
文章轉自:http://www.jspcn.net/htmlnews/11500197164681199.html

相關文章