隨筆-18  評論-20  文章-0  trackbacks-0

                2006 年 11 月發(fā)布   最近,我所工作的機構(gòu)(威斯康星大學(xué)伊奧克萊爾分校)將一個用 Cobol 編寫且運行在 Unisys 大型機上的老舊系統(tǒng)的一部分移植到了 Java/J2EE 環(huán)境中。 我們的 IT 小組主要使用開放源代碼工具(包括 Eclipse、Tomcat 和 Spring)來編寫應(yīng)用程序。但是,許可方式上的更改使我們可以考慮 Oracle 工具,因此我們使用 Oracle JDeveloper 10g 和 Oracle 應(yīng)用程序開發(fā)框架 (ADF) 編寫了一個應(yīng)用程序來測試開發(fā)模型。本文將對該應(yīng)用程序進行描述,從而快速而詳細地介紹如何使用 Oracle ADF 進行 UI 開發(fā)。(有關(guān)更進一步的技術(shù)信息,請參閱 Oracle 技術(shù)網(wǎng)上的 Oracle ADF 教程和 Oracle ADF 開發(fā)人員指南、Oracle ACE Steve Muench 在 Oracle 雜志上內(nèi)容精彩的 ADF 專欄以及 Oracle JDeveloper 論壇中的評論。)

              在本文中,我不會描述構(gòu)建應(yīng)用程序所需的每一個步驟,但希望這里的信息足以使您作出自己的決策。本文假設(shè)您十分了解 Java,熟悉 Eclipse 或 JDeveloper,并具有普通編程知識。(我沒有在每個步驟后提醒您 Save All,但該步驟不應(yīng)省略。)

              改變給定體系結(jié)構(gòu)和開發(fā)模型總是很困難,因此我將首先提供一些背景知識,以說明 JDeveloper 和 ADF 的價值所在,從而證明這種轉(zhuǎn)變的有利性。我還會在一個單獨的部分中提供一些“提示與技巧”。

          背景

              當(dāng)前應(yīng)用程序直接使用了 Java (JDK 1.5)、Spring(MVC、Web Flow、JDBC 模板)和 jsp 頁面。數(shù)據(jù)也復(fù)制到了一個 Oracle 數(shù)據(jù)庫 10g 第 2 版數(shù)據(jù)庫中。盡管我們了解如何使用 JBoss Hibernate 作為對象關(guān)系映射 (ORM) 工具,但我們的數(shù)據(jù)訪問既不復(fù)雜也不是動態(tài)的,而且 Spring JDBC 模板已經(jīng)充分滿足了我們的需要。

              由于我們在生產(chǎn)中使用的是 Oracle 數(shù)據(jù)庫 10g 第 2 版,因此在基于 Windows 的試用版中使用 Oracle 數(shù)據(jù)庫 10g 快捷版 (XE)(Oracle 數(shù)據(jù)庫的免費入門級版本)順理成章,我們希望能夠在其中輕松地訪問數(shù)據(jù)。在決定使用 Oracle 的 TopLink ORM 工具后使用 Oracle 數(shù)據(jù)庫也很有意義,這樣我們就可以輕松地將映射移植到其他數(shù)據(jù)源(如果決定使用測試用例作為生產(chǎn)應(yīng)用程序的基礎(chǔ))。我們對 XE 所作的唯一更改就是在系統(tǒng)主頁中更改系統(tǒng)全局區(qū) (SGA),以減少它使用的內(nèi)存。

              我們選擇的 TopLink 比預(yù)期的效果還要好,因為它抽象了許多使用 JDBC 甚至接口(如 Spring 的 JDBC 模板)的繁復(fù)的詳細信息。(Dustin Marx 在 OTN 上的“在 JDBC 編程中添加一些 Spring 代碼”一文中提供了一個優(yōu)秀示例,該示例使用 JDBC 模板,無需配置復(fù)雜的 Spring 環(huán)境。)JBoss Hibernate 是一個出色的 ORM 工具,但在端到端 ADF 解決方案中集成 TopLink 映射的能力也令人大開眼界并且非常高效。

              根據(jù) Oracle 的建議,我們創(chuàng)建了一個 EJB 會話 Bean 來封裝對數(shù)據(jù)庫的訪問。這只有在應(yīng)用程序和數(shù)據(jù)庫之間有一個層(以便在其中根據(jù)需要使用業(yè)務(wù)邏輯)的情況下才有意義。迄今為止,我們的應(yīng)用程序中沒有任何需要狀態(tài)的事物,而使用 Session Facade 設(shè)計模式時通常會需要狀態(tài)。

              使用 ADF 的一個標(biāo)準(zhǔn)步驟是創(chuàng)建一組能夠訪問數(shù)據(jù)信息庫的數(shù)據(jù)控件,我們將遵循該原則。在不需要業(yè)務(wù)邏輯的情況下(通常是查詢,有時是更新和刪除),通過 UI 控件直接訪問信息十分高效。在較復(fù)雜的情況下,可以通過在會話 Bean 方法中包含業(yè)務(wù)規(guī)則實現(xiàn)來應(yīng)用業(yè)務(wù)規(guī)則。(ADF 開發(fā)人員指南第 1.1 章很好地說明了 ADF 和 JSF 如何協(xié)同工作以提供高效的開發(fā)環(huán)境。)

              我們還使用標(biāo)準(zhǔn)的 JSF 導(dǎo)航創(chuàng)建了一組 jspx 文件。盡管我們熟悉 Struts,但這里并不使用它。我們將使用 jspx 文件,因為這是 Oracle 建議的做法。

              JDeveloper 10.1.3 在整個項目中充當(dāng) IDE。這可能很明顯,但忘了提醒您它無法識別 JDeveloper 在構(gòu)建 ADF 應(yīng)用程序的過程中所扮演的基本角色。JDeveloper 是一個 Java 開發(fā)工具,但它還可以為您提供對 TopLink、ADF UI 及數(shù)據(jù)訪問控件的功能、JSF 功能以及 XML 和 JSP 文件的端到端訪問,還可以提供測試部署和數(shù)據(jù)庫訪問環(huán)境。

          同時,當(dāng)您在 JDeveloper 中編輯文件時,系統(tǒng)會自動在窗口中調(diào)整更改,您在使用 Eclipse 和其他 IDE 時通??床坏竭@些更改。這些更改提供了各種視圖和編輯方法,因此學(xué)習(xí)使用 JDeveloper 的豐富功能是有一定難度的。您需要了解在哪里雙擊、何時使用 StrUCture 和 Data Control 窗口、何時在屬性編輯器中設(shè)置值,以及(偶爾)何時使用 Source 窗口并編寫 Java 或 JSP 代碼。

           

          項目

              我們的項目是一個簡單的學(xué)生會銀行帳戶。所需的基本功能是輸入和編輯支出與存款。該項目基本上是 ADF 教程中描述的功能子集,因此熟悉 SRDemo 的人可以識別出其中許多元素。SRDemo 是一個完整的示例應(yīng)用程序,您可以通過 JDeveloper 的 Help 下拉菜單中的“檢查更新”機制下載該應(yīng)用程序。該程序包含完整的源代碼,ADF 開發(fā)人員指南使用它來說明如何使用 ADF 進行開發(fā)。

          第 0 階段:構(gòu)建應(yīng)用程序的初始設(shè)置

          第 1 步:使用 JSF、EJB 和 TopLink 模板創(chuàng)建一個新的 Web 應(yīng)用程序。(另請參閱 Oracle ADF 教程 1-10。)選擇模板并不重要,所有選項都可用,即使它們最初沒有被選中。通過該模板,創(chuàng)建標(biāo)準(zhǔn)的 Model 和 ViewController 項目,從而保留應(yīng)用程序的前端和后端。您應(yīng)該設(shè)置默認程序包名稱,因為在創(chuàng)建 Java 類時,該名稱可在 JDeveloper 中用作默認名稱。

          第 2 步:設(shè)置數(shù)據(jù)庫。盡管我們可以嘗試使用 New Gallery 的 Database Tier 中的 Offline Database Objects,但我們先前已經(jīng)創(chuàng)建了所需的 SQL,以使用一組表(3 個)創(chuàng)建模式。我們登錄到 XE Web 界面,并使用腳本(您可以在 SQL Command 頁面上的引用中找到該腳本)創(chuàng)建了用戶和表。為這些表指定主鍵很重要,這樣至少可以使 TopLink 具有足夠的信息來生成更復(fù)雜的映射:
          • Account 用于保存有關(guān)帳戶的基本信息。
          • Details 用于保存所有帳戶的交易信息。
          • Manager 是與帳戶關(guān)聯(lián)的個人列表。

              為了填充表,我們編寫了一個使用 DBUnit 的 Java 應(yīng)用程序,并使用引用中的數(shù)據(jù)集創(chuàng)建了一個 CampusAccounts.xml 文件。如果愿意,您可以克隆 XML 元素來擴展數(shù)據(jù)集。由于這是應(yīng)用程序中的第一個 Java 類,我們選擇在 Model 項目中創(chuàng)建一個 New/General/Java 類,以便創(chuàng)建程序包。然后,將類的主體復(fù)制并粘貼到新創(chuàng)建的類中。如果類已經(jīng)創(chuàng)建,我們將選擇 File/Import 選項將 Java Source 復(fù)制到 Model 項目中。

          public static void main(String[] argv) throws Exception {
          Class driverClass = Class.forName("oracle.jdbc.OracleDriver");
          Connection jdbcConnection =
          DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
          "CampusAccounts", "xxxxxx");
          IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);
          IDataSet dataSet = new FlatXmlDataSet(new File("c:\\CampusAccounts.xml"));
          try {
          DatabaseOperation.CLEAN_INSERT.execute(connection, dataSet);
          }
          finally {
          connection.close();
          }
          }
          
              主要片段的主體演示了利用 DBUnit 功能是多么簡單。它顯示了用于連接到 Oracle Database XE 數(shù)據(jù)庫的 URL,這也是標(biāo)準(zhǔn) Oracle JDBC 驅(qū)動程序的名稱。

           

              但是,您需要在項目中添加一個來自 DBUnit 的 jar 文件和一個庫,以編譯代碼。首先,您需要從 DBUnit zip 文件中提取 jar 文件。從 Model 項目的 Properties 中,選擇 Libraries/Add Jar,然后將 DBUnit jar 文件添加到項目中。通過從 Model 屬性中選擇 Libraries/Add Library,您可以添加 Oracle JDBC 庫,該庫包含 Oracle JDBC 驅(qū)動程序。一旦 jar 文件和庫可用,就可以使用 JDeveloper 的 Alt-Enter 代碼完成選項自動添加所需的導(dǎo)入。(確保導(dǎo)入了 java.sql.Connection。)要運行該 Java 應(yīng)用程序,請在 Applications 窗口中選擇該文件和綠色箭頭。一旦連接創(chuàng)建(下一步),就簡單多了。

          第 1 階段:創(chuàng)建初始模型

          第 3 步:在創(chuàng)建模式之后創(chuàng)建 TopLink 對象關(guān)系映射。(另請參閱 Oracle ADF 教程 1-8 和 2-2。)在使用 TopLink 之前需要創(chuàng)建一個連接。選擇 View/Connection Navigator(如果窗口未打開)。 選擇 New Connection on Database,指定一個名稱,并確保選擇了 Oracle (JDBC) 類型。輸入模式名稱和密碼。如果您使用的是 XE,則將 sid 更改為 XE。測試連接以確保成功。

          返回到 Applications 窗口,右鍵單擊 Model,然后從 Tables 中選擇 New/Business Tier/TopLink/Java Objects。為映射命名并更改連接(如果需要)。查詢第 2 步中的模式,并加入所有表。檢查程序包名稱。系統(tǒng)在您指定的程序包中創(chuàng)建了一組數(shù)據(jù)訪問對象 (DAO),每個表一個。通過打開 Model 的 TopLink 文件夾中的映射,您可以看到每個模式表的域映射。如果您在 Structure 窗口中選擇了一個表,Map 窗口就會轉(zhuǎn)而顯示映射的不同視圖。嘗試這個操作是種不錯的做法,因為它可以讓您熟悉 JDeveloper 如何在窗口中調(diào)整更改。

           

              在 Detail 映射中選擇 Queries 選項卡,您會注意到 TopLink 為每個表自動創(chuàng)建了一個 findAll 查詢。要添加一個簡單查詢(將得到表行的較小子集),請在 Named Queries 中選擇 Add,并為查詢命名。然后,在 Parameters 窗口中選擇 Add,設(shè)置參數(shù)類型(通過指定完全限定的 Java 類名,如 java.lang.Integer),然后單擊 Name 列更改參數(shù)名。針對您需要指定的每個參數(shù)選擇 Add。在我們的示例中,已經(jīng)將 findAccountTransactionsByAccount() 添加到 Detail 映射以根據(jù)帳號檢索特定帳戶的所有行,并將 findOneTransaction() 添加到 Detail 映射以檢索特定交易,交易通過帳號(序列號對)區(qū)分。findOneTransaction() 是一個 ReadObjectQuery,而 findAccountTransactionsByAccount() 是一個 ReadAllQuery:

          了解 Oracle ADF:入門示例(圖一) 點擊查看大圖

              如果您選擇 Format 選項卡,可以使用 TopLink 編輯器創(chuàng)建查詢或輸入查詢字符串。要使用查詢表達式創(chuàng)建器,請選擇 EXPression/Edit。在創(chuàng)建器中,選擇 Add,并將 Second Argument 更改為剛剛創(chuàng)建的參數(shù)。如果有其他參數(shù),則再次選擇 Add,創(chuàng)建器將自動創(chuàng)建一個 AND 子句:

          了解 Oracle ADF:入門示例(圖二)

              系統(tǒng)會創(chuàng)建一個默認的 TopLink 會話,對應(yīng)于所創(chuàng)建的連接。您可以打開 sessions.xml 文件,并通過在 Structure 窗口中選擇 Default 來查看默認值。更改諸如日志記錄之類的選項非常簡單。

          第 4 步:創(chuàng)建 EJB 會話。(另請參閱 Oracle ADF 教程 2-14。)對于 Model,選擇 New/Business Tier/EJB/Session Bean。無需更改默認設(shè)置,除非不需要遠程接口。如果查看創(chuàng)建的 Bean,您將看到系統(tǒng)已經(jīng)創(chuàng)建了可用于表行的 merge、persist、refresh 和 remove 方法。您還將看到,系統(tǒng)已經(jīng)為您創(chuàng)建的每個命名查詢創(chuàng)建了一個方法。EJB 向?qū)ё詣由傻?Java 代碼會在該方法內(nèi)創(chuàng)建一個會話事務(wù)。當(dāng)然,您不必編輯該代碼,并且現(xiàn)有方法的文本也不會被覆蓋(如果在重新生成 Bean 時,它仍然是您的首選項)。

          第 5 步:創(chuàng)建 ADF 數(shù)據(jù)控件。(另請參閱 Oracle ADF 教程 2-16。)ADF 數(shù)據(jù)控件為前面步驟中創(chuàng)建的會話 Bean 和 DAO 提供了一個接口。在創(chuàng)建用于訪問數(shù)據(jù)庫的用戶界面控件時,數(shù)據(jù)控件會提供“粘合劑”。如果您從 View 菜單中打開 Data Control 選項板,應(yīng)該看到它是空白的。右鍵單擊會話 Bean 并選擇最后一項:Create Data Control。Data Control 選項板將填充有以下內(nèi)容:

          了解 Oracle ADF:入門示例(圖三)
          為項目創(chuàng)建可用后端的初步工作就完成了。盡管諸如 ADF 控件之類的產(chǎn)物的實際值在構(gòu)建某些頁面時才會顯現(xiàn)出來,但所花費的精力之少仍然令人驚奇。

           

          第 2 階段:創(chuàng)建初始視圖

          第 6 步:使用初始的 faces-config.xml 文件。在首次打開應(yīng)用程序時,打開 Web Content/WEB-INF 文件夾和所創(chuàng)建的 faces-config.xml 文件。如果由于某種原因尚未創(chuàng)建配置文件,則右鍵單擊 ViewController 項目并選擇 New/Web Tier/JSF/JSF Page Flow & Configuration。faces-config.xml 的默認名稱是正確的。如果您選擇 Overview 選項卡,將看到配置文件的空白視圖:

          了解 Oracle ADF:入門示例(圖四) 點擊查看大圖


              在 JSF 應(yīng)用程序中,該視圖是進入中央配置文件的重要窗口。除了一組描述用戶如何在 Faces 應(yīng)用程序中從一個頁面轉(zhuǎn)換到另一個頁面的 XML 元素以外,還有用于 Bean 的元素,這些 Bean 包括在用戶與界面控件(輔助 Bean)交互時調(diào)用其方法的 Bean,以及用于存儲長久信息(如用戶狀態(tài))的 Bean。

          第 7 步:創(chuàng)建初始導(dǎo)航圖和對應(yīng)頁面。(另請參閱 Oracle ADF 教程 3-2。)現(xiàn)在,需要一組初始頁面(主要基于 SRDemo 中使用的頁面模板),以及描述用戶如何從一個頁面轉(zhuǎn)移到另一個頁面的初始導(dǎo)航規(guī)則。選擇針對 faces-confix.xml 文件的 Diagram 選項卡,確保 Configuration 選項板處于開啟狀態(tài),然后將 JSF 頁面拖到配置圖上。此時,您已經(jīng)在配置文件(而不是頁面)中創(chuàng)建了一個導(dǎo)航元素。

              雙擊無標(biāo)題頁面圖標(biāo),以啟動一個將實際創(chuàng)建文件的向?qū)?。將名稱更改為 index;將文件后綴更改為 jspx(Oracle 的普遍建議);確保系統(tǒng)沒有自動公開該頁面的 UI 組件;然后移動 ADF Faces 組件、JSF 內(nèi)核、ADF Faces 和 JSF Html 庫。選擇您喜歡的 HTML 版本 — 我們在 4.0.1 Transitional 版上運行良好。

              index.jspx 將重定向到應(yīng)用程序的實際第一頁,這是創(chuàng)建 Web 應(yīng)用程序的標(biāo)準(zhǔn)做法。這可能會創(chuàng)造一個糟糕的先例,但可以在 Source 窗口中查找 index.jspx,并用以下 scriptlet 替換 f:view 標(biāo)記。注意,您要創(chuàng)建一個目錄結(jié)構(gòu)來管理頁面 — 管理涵蓋所有應(yīng)用程序的所有頁面,而名為 campusaccounts 的子目錄將用于保存該項目的所有頁面。將 scriptlet 插入 index.jspx 文件之后,您就可以安全地保存并關(guān)閉該文件了。

          <jsp:scriptlet>
          response.sendRedirect("faces/administration/welcome.jspx");
          </jsp:scriptlet>
          

              從 Component 選項板中,將另一個 JSF 頁拖到 faces-config.xml 圖上。雙擊圖標(biāo)打開向?qū)?,以設(shè)置其 jsp 頁面。將名稱更改為 welcome,將文件類型更改為 jspx — 并確保設(shè)置目錄,以創(chuàng)建您希望創(chuàng)建的任何子目錄結(jié)構(gòu)。例如,在本案例中,我們將目錄設(shè)置為 ../public_html/administration,以便對應(yīng)于 sendRedirect。移動選項應(yīng)該與創(chuàng)建 index.jspx 時所使用的移動選項相同,HTML 版本也應(yīng)該相同。

              將內(nèi)容添加到 JSP 頁面實際上就是在 Diagram、Property Editor 和 Structure 窗口之間切換。有時,您甚至可以通過 Source 窗口編輯頁面。在 Structure 窗口中,打開 faces 視圖元素并刪除默認的 f:view 標(biāo)記,以便能夠使用包含面板頁的以下文本替換它。面板頁是一個復(fù)雜的 UI 控件,它包含頁眉、頁腳、用于選擇幫助的全局控件以及版權(quán)部分等內(nèi)容。在使用該頁時,您將發(fā)現(xiàn)使用標(biāo)準(zhǔn)界面組件創(chuàng)建復(fù)雜頁面是多么輕松。粘貼文本的最簡單方法就是切換到 Source 窗口,并確保游標(biāo)跟隨文件開頭的三個 jsp 標(biāo)記。

          <f:view>
          <f:loadBundle basename="edu.uwec.financial.resources.UIResources"
          var="res"/>
          <af:document title="#{res['uacct.campusAccounts.title']}"
          initialFocusId="start">
          <af:form>
          <af:panelPage>
          <!-- Page Content End -->
          <f:facet name="branding">
          <af:panelHorizontal>
          <af:objectImage source="/images/banner.jpg"/>
          </af:panelHorizontal>
          </f:facet>
          <f:facet name="menu1">
          <af:menuTabs var="menuTab" value="http://www.QQread.com/oracle/2006/12/#{menuModel.model}">
          <f:facet name="nodeStamp">
          <af:commandMenuItem text="#{menuTab.label}"
          action="#{menuTab.getOutcome}"
          rendered="#{menuTab.shown and menuTab.type=='default'}"
          disabled="#{menuTab.readOnly}"/>
          </f:facet>
          </af:menuTabs>
          </f:facet>
          <f:facet name="menu2">
          <af:menuBar/>
          </f:facet>
          <f:facet name="menuGlobal">
          <af:menuButtons>
          <af:commandMenuItem text="#{res['uacct.menu.logout']}"
          action="GlobalLogout" immediate="true"
          icon="images/blafIcons/logout.gif"/>
          <af:commandMenuItem text="#{res['uacct.menu.help']}"
          action="GlobalHelp" immediate="true"
          icon="../images/blafIcons/help.gif"/>
          </af:menuButtons>
          </f:facet>
          <f:facet name="messages">
          <af:messages/>
          </f:facet>
          <f:facet name="appCopyright">
          <!--Copyright msg-->
          <h:panelGroup>
          <af:objectSpacer width="10" height="10" id="objectSpacer4"/>
          <af:panelHorizontal halign="center">
          <af:outputText value="#{res['uacct.copyright']}"/>
          </af:panelHorizontal>
          </h:panelGroup>
          </f:facet>
          <f:facet name="appAbout">
          <!-- The About this Application Link-->
          <af:panelHorizontal halign="center">
          <af:commandLink text="#{res['uacct.about']}" action="GlobalAbout"
          immediate="true"/>
          </af:panelHorizontal>
          </f:facet>
          <f:facet name="infoUser">
          <!-- Show the Logged in user -->
          <h:outputFormat value="#{res['uacct.connectedUser']}"
          rendered="#{userInfo.authenticated}" escape="false">
          <f:param value="#{userInfo.userName}"/>
          </h:outputFormat>
          </f:facet>
          </af:panelPage>
          </af:form>
          </af:document>
          </f:view>
          您將注意到 Structure 窗口中報告了錯誤,這些錯誤將在下一步中解決。
          

           

           

          第 8 步:不擇手段地占為己有。(另請參閱 Oracle ADF 教程 4-2。)我們建議從 SRDemo 中借用幾個文件,以使您快速了解如何創(chuàng)建應(yīng)用程序。由于使用資源文件很簡單,我們決定始終使用它來標(biāo)記所有 UI 組件,甚至是按鈕上很明顯的標(biāo)記(如 Submit)。 我們預(yù)計大部分內(nèi)聯(lián)網(wǎng)應(yīng)用程序都沒有國際化需求,但這是一個設(shè)計決策,它創(chuàng)造了一個較好的先例。我們還建議借用幾個類(如 ADFUtils 和 JSFUtils),因為它們非常有用。如果您必須通過 Java 代碼訪問 JSF 和 ADF 框架中存儲的變量,則有一點麻煩。一旦您了解 Oracle 使用的綁定和命名標(biāo)準(zhǔn),就會覺得這些實用程序類十分簡單,示例如下。導(dǎo)入圖像文件夾也很有意義,因為它包含了瀏覽器外觀 (BLAF) 文件夾和界面中使用的幾個圖標(biāo)。

              我們導(dǎo)入文件的方法是選擇 ViewController 項目,選擇 File/Import/Java Source,然后瀏覽到 SRDemo 項目中的類。SRDemo 中的完整路徑與 mywork 位于同一級別 — 參見 samples/SRDemo/UserInterface/src/oracle/srdemo/view。將 ADFUtils 和 JSFUtils 添加到 util,然后將它們復(fù)制到程序包結(jié)構(gòu)中(我們在 src 文件夾中使用的是 edu/uwec/financial/util);將 ResourceAdapter 和 UIResources 添加到 resources(我們使用的是 edu/uwec/financial/resources);然后通過菜單(我們使用的是 edu/uwec/financial/menu)添加 MenuItem、MenuModelAdapter 和 MenuTreeModelAdapter。注意,當(dāng)您導(dǎo)入 Java 文件后,可能需要修改程序包名稱以匹配目錄結(jié)構(gòu)。

              您可以導(dǎo)入一些標(biāo)準(zhǔn)圖像,方法是選擇 File/Import/Web Source,瀏覽到 UserInterface/public_html,然后選擇圖像 — 確保將 images 文件夾復(fù)制到 public_html 文件夾中。這個步驟有一點麻煩,因為在瀏覽時很容易過于深入:

          了解 Oracle ADF:入門示例(圖五)

              此時,jspx 文件中的錯誤應(yīng)該已經(jīng)消失,但可能需要修正面板頁上的元素,例如,要包含在 branding 控件 (facet) 中的所有圖像。如果您要將某個圖像包含在頁面頂部,應(yīng)將其作為 WebContent 導(dǎo)入 ViewController 項目的 images 文件夾。在 Structure 窗口的面板頁中,選擇 branding/panelHorizontal,然后在 Properties 窗口中重設(shè)其對象圖像。您還應(yīng)該確保頁面上的圖標(biāo)(如 logout 和 help)具有正確的 Source 屬性。在 Property 窗口的 Source 屬性中選擇每個圖標(biāo)和 ... 按鈕,并在 Source 窗口中查找圖像。您需要在 welcome.jspx 中編輯諸如 loadBundle 標(biāo)記之類的項,以便與程序包結(jié)構(gòu)相匹配。

          示例屬性文件項與 welcome.jspx 中引用的屬性不對應(yīng)。以下是我們添加的初始名/值對集。

          uacct.about=About MyBlugold
          uacct.copyright=\u00a9 2006 University of Wisconsin - Eau Claire
          uacct.menu.help=Help
          uacct.menu.logout=Logout
          uacct.menu.campusAccounts=Campus Accounts
          uacct.campusAccounts.title=Campus Accounts
          uacct.connectedUser=Logged in as <b>{0}</b>
          

              ADFUtils 類沒有編譯,因為它需要一個庫。在 ViewController 項目上打開 Properties,然后添加 ADF Model Runtime 庫。

              如果您選擇 index.jspx 并運行應(yīng)用程序(選擇綠色箭頭),應(yīng)該看到與以下類似的內(nèi)容 — 當(dāng)然,還包含標(biāo)幟。

          實際上,歡迎頁面將為我們提供更加“全局”的按鈕(如 Help 和 Logout),因為您可以從任何頁面選擇它們。

           

          第 9 步:創(chuàng)建菜單。這一部分將介紹從 SRDemo 中借用以創(chuàng)建菜單的代碼,如果您希望該簡介簡短些,可以跳過該部分。


              管理頂層菜單所需的標(biāo)記和 Java 代碼已添加至項目,但需要在 faces-config.xml 文件中添加相關(guān)項以將其連接。一般而言,JDeveloper 會提供所需項,您也可以打開 faces-config.xml 文件并從 Overview 選項卡添加 Bean 定義。另一種方法是通過 Source 窗口將以下示例復(fù)制到文件,從而使用托管 Bean 元素作為項模型以獲得類似的 Bean(如 Bean 注釋標(biāo)記中所述)。

          <!-- Global menu tab for logout (we also added a tab for help -->
          <managed-bean>
          <managed-bean-name>menuItem_GlobalLogout</managed-bean-name>
          <managed-bean-class>edu.uwec.financial.menu.MenuItem</managed-bean-class>
          <managed-bean-scope>session</managed-bean-scope>
          <managed-property>
          <property-name>label</property-name>
          <value>#{resources['uacct.menu.logout']}</value>
          </managed-property>
          <managed-property>
          <property-name>icon</property-name>
          <value>/images/logout.gif</value>
          </managed-property>
          <managed-property>
          <property-name>type</property-name>
          <value>global</value>
          </managed-property>
          <managed-property>
          <property-name>viewId</property-name>
          <value>/administration/Logout.jsp</value>
          </managed-property>
          <managed-property>
          <property-name>outcome</property-name>
          <value>GlobalLogout</value>
          </managed-property>
          </managed-bean>
          <!-- Campus Accounts menu tab (we also added tabs for Purchasing and Accounting) -->
          <managed-bean>
          <managed-bean-name>menuItem_CampusAccounts</managed-bean-name>
          <managed-bean-class>edu.uwec.financial.menu.MenuItem</managed-bean-class>
          <managed-bean-scope>session</managed-bean-scope>
          <managed-property>
          <property-name>label</property-name>
          <value>#{resources['uacct.menu.campusAccounts']}</value>
          </managed-property>
          <managed-property>
          <property-name>viewId</property-name>
          <value>/administration/campusaccounts/CampusAccounts.jspx</value>
          </managed-property>
          <managed-property>
          <property-name>outcome</property-name>
          <value>GlobalCampusAccounts</value>
          </managed-property>
          </managed-bean>
          <!-- create the main menu menuModel bean, only one needed -->
          <managed-bean>
          <managed-bean-name>menuModel</managed-bean-name>
          <managed-bean-class>edu.uwec.financial.menu.MenuModelAdapter</managed-bean-class>
          <managed-bean-scope>session</managed-bean-scope>
          <managed-property>
          <property-name>viewIdProperty</property-name>
          <value>viewId</value>
          </managed-property>
          <managed-property>
          <property-name>instance</property-name>
          <value>#{menuTreeModel.model}</value>
          </managed-property>
          </managed-bean>
          <!-- create the main menu menuTreeModel bean, only one needed -->
          <managed-bean>
          <managed-bean-name>menuTreeModel</managed-bean-name>
          <managed-bean-class>edu.uwec.financial.menu.MenuTreeModelAdapter</managed-bean-class>
          <managed-bean-scope>session</managed-bean-scope>
          <managed-property>
          <property-name>childProperty</property-name>
          <value>children</value>
          </managed-property>
          <managed-property>
          <property-name>listInstance</property-name>
          <list-entries>
          <value-class>edu.uwec.financial.menu.MenuItem</value-class>
          <value>#{menuItem_GlobalLogout}</value>
          <value>#{menuItem_GlobalHelp}</value>
          <value>#{menuItem_CampusAccounts}</value>
          <value>#{menuItem_Purchasing}</value>
          <value>#{menuItem_Accounting}</value>
          </list-entries>
          </managed-property>
          </managed-bean>
          <managed-bean>
          <managed-bean-name>resources</managed-bean-name>
          <managed-bean-class>edu.uwec.financial.resources.ResourceAdapter</managed-bean-class>
          <managed-bean-scope>application</managed-bean-scope>
          </managed-bean>
          


          由于這些 Bean 將引用資源文件,因此 faces-config.xml 文件還需要一個為其定義的項。在應(yīng)用程序標(biāo)記中,除了添加 default-render-kit 以外,還需要添加以下 xml 元素:

           

          <message-bundle>edu.uwec.financial.resources.UIResources</message-bundle>
          

              再次運行 index.jspx 文件將顯示一個與以下類似的頁面(如果您沒有添加用于購買、幫助等的托管 Bean,那么該頁面將只顯示 Campus Accounts 選項卡):

          了解 Oracle ADF:入門示例(圖七) 點擊查看大圖

           

          第 10 步:創(chuàng)建第一個輸入頁面。第一個“有用的”頁面將是一個允許用戶輸入帳號的頁面,這是管理帳戶的第一步。打開 faces-config.xml 圖并將一個新頁面拖至其上,然后雙擊圖標(biāo)對該頁面進行編輯。 在本例中,我們希望為校園帳戶 (campusaccounts) 創(chuàng)建另一個組織級別,因此在 /administration/campusaccounts 中創(chuàng)建了 choose.jspx(在 public html 之后添加 administration\campusaccounts)。我們決定讓 JDeveloper 在第二步中創(chuàng)建托管 Bean。choose.jspx 的輔助 Bean 將自動命名為 Choose.java,并包含每個用戶界面組件的域。這意味著,您在每次添加組件時(即便是如 spacer 般簡單的組件),它都會通過自己的 getter 和 setter 顯示為一個域。對于編寫 Java 代碼以更改 spacer 中的屬性大?。ㄈ绺叨龋﹣碚f,這十分有意義,然而還是會因此創(chuàng)建出復(fù)雜的輔助 Bean。在本例中,從自動創(chuàng)建的輔助 Bean 開始要更為簡單些(如果我們希望了解它執(zhí)行的操作)。

              使用 Structure 窗口,將 替換為 welcome.jspx 中的 view 標(biāo)記。實質(zhì)上,您已將歡迎頁面用作模板。在 choose.jspx 的 Structure 窗口中,您可以刪除 view 標(biāo)記,然后將 view 標(biāo)記從 welcome.jspx 復(fù)制并粘貼到 choose.jspx 中。如果您選擇在 Source 窗口中進行更改,請注意保留指示 jspx 具有輔助 Bean 的 html 注釋 — 該 Oracle 慣例如下所示:

          <!--oracle-jdev-comment:auto-binding-backing-bean-name:backing_administration_campusaccounts_choose-->
          

              向在 GlobalCampusAccounts 上指定導(dǎo)航規(guī)則的 faces 配置文件添加導(dǎo)航規(guī)則,界面將導(dǎo)航至應(yīng)用程序的第一個頁面。這是一個全局規(guī)則,因為您可以通過在任何應(yīng)用程序的任意位置選擇 CampusAccounts 的選項卡來更改為 CampusAccounts。在 faces-config.xml 中輸入的標(biāo)記是

          <navigation-rule>
          <navigation-case>
          <from-outcome>GlobalCampusAccounts
          <to-view-id>/administration/campusaccounts/choose.jspx
          </navigation-case>
          </navigation-rule>
          

              您可能需要編輯 commandMenuItems 中的 logout 和 home 圖標(biāo)屬性,并更改它們的圖標(biāo)值以使用 blaf 文件夾中的 gif 文件。

              您需要將 PanelHorizontal 插入面板頁以保存輸入文本組件。盡管也可以使用組件選項板 (Component palette),但通常我們認為利用 Structure 頁來執(zhí)行該操作更為簡單(右鍵單擊 PanelPage 元素并選擇 ADF Faces Core 組件即可)。注意,ADF 表單包含有 PanelPage,因此您已經(jīng)具有了自己的 html 表單元素。向水平面板添加一個 InputText 組件。在 Properties 窗口中,更改標(biāo)簽以使用存儲在資源文件中的屬性。一種簡單的方法是先編輯資源文件并添加屬性,然后在 Structure 窗口中雙擊 inputText 元素,選擇 Bind 在 JSF 對象中查找 res,并選擇您剛才輸入的屬性值。一旦您習(xí)慣了訪問資源所需的 EL 格式,就會發(fā)現(xiàn)在 Property Editor 中鍵入屬性值也很簡單。在水平面板上的輸入文本組件后面添加一個 CommandButton,并更改其名稱以使用資源文件中定義的另一個屬性 — 再次建議您使用 Structure 窗口。

              雙擊按鈕轉(zhuǎn)至輔助 Bean。您需要從 InputText 組件獲取文本,并將其置于用戶狀態(tài),以便當(dāng)用戶訪問 CampusAccounts 應(yīng)用程序的選項時它始終可用。

          public String commandButton1_action() {
          Object text = getInputText1().getValue();
          UserSystemState.storeCurrentAcctNum(new Integer(acctNum));
          return "list";
          }
          

              注意,此處無需任何驗證,而您在使用 Faces 組件的選項時會進行不必要的驗證。如果您在 InputText 元素上設(shè)置必需屬性,則會強迫用戶輸入值。如果您在 InputText 標(biāo)記內(nèi)插入一個 ValidateRegExp 驗證程序并添加模式 [0-9]+,則會要求用戶至少為帳號輸入一位數(shù)字。

          在本例中,我們添加了來自 SRDemo 的 UserSystemState,以將其用作模型并創(chuàng)建用于保存帳號的靜態(tài)函數(shù)。我們還必須添加 userSystemState(u 為小寫) 作為 faces-config.xml 文件中的托管 Bean 的名稱。您可以通過 managed-bean-class 域來推斷我們使用的程序包名。JDeveloper 管理 faces-config.xml 文件的明顯特征之一是,如果在編譯代碼或指定程序包名時出現(xiàn)問題,您就會在其標(biāo)記中看到警告。JDeveloper 會主動分析 xml 配置文件。

           

          <managed-bean>
          <managed-bean-name>userSystemState</managed-bean-name>
          <managed-bean-class>edu.uwec.financial.view.backing.UserSystemState</managed-bean-class>
          <managed-bean-scope>session</managed-bean-scope>
          </managed-bean>
          

          以下是 UserSystemState 的起始代碼,用于創(chuàng)建 Command 按鈕中使用的靜態(tài)函數(shù);它將替代所有來自 SRDemo 的域和方法。記住檢查程序包名:

          private HashMap _settings = new HashMap();
          private static final String CURRENT_ACCT_NUM = "CURRENT_ACCT_NUM";
          public Integer getCurrentAcctNum() {
          return (Integer)_settings.get(CURRENT_ACCT_NUM);
          }
          public void setCurrentAcctNum(Integer acctNum) {
          _settings.put(CURRENT_ACCT_NUM, acctNum);
          System.out.println("setCurrentAcctNum:"+acctNum); // some old fashioned testing
          }
          public static void storeCurrentAcctNum(Integer acctNum) {
          JSFUtils.setManagedBeanValue("userSystemState.currentAcctNum", acctNum);
          }
          public static void retrieveCurrentAcctNum() {
          JSFUtils.getManagedBeanValue("userSystemState.currentAcctNum");
          }
          

              該代碼比較奇特。userSystemState.currentAcctNum 似乎是 UserSystemState 中某個域的引用,但這個名稱沒有域。JSFUtils.getManagedBeanValue 函數(shù)調(diào)用的參數(shù)被解析為 getter;因此,userSystemState.currentAcctNum 將導(dǎo)致對 getCurrentAcctNum() 進行調(diào)用。

              如果運行 index.jspx 并選擇 CampusAccounts 選項卡,您應(yīng)該看到應(yīng)用程序的初始頁面將如下所示:

          了解 Oracle ADF:入門示例(圖八) 點擊查看大圖

           

          第 11 步:創(chuàng)建第一個 ADF 數(shù)據(jù)控件。(另請參閱 ADF 教程 5-2。)這一步充滿了樂趣,并且 ADF 的價值將在這一步真正體現(xiàn)出來。創(chuàng)建了允許用戶輸入帳號的頁面后,您現(xiàn)在希望獲取所有與該帳號關(guān)聯(lián)的交易 — 文件上的所有存款和支出。

              在 faces 導(dǎo)航圖中創(chuàng)建一個名為 /administration/campusaccounts/list.jspx 的頁面,并在編輯 list.jspx 時自動公開 UI 組件。復(fù)制來自 welcome.jspx 的 view 標(biāo)記,如第 9 步中執(zhí)行的操作。

              您需要連接列表頁以顯示 Detail 表(或 Detail DAO,具體取決于您如何考慮)中的相應(yīng)行。請牢記,ADF 數(shù)據(jù)控件是構(gòu)建 ADF 應(yīng)用程序的關(guān)鍵,因此請打開 Data Control 選項板。

          了解 Oracle ADF:入門示例(圖九)

          您可以將 findAccountTransactionsByAccount() 函數(shù)拖放到列表頁 — 在這種情況下,您能夠創(chuàng)建諸如 Command 按鈕或參數(shù)表單之類的組件。

              而將 Detail 拖放到 panelPage 將創(chuàng)建一組可以從 Detail 表顯示的行 — 這些行具有一個通用帳號??紤]到在這種情形下一個較長的組件列表比較有用,因此選擇 Tables/ADF Read-only Table...Action Binding Editor 將顯示,因此您需要從選擇頁面獲取為帳號存儲的值,并將其作為要用于 findAccountTransactionsByAccount 的值進行綁定:

          了解 Oracle ADF:入門示例(圖十)


              現(xiàn)在,顯示所有域并啟用選擇和排序功能。您還可以通過在 Structure 窗口中雙擊每一列,來編輯列屬性以有選擇地啟用/禁用排序功能并更改列標(biāo)題。在本例中,我們向資源文件添加了列標(biāo)題,然后將 HeaderText 綁定到引用,如 #{res['uacct.campusAccounts.account']}。(您還可以通過在 Structure 窗口中雙擊組件,來重置表的選擇控件中的文本。)我們發(fā)現(xiàn) Bind 按鈕比較有用。

              如果運行該應(yīng)用程序并輸入一個有效帳號,您希望看到的內(nèi)容將如下所示:

          了解 Oracle ADF:入門示例(圖十) 點擊查看大圖

              如果輸入 1000 作為帳號,您會發(fā)現(xiàn)自己仍位于選擇頁面。您需要指定一個從選擇頁面到列表頁面的轉(zhuǎn)換。在 faces-config.xml 文件中,打開 Design 窗口并確保 Component 選項板可見。選擇 JSF Navigation Case,然后單擊選擇頁面和列表頁面(請按此順序操作)。編輯轉(zhuǎn)換標(biāo)簽并將 success 更改為 list,從而與 Choose.java 中 Command 按鈕操作返回的值相對應(yīng)。現(xiàn)在,數(shù)據(jù)將顯示在列表頁面中。

              注意顯示這個表(包含 Detail 數(shù)據(jù)庫表中的項)是多么輕松。界面組件是一個 ADF JSF 組件,因此可以說您免費獲得了包括各種功能在內(nèi)的復(fù)雜顯示對象,如分頁(總共 33 行結(jié)果,一次打印 10 行,如果結(jié)果全部匹配,可以一次打印全部 33 行)、分層(每行具有一種不同的顏色)、排序以及通過單選按鈕選擇單個行的能力(例如,能夠編輯其中的內(nèi)容)。這個頁面的外觀使用默認的 Oracle 外觀,但是,更改用于指定組件標(biāo)簽的 Css 文件可以獲得不同的顏色、字體和圖標(biāo)。

              此外,您還會注意到利用 ADF 提供的復(fù)雜數(shù)據(jù)控件可以十分輕松地實現(xiàn)數(shù)據(jù)訪問。在將 ADF Read-Only 表拖放到頁面之后,系統(tǒng)會推斷返回的輔助對象類型 (Detail.java),并自動將其用于創(chuàng)建相應(yīng)列。系統(tǒng)提供了行集行為(一次 10 行),正如基于派生自原始數(shù)據(jù)庫表的元數(shù)據(jù)的類型解析一樣。

          第 12 步:創(chuàng)建編輯頁面。(另請參閱 Oracle ADF 教程 10-2。)在列表頁面上,用于選擇的 Table 控件 (facet) 包含一個 af:tableSelectOne 標(biāo)記,該標(biāo)記內(nèi)部有一個 Command 按鈕。如果雙擊 Command 按鈕,將打開輔助 Bean,您可以在其中調(diào)用輔助函數(shù)來獲取數(shù)據(jù)以唯一標(biāo)識選定行,以便將其存儲以用于下一頁面的檢索。

          public String commandButton1_action() {
          setCurrentTransactionIdFromRow();
          return "edit";
          }
          
          List.java 中的輔助函數(shù)如下所示:
          private void setCurrentTransactionIdFromRow() {
          FacesContext ctx = FacesContext.getCurrentInstance();
          JUCtrlValueBindingRef tableRowRef = 
          (JUCtrlValueBindingRef) this.getTable1().getRowData(); Integer transId = (Integer)tableRowRef.getRow().getAttribute("cdPostSequence"); UserSystemState.storeCurrentTransId(transId); }
          
          

              需要將 storeCurrentTransId() 添加至 UserSystemState,以便將第 9 步中的 storeCurrentAcctNum() 用作模型。

              到目前為止,已經(jīng)介紹了選擇要編輯的行所需進行的更改?,F(xiàn)在,需要創(chuàng)建一個要在其中進行編輯的新 jspx 頁面。在 faces-config.xml 文件中,添加一個 jsp 頁面,然后對其進行編輯以命名為 edit.jspx。在 Component 選項板中,選擇 JSF Navigation Case,并在 Design 窗口中將轉(zhuǎn)換標(biāo)簽更改為編輯,以匹配 Command 按鈕中指定的返回值。

              轉(zhuǎn)到 edit.jspx 頁面,從 Data Control 選項板中選擇 findOneTransaction/Detail,并使用 Forms/ADF Form 將其拖放至面板頁。在其中包含一個 Submit 按鈕,并更改域順序(如果需要)。將參數(shù)設(shè)置為 JSF 對象中的值,以使用 UserSystemState 中的 acctNum 和 transId。完成操作綁定之后,您可以將不希望用戶編輯的域的 readOnly 屬性設(shè)置為 true。在 Structure 窗口中雙擊每一個 inputText 域,然后從資源文件設(shè)置它們的標(biāo)簽。首先在資源文件中編輯值要更為簡單。允許用戶從編輯頁面退出可能是最好的做法,因此您可以用 PanelGroup 圍繞 Submit 按鈕,然后在 Submit 之前或之后添加另一個 CommandButton。您需要選擇這些按鈕并添加返回值。對于 Cancel 按鈕,無需調(diào)用與該按鈕對應(yīng)的輔助函數(shù),就可以編輯 action 屬性并指定導(dǎo)航轉(zhuǎn)換值。Cancel 按鈕的一些原始內(nèi)容(如“cancel”)將生效。在 faces-config.xml Design 窗口中添加一個用于提交返回值的 jsf 導(dǎo)航示例,以便從編輯頁面返回列表頁面。另一種比較好的方法是,首先在 faces-config.xml 文件中設(shè)置導(dǎo)航值,在這種情況下,選擇這些按鈕的 action 屬性值時,該值將顯示為選項 — JDeveloper 使用配置文件比較有利。


              您仍然需要編寫代碼來保持在編輯頁面上所作的更改。但在本示例中,您將再次使用 ADF 開發(fā)范例。換言之,與其在輔助 Bean 中編寫代碼,不如依靠 JDeveloper/ADF 向?qū)砭帉懕3指乃璧拇a。您還將使用在最初創(chuàng)建 ORM 并生成會話 Bean 時自動創(chuàng)建的 mergeEntity() 函數(shù)。

              如 ADF 教程第 10 章所建議,在 edit.jspx 頁面上打開 Design 窗口,然后打開 Data Control 選項板。將 mergeEntity() 方法拖放到 Submit 按鈕上,并選擇 Bind Existing CommandButton。下一個顯示的頁面是 Action Binding Editor。 雙擊向?qū)乱徊街械闹悼颍ɑ蛉绻?... 按鈕顯示選擇該按鈕),打開 ADF Bindings 中的綁定。請牢記該綁定引用 ADF 中提供的所有綁定。打開 findOneTransactionIter 節(jié)點并選擇 currentRow 中的 dataprovider。構(gòu)建的表達式(指定當(dāng)前記錄)是 ${bindings.findOneTransactionIter.currentRow.dataProvider}。注意,Submit 按鈕的 ActionListener 屬性已重置為 #{bindings.mergeEntity.execute}??蓪?action 屬性設(shè)置為“list”,以便完成對數(shù)據(jù)庫的更改后,我們的界面將返回到列表頁面。將其值可進行更改的所有文本域的 immediate 屬性設(shè)置為 true。編輯頁面應(yīng)如下所示:

          了解 Oracle ADF:入門示例(圖十二)
          此外,ADF 可以非常輕松地添加編輯事務(wù)的功能。雖然此處未提及,但您還可以向會話 Bean 添加另一個函數(shù),以便在調(diào)用 mergeEntity 之前將業(yè)務(wù)規(guī)則應(yīng)用到編輯域 (Apply Business Rules to Edited Field)。

          適可而止

           

          還有許多演示無法全部囊括在本次練習(xí)中,但您仍可以通過教程或開發(fā)人員指南來完成:

          • 您沒有為應(yīng)用程序添加任何安全措施,以確保只有簽名信息庫中的用戶可以添加記錄(或編輯記錄)。簡單的安全性將允許您打印用戶名而不是空值。
          • 您沒有處理錯誤或特殊條件。
          • 您沒有使用 ADF 的驗證功能。例如,確保輸入文本框在用戶輸入新交易時不為空就比較有意義。
          • 添加一個選擇以允許用戶從交易列表刪除存款或支出,這樣比較有趣。

          但是您必須適可而止!

          感謝并總結(jié)

           

              我們衷心感謝 JDeveloper 團隊就本文中有關(guān) JDeveloper 功能的語句精確性進行了檢查。Oracle 文檔詳細列出了許多此處未提及的 JDeveloper 特性。

              正如我們在簡介中所述,在您已經(jīng)熟悉了某種特定開發(fā)方法后很難再轉(zhuǎn)而使用另一種技術(shù)。本文中,我們使用了 Spring JDBC 模板進行數(shù)據(jù)建模、利用 Spring MVC 和 Spring Web Flow 進行導(dǎo)航,以及將 Eclipse 用作開發(fā)環(huán)境?;叵肫饋恚_始我們是希望了解如何在新環(huán)境中做我們已經(jīng)知曉的事情,而選件(如輔助 Bean)則助了我們一臂之力。最初我們沒有打算嘗試 TopLink,甚至尋求另一種方法來使用 ADF 控件。值得高興的是,我們閱讀了 Oracle 參考,這些參考使我們對于嘗試 ADF 提供的其他功能充滿了信心。

              對于應(yīng)用程序開發(fā)框架而言,ADF 無疑是一個卓越的工具、一個不錯的助手。我們力圖通過 ADF 和 JDeveloper 探索出若干其他方法,包括

          • 使我們現(xiàn)有的基于 Spring 的后端服務(wù)能夠用作可從 ADF Faces 接口調(diào)用的 Web 服務(wù)。Oracle ACE Lucas Jellema 撰寫的網(wǎng)志給予了我們嘗試這種想法的靈感。
          • 使用 Oracle XML Publisher 作為構(gòu)建報表頁面的另一種方法
          • 將 BPEL 插件用于 JDeveloper,以根據(jù)業(yè)務(wù)流程中人為干預(yù)的需要進行建模。據(jù)說,BPEL 之于流程管理正如 SQL 之于數(shù)據(jù)管理。

          Oracle 提供的開發(fā)工具系列可以很好地滿足我們的需求。

          提示與技巧

          1. 一不做,二不休。文中數(shù)次提及的其當(dāng)之無愧的一個事實是:JDeveloper 和 ADF 是功能強大的端到端解決方案。它們具有挑戰(zhàn)開發(fā)環(huán)境(如 .net)的實力。例如,我們最初計劃不使用 TopLink 將示例應(yīng)用程序放在一起,并認為在應(yīng)用程序中編寫基于 Spring 的數(shù)據(jù)訪問很輕松。閱讀 ADF 教程激發(fā)了我們對 TopLink 的好奇,因此我們決定嘗試使用它,并在開始時只是認為這是無害的。在為交易添加第一個列表表單花費了大約 90 秒后,我們的態(tài)度發(fā)生了根本性轉(zhuǎn)變。最初,mergeEntity 函數(shù)似乎只是由 TopLink 創(chuàng)建的另一個產(chǎn)物。在添加了編輯頁面之后,我們了解了其價值,以及可對 Faces 組件進行無縫訪問的 ADF 控件的價值。JDeveloper 提供了集成的開發(fā)環(huán)境。ADF 不僅是一組 UI 組件,還是一個完善的前端、后端框架,可提供能夠顯著提高工作效率的工具。

          2. JDeveloper 與 Eclipse 或 Websphere Application Developer 在創(chuàng)建程序包、復(fù)制和移動文件方面存在著區(qū)別。對于圖像和其他非 Java 文件,我們發(fā)現(xiàn)復(fù)制和移動文件最簡單的方法是在 Windows Explorer 中進行操作,然后在 Applications 窗口中進行刷新。使用 File 中的 Import 選項時,請確保編輯 CopyTo 行以將完整的文件夾(程序包)名包括在內(nèi)。重命名文件和移動文件還會對配置文件和屬性值造成重大破壞。我們一般使用 Property Editor 中的 ... 選項來設(shè)置圖像和其他文件的屬性值。編輯配置文件需要敏銳的眼光和一定的耐心。我們可能犯的最嚴重錯誤就是在 faces 配置文件中將 campusAccounts 更改為 campusaccounts。頁面之間不會出現(xiàn)轉(zhuǎn)換,從而浪費了大量時間。誠然,使用 JDeveloper 時保持程序包一致的確令人煩躁。

          3. 下載 SRDemo 非常簡單,如果您剛好安裝了 JDeveloper。在 Help 菜單中,選擇 Check for Updates,然后選擇 Official Oracle Extensions。選取 ADF SRDemo,并按向?qū)瓿上鄳?yīng)操作。要運行它,請轉(zhuǎn)至 SRDemo 應(yīng)用程序并選擇 index.jspx 和綠色箭頭。一旦下載了演示程序,您就可以訪問其全部文件,包括幾乎所有應(yīng)用程序都需要的幫助類(如 JSFUtils 和 UserSystemState)。您需要為 SRDemo 提供數(shù)據(jù)庫模式。

          4. 您不必離開 JDeveloper 就可查看數(shù)據(jù)庫表的值。從 Connections 選項卡中,選擇您的 Connection 和模式,然后打開一個表。表值將顯示在 Data 選項卡(可能位于窗口底部)中。

              Tom Moore 是威斯康星大學(xué)伊奧克萊爾分校的高級顧問,專攻知識與技術(shù)服務(wù)。Tom 持有威斯康星大學(xué)密爾沃基分校的計算機科學(xué)碩士學(xué)位,熱衷于 Java 和開放源代碼產(chǎn)品(如 Struts 和 Spring)。在他將注意力轉(zhuǎn)向 Oracle 開發(fā)工具和框架之前,已是威斯康星大學(xué)伊奧克萊爾分校計算機科學(xué)系的老成員。
            posted on 2007-08-18 10:29 JavaPoint 閱讀(1718) 評論(1)  編輯  收藏 所屬分類: Java

            評論:
            # re: 了解 Oracle ADF:入門示例 2016-08-05 17:11 | 鄭州
            hhhh  回復(fù)  更多評論
              
            主站蜘蛛池模板: 神池县| 成武县| 雷波县| 扎囊县| 乐安县| 兴安县| 镇江市| 石林| 广平县| 安仁县| 深州市| 宁乡县| 家居| 吉木乃县| 冕宁县| 五峰| 太仓市| 苏尼特右旗| 邢台市| 扶余县| 西华县| 炎陵县| 民县| 东平县| 永善县| 墨脱县| 铜川市| 双流县| 太谷县| 康保县| 抚宁县| 宾川县| 青川县| 延吉市| 河西区| 开封县| 玉溪市| 五莲县| 龙川县| 嘉义县| 蕲春县|