EBS OAF 頁面的技術剖析(2)

(版權聲明,本人原創或者翻譯的文章如需轉載,如轉載用於個人學習,請註明出處;否則請與本人聯繫,違者必究)

原文來自於OAF開發文檔

OADBTransaction

圖5:基礎模型架構-OADBTransaction


注意:要完全的精確和兼容,這個圖應該包含實現類oracle.apps.fnd.framework.server.OADBTransactionImpl而不是oracle.apps.fnd.framework.OADBTransaction接口,儘管如此,我們選擇稍後再包含它因爲你只在你的代碼中使用這個接口。

就像上面圖中展示的,OADBTransaction在你的模型代碼扮演了中心角色,因爲它封裝了關聯根應用模塊的JDBC連接/數據庫會話,並且直接擁有所有你創建的實體對象(你的由根應用模塊擁有的視圖對象,在他們視圖行上持有的是它們實體對象的引用)。你也會在你的模型代碼中爲下面的通常行爲正常使用OADBTransaction:

l  創建一個可調用的語句來執行PL/SQL方法或程序。

l  訪問會話級別應用上下文信息比如用戶名,ID,當前職責等等。

l  如果你需要進行NLS操作比如把服務器日期/時間轉換爲用戶日期/時間等等,可以訪問oracle.apps.fnd.framework.OANLSServices對象。

對OADBTransaction的訪問是由根應用模塊所提供的。

界面視圖

界面視圖格式化並展示模型數據給用戶。

第三章的實現界面視圖裏詳細介紹了下面的內容。

定義頁面

在開發期間,你可以使用聲明式JDeveloper工具爲每個頁面指明bean的層次結構,JDeveloper在Building “Hello, World”裏有介紹。在Oracle E-Buisness Suite開發中,你會使用(源控制)XML文件來進行頁面定義。當你的產品部署到一個客戶的站點時,OAF框架會在數據庫存儲之外運行這些頁面定義。

簡介概括來說,你可以使用JDeveloper來定義由區域和items組成的頁面.

l  Items是簡單的小部件就像按鈕,字段,圖像等等不包含子控件的小控件。

l  區域是容器對象,它可以包含items和其它的區域。區域是示例比如headers, tables和特殊的佈局組件。

l  每個你定義的區域和Item都有一個style屬性,它會告訴OAF框架如何在運行時怎麼去實例化這個web bean(這個也表明了爲這個bean要生成什麼HTML)。比如,如果你定義了一個區域它的style屬性爲”table”,那麼OAF會實例化一個oracle.apps.fnd.framework.webui.beans.table.OATableBean對象。

l  所有的頁面必須有一個頂層的區域(一般稱爲”根區域”),它的style爲pageLayout,會被實例化爲oracle.apps.fnd.framework.webui.beans.layout.OAPageLayoutBean對象。

l  在JDeveloper頁面樹(和相應的XML文件)中區域和items的順序會告訴OAF框架把這些對象加到運行時bean組織層次中哪個地方。

下面的圖6給了一個實例化的示例頁面的各種web beans的幕後外觀。你看的的標籤是後面的web beans的名稱。比如,一個彈出式列表實例化爲oracle.apps.fnd.framework.webui.beans.message.OAMessageChoiceBean,一個提交按鈕實例化爲oracle.apps.fnd.framework.webui.beans.form.OASubmitButtonBean.

圖7展示了相應的頁面定義。

圖6:UI組件頁面展示了相應web beans的名稱


注意:下面顯示的區域和item名稱不符合Oracle EBS命名標準;反而,它們是用於幫助你解釋相應的結構到相應的web beans.

圖7:JDeveloper中頁面結構


屬性集

每個區域或者item都可以使用屬性集來繼承屬性組的設置。一個屬性集時一個命名的,可重用的屬性集合,它可以別任何類型的UI對象屬性,包括區域,item和其它的屬性集。每當你建立了一個使用了屬性集的UI,你可以覆蓋繼承的屬性(雖然在OAF編程標準中是不鼓勵的)。

要演示這個概念,在應用開發中,每個表必須爲每個顯示列關聯屬性集。這些屬性集包含提示,顯示寬度等等屬性。

l  在OAF ToolBox Sample Library/Tutorial中,有一個採購訂單表(FWK_TBX_PO_HEADERS),其主鍵列類型爲NUMBER且名爲HEADER_ID,它也作爲採購訂單號顯示給用戶。

l  這個表有一個叫做關聯的FwkTbxPoHeaders屬性集XML包文件,它包含了表中所有顯示列的屬性集(每個列都有一個屬性集)。其中之一的屬性集叫做HeaderId

HeaderId屬性集有一個Prmpt屬性設置爲Order Number並且顯示長度設置爲合理的15.

l  當你創建一個包含採購訂單編碼Item的頁面時,我們可以設置它的屬性集屬性爲完全合適的名爲/oracle/apps/fnd/framework/toolbox/attributesets/FwkTbxPoheaders/Headerid的屬性集。

圖8:在JDeveloper中使用一個屬性集


組件重用

組件重用

如果你想包含共享對象到你的頁面中,你可以簡單繼承它們。

比如,在OAFToolBox Sample Library/Tutorial中,我們創建了一個通用區域(名爲PoSummaryRN),因此同樣的內容不需要編碼就可以包含在多個頁面中。要加一個共享區域到一個頁面,我們只需要簡單創建一個新的區域,然後設置它的Extends屬性爲共享區域的符合條件的全名稱: /oracle/apps/fnd/framework/toolbox/tutorial/webui/PoSummaryRN

注意:在引用頁面,共享區域是不可以編輯的,因此它的items在JDeveloper結構面板中都是灰色的。

圖9:在JDeveloper中擴展一個區域


數據源綁定

對於任何需要和數據庫交互的beans(查詢,插入,更新和/或者刪除),你也需要指定一個綁定到View Instance Name數據源並且關聯View Attribute Name.這個綁定至關重要,因爲OAF框架使用它從潛在的視圖對象中獲取查詢數據或者寫用戶輸入的數據到視圖對象實例中。

l  View Instance Name屬性引用它所包含的應用模塊上下文中的潛在的視圖對象(所有的視圖對象都”存活”於一個應用模塊中並且在它的容器內由實例名稱來標示)。比如,如果一個SupplierVO視圖對象在你頁面的根應用模塊中由實例名稱”MySupVO”標示,”MySupVO”這裏就是你指定的名稱。

l  View Attribute Name引用了映射到列的潛在視圖對象中的屬性。比如,如果你有的SupplierVO有一個”SupplierId”屬性(它映射到了潛在的SUPPLIER_ID列),“SupplierId”在這裏就是你指定的名稱。

定義菜單

所有的OAF應用就像Oracle Browser Look and Feel (BLAF) UIGuideline: Tabs/Navigation.描述的都包含菜單。你可以使用Oracle EBS的菜單和功能定義forms聲明式的定義這些菜單結構。稍後我們會在開發文檔中詳細介紹這個。

就像OAF會翻譯你的聲明式UI佈局到運行時的bean層次結構,它也包含了聲明式的菜單定義的web beans.

定義頁面流

當處理多頁面事務流時,OAF框架爲複雜的硬編碼的控制器邏輯提供了一個聲明式(因此可客製化)的方法。關於這個功能的額外信息可以參考Chapter 4: Declarative Pageflow UsingWorkflow

個性化頁面

OAF框架也包含了一個聲明式的叫做OA Personalization Framework客製化的基礎設施.這是爲了終端用戶和產品發佈鏈支持客製化的相應(更改本地化,排列等等)。

注意:就像你在開發文檔中看到的,聲明式的創建區域和item比編程創建它們更好。實際上,你僅應該當你不能聲明式的創建它們時才通過編程式創建組件,這樣客戶可以個性化你的工作。

控制器

控制器響應用戶的動作並指引應用流轉。

第三章中的Implementing the Controller文檔更詳細的描述了下面的內容。

控制器可以在區域層次上界面視圖進行關聯(從更普遍的角度來看,任何實現了oracle.apps.fnd.framework.webui.beans.OAWebBeanContainer接口的OAF web beans都可以關聯控制器)。

所有你創建的控制器都像下面圖10中展示的繼承於oracle.apps.fnd.framework.webui.OAControllerImpl

控制器類是你定義webbeans如何表現的類。特別的是,你寫控制器代碼用於:

l  在運行時操作/初始化UI(包含任何編程實現的而不能通過聲明式實現的佈局)

l  攔截和處理比如按鈕按下的用戶事件。

請求處理

當瀏覽器爲你的頁面發出一個OA.jsp請求時:

1.        oracle.apps.fnd.framework.webui.OAPageBean(主要的OAF頁面處理類)使用頁面名稱來決定它需要哪個應用模塊,因此它可以從應用模塊池中取出其應用模塊實例。這個應用模塊也會從連接池取出一個JDBC連接,並且頁面的事務上下文也會建立起來。

2.        驗證用戶會話;如果無效,會顯示登錄頁面(注意這是爲了簡單化;更多詳細信息會在後面的開發文檔中有提及)。

3.        假設用戶是有效的,OAPageBean會根據請求參數來判斷正處理的是HTTP POST還是GET請求。

處理GET請求

當瀏覽器發出一個GET請求到服務器來請求一個頁面時(或者你手工轉向它),OAF框架會使用聲明的UI定義來構建web bean的層次結構:

1.      OAPageBean會調用頁面頂層pageLayout bean的processRequest()方法,然後整個web bean層次結構都會如下被遞歸處理來初始web beans(包括任何關聯的模型組件):

1.        每個web bean實例化它的控制器—如果它有的話—並調用控制器上的processRequest(OAPageContextpageContext, OAWebBean webBean)方法。這個方法是你用於構建/修改你頁面佈局,設置webbean屬性和做任何手工數據初始化(如果,比如,當你導向到一個頁面時,你需要做自動查詢)的方法。

