2017年1月30日 星期一

將 JSF Composite Component 包裝成 jar 檔供其他 Web 專案使用

1.技術問題

JSF 的 composite component (複合元件) 的功能可以組合現有 UIComponent 成為新的、重複使用的元件。可以組合成的複合元件使用、驗證器、轉換器、JSF 系統事件、及 AJAX。 完成的複合元件會包含:
  • facelet: 檔案名稱為新的標籤的名稱,其內容定義標籤的屬性及組合現有的元件。
  • java class: 支援此複合元件執行所需要的 java 程式碼。
例如,可以組合 h:outputLabel, h:inputText, h:commandButton 等三個元件,再加上一個驗證器成為新的元件專門用來輸入電子郵件。
當你完成複合元件時,你可以在現有 Web 專案的 facelet 中直接使用此元件的標籤。但是,如何將此複合元件變成一個獨立的程式庫供其他的 Web 專案使用呢?



2.參考解答

複合元件可以被包裝成 jar 檔,供其他的 JSF 專案使用。

複合元件被視為應用程式的資源之一,預設需放在 JSF 的 Resource Library 中。如果是在 Web 專案,Resource Library 的位置在 [webroot]/resource 下;當包裝成 war 檔後,其位置在 WEB-INF/resources[2]。如果是在 Java Application 專案,Resource Library 的位置在 META-INF/resources 下。預設資源位置的名稱空間 URL 為 xmlns:my="http://xmlns.jcp.org/jsf/composite/

你也可在 META-INF 下新增一個 [component_name].taglib.xml 檔案自訂自己的名稱空間 URL[3]。

綜合上述,在 jar 檔中的結構為:
  • /META-INF/faces-config.xml
  • /META-INF/[component_name].taglib.xml
  • /META-INF/resources/comp (library with composite components)
  • /META-INF/resources/css (Stylesheets)
  • /META-INF/resources/images
  • /META-INF/resources/js
  • /package_name/class_name.class

Application Configuration Resource File

Application Configuration Resource 檔案,或者 faces-config.xml,是用來註冊及設定物件(object)和資源(resource),並且用來定義瀏覽規則(navigation rule)[4]。 若複合元件中內有使用 annotation 的 java class,則必須在 META-INF 目錄下使用 faces-config.xml,告知 JSF 在 class path 下的類別使用 annotation 註記。此時的 faces-config.xml 的內容為:



當應用程式載入時,JSF 會依照以下的方式來尋找一個或多個設定檔案[4]:
  1. 對於 /WEB-INF/lib 目錄下的 jar 檔,尋找此 jar 檔內的 /META-INF/faces-config.xml。如果此檔案存在,會載入此 faces-config.xml 內定義的物件和資源。JSF 會掃描 jar
  2. web.xml 內 javax.faces.application.CONFIG_FILES 參數所指定的一個或多個設定檔案
  3. 在應用程式的 /WEB-INF/faces-config.xml。
你也可將 JSF Facelets 和其相關的 Managed Beans 包裝起來成為 jar 檔供其他專案使用[1]。

3.實作示範

實作一個 DateRangeInput 複合元件,可以輸入起始及結束日期。檢查規則:結束日期不能早於起始日期。日期輸入的元件為 p:calendar (PrimeFaces 的 Calendar 元件)。

Task 1. 製作 DateRangeInput 複合元件

  1. 在 Netbeans 中開啟新的 Java Application 專案
  2. 在專案的 Source Packages 下建立一套件 META-INF.resources.comp
  3. 在 META-INF.resources.comp 下,放入先前完成的 facelet: dateRange.xml
  4. 在 Source Packages 下建立 META-INF 套件。
  5. 在 META-INF 下建立 faces-config.xml。
  6. 建立套件 /validator。
  7. 將驗證器 DateRangeValidator.java 放置到套件 /validator。
  8. Clean and Build 你的 Java Application 專案,便會產生 jar 檔。
在前述的 Task 中,我們使用預設的 namespace url,所以不需建立 .taglib.xml 檔案來自訂複合元件的 namespace url。 也可以在 Web 專案中使用 Ant 來建立 jar 檔[5]。

Task 2. 在 Web 專案中使用複合元件

  1. 建立新的 JSF Web 專案
  2. 加入 PrimeFaces 及 符合元件的 jar 檔。
  3. 建立一 Managed Bean,其具有 startDate 及 endDate 兩個 properties。
  4. 在 index.xhtml 中加入複合元件的 namespace url,及複合元件的標籤。
  5. Build and Deploy 專案

4.參考資料

[1] Java EE6> Packaging JSF facelets (xhtml) and ManagedBeans as JAR, http://stackoverflow.com/questions/6104498/java-ee6-packaging-jsf-facelets-xhtml-and-managedbeans-as-jar
[2] Packaging composite component in JSF2 with Netbeans 7.0.1, Maven http://stackoverflow.com/questions/8295935/packaging-composite-component-in-jsf2-with-netbeans-7-0-1-maven
[3] JSF2 Reuse composite components – Packaging in a Jar file - English Article http://www.jcafe.info/2011/02/jsf2-reuse-composite-components.html
[4] Application Configuration Resource File, http://docs.oracle.com/javaee/6/tutorial/doc/bnawp.html
[5] Sharing JSF 2 Composite Components, https://digitaljoel.nerd-herders.com/2009/12/14/sharing-jsf-2-composite-components/

沒有留言: