天天看點

《Java EE 7精粹》—— 3.3 複合元件

本節書摘來異步社群《java ee 7精粹》一書中的第3章,第3.3節,作者:【美】arun gupta,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

jsf使用facelets的功能和資源的處理來定義複合元件,定義在facelets标記檔案中的一個或多個jsf元件組成了一個複合元件。這個.xhtml檔案存儲在資源庫中,可以從頁面的任意區域建立一個可重用的元件。

複合元件在定義頁面中定義,在使用頁面中使用。定義頁面使用定義中繼資料(或參數),使用<code>&lt;cc:implementation&gt;</code>定義實作,其中cc是<code>http://xmlns.jcp.org/jsf/composite/</code>命名空間的字首。jsf規範的未來版本可能會放寬對指定中繼資料的規定,因為它可以從實作本身派生。

可以使用jsf1.2定義一個複合元件,但這需要對jsf的生命周期有更深入的了解,并且需要編寫多個檔案。jsf2隻用一個xhtml檔案即可實作,簡化了複合元件的定義。

例如,在一個facelet中有如下代碼片段來顯示登入表單:

這段代碼将呈現一個兩行三列的表,如圖3-1所示。

《Java EE 7精粹》—— 3.3 複合元件

第一列顯示要輸入的字段的提示,第二列顯示文本輸入框,資料可以輸入其中,第三列(它開始是空的)用于顯示對應字段的消息。第一行的輸入值綁定到user.name字段,第二行中的輸入值綁定到user.password字段。還有一個指令按鈕,單擊該按鈕将調用userservice的bean的register方法。

如果這個登入表單要被顯示在多個頁面,那麼應當将這段代碼片段轉換成一個複合元件而不是到處複制這段代碼。這需要将代碼片段複制到一個.xhtml檔案中,該檔案位于标準資源目錄的一個庫中。基于約定優于配置的思想,這段代碼片段會自動配置設定一個命名空間和一個标簽名。

比如,前述的片段被複制到resources/mycomp目錄下的login.xhtml檔案中,其定義的頁面所示如下:

《Java EE 7精粹》—— 3.3 複合元件

在這段代碼中,cc:interface用于定義描述元件特性的中繼資料,如支援的屬性、facet和事件監聽的連接配接點。cc:implementation包含代替複合元件的标記。

複合元件的命名空間是把<code>http://xmlns.jcp.org/jsf/composite/和mycomp</code>連接配接起來。标簽名是不帶.xhtml字尾的頁面檔案名:

《Java EE 7精粹》—— 3.3 複合元件

比方說,這段代碼片段在不同頁面中單擊送出按鈕時,需要傳遞不同的值表達式(而非<code>#{ user.name }</code>)并調用不同的方法(而不是<code>#{ userservice.register}</code>)。定義的頁面可以傳遞的值如下:

《Java EE 7精粹》—— 3.3 複合元件

在這段代碼中,所有的參數都顯式地在cc:interface中被指定。第三個參數有一個目标屬性指向ccform:loginbutton。

在cc:implementation中:

h:form有一個id屬性是必需的,以便在表單内的按鈕可以明确地引用。

h:inputtext現在使用#{cc.attrs.xxx}代替#{ user.xxx }。#{ cc.attrs }是一個預設的el表達式,對複合元件的作者可用,提供通路目前複合元件的屬性。在本例中,#{ cc.attrs}有name和password屬性。

actionlistener是一個事件監聽器的連接配接點。它被定義為一種方法簽名并描述了該方法簽名。

h:commandbutton有一個id屬性,以便它可以在h:form内被明确指定。

使用者名、密碼和actionlistener傳遞使用頁面中需要的屬性:

《Java EE 7精粹》—— 3.3 複合元件

現在,使用頁面可以傳遞不同的backing bean,在點選送出按鈕時,可以調用不同的業務方法。

總而言之,複合元件提供了以下好處。

遵循了不重複自己(dry)的設計模式,代碼一處儲存,到處重用。

允許開發人員不使用任何java代碼或xml配置編寫新的元件。