2.        一些複雜的webbeans(像oracle.apps.fnd.framework.webui.beans.table.OATableBeanoracle.apps.fnd.framework.webui.beans.layout.OAPageLayoutBean)需要通過調用他們的prepareForRendering()方法來做post-controller處理(這個方法在相應的bean Javadoc裏有詳細描述)。

3.        每個web bean調用它的子控件的processRequest()方法。

2.      oracle.apps.fnd.framework.webui.OAPageBean把web bean的層次結構交給UIX來生成頁面併發送給瀏覽器。

處理POST請求

當瀏覽器爲一個頁面向服務器發出一個POST請求時:

1.      OAPageBean檢查是否web bean層次結構已在內存中。如果沒有(因爲資源已經被回收,用戶通過瀏覽器的回退按鈕導航,或者從一個消息對話框頁面發出一個POST請求到主頁面),它會就像在上面GET請求處理中描述的一樣來重新創建層次結構。

2.      OAPageBean調用在層次結構中的所有beans的processFormData(OAPageContextpageContext, OAWebBean webBean)方法來把form數據寫回到模型中(特別的,它會調用pageLayout區域上的processFormData()方法,然後每個web bean遞歸調用它的子控件上的processFormData()方法)。寫回form 數據到對應的模型會自動調用屬性和實體級別的驗證,並且如果你拋出任何驗證異常,處理就會終止並且錯誤消息會顯示給用戶。

3.      如果在processFormData()階段沒有拋出異常,OAPageBean就會使用上面描述的方式來調用在層次結構中的web bean的processFormRequest(OAPageContextpageContext, OAWebBean webBean)方法。這樣你的控制器代碼就有機會來對用戶的動作作出相應的處理了。

4.      如果沒有JSP轉向或者頁面重定向請求發出--或者異常在processFormRequest()拋出—那麼頁面就會被刷新。

OAPageContext

當OAF框架收到一個OA.jsp請求時,OAPageBean會創建一個oracle.apps.fnd.framework.webui.OAPageContext對象,這個類僅存在於頁面的處理期間。上面描述的3個重要方法(processRequest(), processFormData()processFormRequest())的每一個都使用OAPageContext作爲參數,並且任何你寫的控制器代碼都會利用這個重要的類。

圖10:OAPageContext類和其它關鍵類的關係


就像上面的圖演示的,OAPageContext有對請求和根應用模塊的引用。有了這些關係,OAPageContext被傳遞給每個你的控制器響應處理的方法,你就可以知道如何在下面列出的常用任務使用OAPageContext:

訪問請求參數

可能最重要的,這是你用於讀取請求參數值的類,通過調用一個簡單的方getParameter(Stringname)法(記住請求包含全部URL參數加上—如果是一個POST請求—全部form字段值,加上用戶選擇的關聯動作/控制部件的名稱和事件)。

小技巧:對於你的頁面上的單個web beans(按鈕,字段等等),傳遞給getParameter()的name的值是相應的你在定義頁面時分配的標識ID。因此,比如,你可以在控制器裏寫下面的代碼阿狸知道是否用戶按了你在JDeveloper命名爲”GoButton”的按鈕

processFormRequest(OAPageContextpageContext, OAWebBean webBean)
{
 if (pageContext.getParameter("GoButton") != null)
 {
   // The user pressed the "Go" button, do something...
 }
}


訪問根應用模塊

OAPageContext緩存了根應用模塊的引用,其可以提供對視圖對象和事務的訪問。如果你需要訪問一個應用模塊,可以像下面:

processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
  OAApplicationModule am = (OAApplicationModule)pageContext.getRootApplicationModule();

}


發出導航指令

你可以使用這個類的方法來告訴OAF框架來進行JSP轉向或者一個客戶端的重定向。比如(我們會在稍後的開發文檔中對這個方法做更詳細的介紹):

processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
  if (pageContext.getParameter("CreateButton") != null)
  {
    // The user pressed the "Create Supplier" button, now perform a JSP forward to
    // the "Create Supplier" page.
    pageContext.setForwardURL("OA.jsp?page=/oracle/apps/dem/employee/webui/EmpDetailsPG",
                                   null,
                                                           OAWebBeanConstants.KEEP_MENU_CONTEXT,
                                                           null,
                                                           null,
                                                           true, // Retain AM
                                                           OAWebBeanConstants.ADD_BREAD_CRUMB_YES, // Show breadcrumbs
                                                           OAWebBeanConstants.IGNORE_MESSAGES);
  }
}


訪問應用上下文信息

就像你的模型代碼中的OADBTransactionOAPageContext提供了對servlet會話層Oracle EBS上下文信息,比如用戶名稱,id,當前職責等等。比如,下面的代碼片段演示瞭如何獲取用戶名稱:

processRequest(OAPageContext pageContext, OAWebBean webBean)
{
  String userName = pageContext.getUserName();
}


發佈了105 篇原創文章 · 獲贊 47 · 訪問量 86萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章