免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
JSF Tour 5 MyFaces Intro
Apache MyFaces項目包含了幾個關于JavaServer技術的子項目。如果需要了解更多關于JavaServer Faces的知識,請參考MyFaces對于JSF的介紹。
    Apache MyFaces項目提供了以下的功能:
    JavaServer Faces的實現(xiàn)(MyFaces API和MyFaces Impl模塊)
    用于構建JSF相關的web應用程序的組件庫,例如MyFaces Tomahawk、MyFaces Trinidad、MyFaces Tobago。
    JavaServer Faces擴展包,例如MyFaces Orchestra。
    與其他技術和標準的集成模塊。(用于開發(fā)移動客戶端,在本文和后續(xù)文章中對這部分功能不進行介紹。)
    可以在如下位置下載和MyFaces Impl及其各個子項目的發(fā)布包及樣例程序。MyFaces API 中國網(wǎng)管聯(lián)盟www、bitsCN、com

    在JSF的子項目中,Core子項目視JSF規(guī)范的一個實現(xiàn),其他的項目實現(xiàn)了相關的規(guī)范,例如Portlet Bridge,或者為其他的JSF實現(xiàn)添加了擴展,注意,不僅僅是MyFaces Core。同時,MyFaces的擴展,例如Tomahawk,可以和任意的JSF實現(xiàn)協(xié)同工作,例如Sun Reference Inplementation。
    MyFaces Core1.1.x可以在Tomcat 5.5下工作,但是MyFaces Core 1.2.x要求 Tomcat 6.0環(huán)境。
    MyFaces項目不依賴于其他的項目。它是一個獨立的程序。

網(wǎng)管網(wǎng)bitsCN_com

 

    JSF FAQ
    1.     javax.faces.STATE_SAVING_METHOD的值為client和server時的區(qū)別?
    簡而言之,server端狀態(tài)降將UI組件的持有的信息在HTTP Session中保存,而client狀態(tài)將UI組件持有的信息保存在返回給用戶的頁面的隱藏域(hidden field)。
    client端狀態(tài)對于非常大數(shù)量的用戶來說比較實用,因為不需要在服務器端保存用戶的狀態(tài),從而節(jié)省了內(nèi)存。但是缺點是在網(wǎng)絡中為每個請求傳送了更多的數(shù)據(jù)。
    即使選擇的是client端狀態(tài),任何一個session-scoped實體仍然存在于http session中,這個標記只是影響JSF實現(xiàn)將UI組件持有的數(shù)據(jù)存放在什么位置。
    任何實現(xiàn)了StateHolder的組件,必須實現(xiàn)saveState(FacesContext)和restoreState(FacesContext, Object)方法,來幫助JavaServer Faces Implementation來保存和恢復跨越多個請求的組件的狀態(tài)。
    為了設置值,必須實現(xiàn)saveState方法。這個方法在render響應階段被調(diào)用,在這期間響應的狀態(tài)被設置,用來處理后需的請求。下面是MapComponent組件的該方法的實現(xiàn):
    public Object saveState(FacesContext context) { 中國網(wǎng)管聯(lián)盟www、bitsCN、com
        Object values[] = new Object[2];
        values[0] = super.saveState(context);
        values[1] = current;
        return (values);
    }
    該方法初始化了一個數(shù)組,用來持有保存了的狀態(tài),然后保存所有與MapComponent關聯(lián)的狀態(tài)的所有內(nèi)容。
    實現(xiàn)StateHolder的組件必須提供restoreState方法,該方法用來恢復保存在saveState方法中保存的組件的狀態(tài)。restoreState方法在恢復視圖階段被調(diào)用,在此期間,JavaServer Faces Implementation會檢查是否在最后render response階段保存了狀態(tài),并判斷是否需要恢復,以便進行下次的后退。下面是MapComponent組件的restoreState方法。
    public void restoreState(FacesContext context, Object state) {
        Object values[] = (Object[]) state;
         super.restoreState(context, values[0]);
        current = (String) values[1]; 中國網(wǎng)管聯(lián)盟www_bitscn_com
    }
    該方法的參數(shù)為FacesContext和Object實例,表示存儲組件狀態(tài)的數(shù)組。這個方法將Object數(shù)組中保存的數(shù)據(jù)進行設置。
    當在自定義的組件類中實現(xiàn)這些方法時,確保在部署描述符中指定了需要將這些狀態(tài)保存在哪里,即client還是server。如果狀態(tài)時保存在client,整個視圖的狀態(tài)都被提供給頁面的一個hidden field。
    可以通過設置javax.faces.STATE_SAVING_METHOD上下文參數(shù)(context-parameter)。
    2.     瀏覽器總是顯示一個到上一個頁面的鏈接?
    默認情況下,JSF在內(nèi)部使用forward操作來在頁面之間導航。
    所以當一個用戶首先訪問頁面A,然后取回一些內(nèi)容。這些內(nèi)容會被包裝在表單中,表單以頁面A作為提交的地址。
    當用戶接著執(zhí)行操作,提交頁面,這時JSF收到post請求,回復頁面A的視圖,并執(zhí)行postback處理。作為postback處理的一部分,頁面A的邏輯可能通知JSF框架應該顯示頁面B。
    默認情況下,JSF會執(zhí)行一個內(nèi)部forward到頁面B,使頁面B被取回,作為用戶提交表單的結(jié)果。
    這時用戶在屏幕上看到頁面B。但是瀏覽器只知道它將數(shù)據(jù)發(fā)送給了頁面A,所以,瀏覽器導航欄上顯示的URL是頁面A的URL,雖然顯示的內(nèi)容是頁面B。不幸的是,HTTP/HTML不能使瀏覽器知道應該顯示頁面B的URL。因此,作為JSF的默認行為,瀏覽器的URL經(jīng)常是實際顯示內(nèi)容的頁面的上一頁。 中國網(wǎng)管論壇bbs.bitsCN.com
    不僅僅對于用戶來說是奇怪的,同時加入收藏夾的時候也比較困難,注意,收藏夾的位置一般來說是沒有關系的。因為JSF應用程序通常是可交互的,并且是狀態(tài)豐富的。
    另外一個缺點是在JSF視圖中使用關聯(lián)鏈接是不安全的。(例如樣式表的相對路徑或者圖標)。當瀏覽器提交內(nèi)容到A,并獲取數(shù)據(jù)共頁面B使用時,在返回頁面中的relative links都會被作為相對于它(瀏覽器)所知道的最后的url。所以第一次查看頁面B時,所有相對鏈接都是相對于頁面A的,如果A和頁面B不在一個目錄中,那么就會出現(xiàn)問題。
    這個問題的一個解決辦法就是使用<redirect/>標記來定義導航規(guī)則。這樣,會使用http redirect命令錘嫠咪榔骰袢⌒亂趁媯傭〈蔥心誆康膄orward。 但是,這樣做效率比較低,因為瀏覽器需要使用第二次請求來獲取它的內(nèi)容,而不是在針對初始的post請求,在響應時立即獲取它的內(nèi)容。另外一個重要的問題就是,獲取頁面B的內(nèi)容是在一個單獨的請求中,這樣就沒有辦法從A頁面中傳遞任何的請求范圍(request-scoped)數(shù)據(jù),在這樣的目的使用request范圍的變量非常方便,也是很常用的。
    Tomahawk sandbox庫中包含了s:redirectTracker組件,可以臨時將request-scoped變量保存在http session中,這樣使用<redirect/>規(guī)則就可以在不丟失request范圍變量的情況下使用,但是這要求存在http session,并且效率低下。

中國網(wǎng)管聯(lián)盟www、bitsCN、com


    MyFaces FAQ
    1.     什么是shared項目?
    如果myfaces-core、tomahawk、tobago、trinidad都是完全獨立的項目,那么就不需要shared代碼項目,每個項目都在各自的名稱空間內(nèi)維護代碼。但是,會存在大量的重復代碼,并且工作量的浪費。因為它們都屬于myfaces項目,所以多個子項目可以共用的代碼放在shared項目中,以便減少開發(fā)和維護的工作量。
    但是,這些子項目又都有各自的獨立釋放周期。并且,tomahawk/tobago/trinidad都應該運行在任意的JSF實現(xiàn)上,而不僅僅是myfaces-core。目前使用的解決辦法是重命名shared的類的報名。代碼被重命名成org.apache.myfaces.shared_impl、org.apache.myfaces.shared_tomahawk等等。這樣每個子項目就可以在發(fā)布的時候包含所有的支持類,而不是一個獨立的共享jar文件,也不需要關心相同類的定義的沖突。對于特定項目的升級不會影響到相同環(huán)境下的其他項目。
    注意最近的MyFaces項目的釋放都是用了shared庫,并在源代碼的jar文件中包含了shared項目的源代碼,所以不需要添加額外的源代碼jar文件。
    2.     如何從MyFaces獲取格式良好的HTML輸出?

中國網(wǎng)管聯(lián)盟www_bitscn_com


    JTidy項目提供了一個ServletFilter,可以將響應的消息在輸出前進行重新的格式化。Mozilla Firefox瀏覽器提供了一個擴展的View Formatted Source功能。
    在一些版本的MyFaces中,可以通過設置org.apache.myfaces.PRETTY_HTML來在web.xml文件中啟用pretty輸出。但是,這個選項從來都沒有被很好的支持,因為需要所有的renderer來支持,以便其工作??赡茉谝院蟮腗yFaces發(fā)布中移除。
    3.     MyFaces Core和tomahawk發(fā)布包中的版本號表示什么?
    MyFaces Core使用三個部分來表示版本,例如1.1.1。但是這個值和普通的版本號計數(shù)是不同的。強兩個數(shù)字表示了JSF規(guī)范的版本。因為二進制的JSF規(guī)范的API沒有改變,前兩位數(shù)字相同的發(fā)布包被認為是兼容的,所有使用JSF指定特征的既存代碼會同樣可以使用。
    Tomahawk庫也適用相同格式的版本號。但是因為JSF 1.2規(guī)范是向后兼容的,即兼容JSF 1.1規(guī)范,所有Tomahawk發(fā)布的版本中,1.1.x同樣可以工作在JSF 1.2上。注意,tomahawk釋放不保證二進制向后兼容。
    4.     為什么DataModel不是可序列化的? 網(wǎng)管聯(lián)盟www.bitsCN.com
    DataModel類(在UIData組件中使用)在顯示和恢復視圖階段不需要保存任何任何狀態(tài)。因此,不需要將它定義為可序列化的。
    如果需要定義可序列化的managed bean,并且它包含一個DataModel類型的成員變量,那么將成員變量定義為transient。
    5.     為什么時間顯示不正確?
    JSF規(guī)范要求默認的date->String轉(zhuǎn)換器使用標準的UTC時區(qū),也叫做GMT時區(qū)。
    MyFaces 1.1.0或者早期的發(fā)布并沒有遵循JSF規(guī)范,它們默認的使用了服務器的時區(qū)。
    可以通過顯示試用轉(zhuǎn)換器來進行時區(qū)的控制,例如:
    <f:convertDateTime timeZone="Antarctica/South_Pole" .../>
    或者
    <f:convertDateTime timeZone="#{bean.timeZone}" .../>
    #{bean.timeZone}返回字符串id或者TimeZone實例。
    當然,也可以注冊自定義的converter來覆蓋標準的converter,使自定義代碼適用于所有的時間到字符串的轉(zhuǎn)換。
    6.     如何在一個managed bean中訪問另外一個managed bean?

54ne.com


    有兩種方法來實現(xiàn)訪問同一個webapp中的其他managed bean:
    使用依賴注入:在faces配置文件中定義managed beans,managed bean的屬性可以被聲明成到其他managed bean的引用:
    <managed-bean>
       <managed-bean-name>neededBean</managed-bean-name>
       <managed-bean-class>fqn.to.NeededBean</managed-bean-class>
       <managed-bean-scope>session</managed-bean-scope>
     </managed-bean> m

 

     <managed-bean>
       <managed-bean-name>usingBean</managed-bean-name>
       <managed-bean-class>fqn.to.UsingBean</managed-bean-class>
       <managed-bean-scope>request</managed-bean-scope>
       <managed-property>
         <property-name>neededBean</property-name>
         <value>#{neededBean}</value>
       </managed-property>
     </managed-bean>
    限定條件如下:
    using bean必須的生命周期小于或者等于被引用的needed bean
    using bean必須具有setter方法,以needed bean作為參數(shù)
    beans不能管理彼此的依賴。
    使用查詢機制:下面的代碼可以在MyFaces 1.1中來顯示的通過名字查詢?nèi)我獾膍anaged bean。 54com.cn
    FacesContext facesContext = FacesContext.getCurrentInstance();
    NeededBean neededBean
        = (NeededBean) facesContext.getApplication()
            .getVariableResolver().resolveVariable(facesContext, "neededBean");
    在MyFaces 1.2中,不使用上述的方法,而是推薦使用:
    ELContext elContext = FacesContext.getCurrentInstance().getELContext();
    NeededBean neededBean
        = (NeededBean) FacesContext.getCurrentInstance().getApplication()
            .getELResolver().getValue(elContext, null, "neededBean");
    同樣,可以使用這個代碼來計算任意的JSF表達式:
    FacesContext facesContext = FacesContext.getCurrentInstance();
    NeededBean neededBean
        = (NeededBean)facesContext.getApplication() feedom.net
          .createValueBinding("#{neededBean}").getValue(facesContext);
    7.     如何得知一個managed bean的屬性是否都被設置?
    managed bean必須具有一個默認的無參構造器。所有的managed-property聲明會調(diào)用合適的setter方法。但是,通常在所有的bean屬性被定義后進行一些初始化的操作。
    Spring提供了post-inistialisation回調(diào)功能,任何實現(xiàn)InitializingBean的bean會調(diào)用afterPropertiesSet方法。在JSF中沒有準確的等價操作,但是有一些接近的方式:
    定義bean的setter方法,例如public void setInitialized(boolean state)
    將下面的屬性作為managed bean的最后一個屬性
     <managed-bean>
        ....
        <managed-property>
          <property-name>initialized</property-name>
          <value>true</value>

中國網(wǎng)管聯(lián)盟www、bitsCN、com

        </managed-property>
     </managed-bean>
    JSF規(guī)范要求managed properties根據(jù)它們聲明的順序進行初始化。所以setInitialized方法會在所有其他屬性被調(diào)用后進行設置。
 
8.     PhaseListener為什么會被調(diào)用兩次?
    JSF規(guī)范要求任何JSF實現(xiàn)框架在啟動時自動加載/WEB-INF/faces-config.xml,所以沒有必要添加如下的context參數(shù):
    <context-param>
       <param-name>javax.faces.CONFIG_FILES</param-name>
       <param-value>/WEB-INF/faces-config.xml</param-value>
    </context-param>
    如果在web.xml文件中配置了上述信息,會迫使JSF實現(xiàn)加載配置文件兩次,所以注冊了每個phase listener兩次。
    9.     dataTables的Action listener和action命令沒有被調(diào)用?
    如果action源(h:commandLink,h:commandButton)沒有被提供,那么Action Listeners和actions就不會被激活。當action源在dataTable上時,并且dataTable的value屬性指向一個請求范圍的數(shù)據(jù)源,那么action源在接下來的請求中就沒有被提供,例如:
    <h:dataTable value="#{requestScopedBean.dataModel.wrappedData}" /> 
            <h:column>
                    <h:commandLink value="click here" action="#{backingBean.willNotFire}" />
            </h:column>
    </h:dataTable>
    action源沒有被rendered,是因為數(shù)據(jù)源在隨后的請求中不存在了(在第一次響應完成后,被垃圾回收器進行了回收)。
    為了解決這個問題,使用t:saveState標記或者將request范圍的bean放在session范圍內(nèi):
    <t:saveState value="#{myRequestScopedBean.dataModel.wrappedData}" />
    10. 日歷、樹等不能工作,并發(fā)生javascript腳本錯誤?
    這是需要配置MyFacesExtensionFilter。
    一些MyFaces組件不僅僅包含了HTML,可能需要額外的支持腳本、樣式表、圖片等等。這些資源包含在MyFaces的jar文件中,Extensions Filter添加所需的代碼和URL來提供這些資源給生成的HTML。
網(wǎng)管聯(lián)盟www.bitsCN.com

    一些其他的組件,例如文件上傳需要解析Multipart請求,這也是由Extensions Filter來完成的。
    使用ExtensionFilter有如下的好處:
    將MyFaces的組件和應用程序良好的隔離
    不需要在頁面或者webapp中添加MyFaces其他的組件相關的代碼或者資源。
    為MyFaces開發(fā)組提供了靈活的更新組件,保持透明及向后兼容的功能。
    為頁面開發(fā)人員減輕了壓力。
    只加載對使用組件的資源
    處理MyFaces資源緩存
    可以通過如下方式配置extension filter:
    在web.xml文件中,將filter映射到JSF頁面,例如*.jsp,以便使filter可以更新頁面中的資源鏈接;同時映射filter到/faces/myFaces/ExtensionResources/*路徑,這樣可以處理頁面獨立的資源,例如圖片,javascript腳本文件以及樣式表等等。下面是一個配置的例子:
    <filter>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
54ne.com

        <init-param>
            <param-name>maxFileSize</param-name>
            <param-value>20m</param-value>
            <description>Set the size limit for uploaded files.
                Format: 10 - 10 bytes
                        10k - 10 KB
                        10m - 10 MB
                        1g - 1 GB
            </description> feedom.net
        </init-param>
    </filter>
網(wǎng)管網(wǎng)bitsCN_com

 

    <!-- extension mapping for adding <script/>, <link/>, and other resource tags to JSF-pages -->
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <!-- servlet-name must match the name of your javax.faces.webapp.FacesServlet entry -->
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>

網(wǎng)管聯(lián)盟www.bitsCN.com

 

    <!-- extension mapping for serving page-independent resources (javascript, stylesheets, images, etc.) -->
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
    </filter-mapping>
    同樣,也可以將使用url-pattern來代替serlvet-name元素。但是仍然需要/faces/myFacesExtensionResource/*這個映射。
    <!-- extension mapping for adding <script/>, <link/>, and other resource tags to JSF-pages -->
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <url-pattern>*.jsf</url-pattern>
    </filter-mapping>
    使用這個過濾器不會對性能造成太大的影響,即不會延遲響應時間,但是由于需要在將響應寫出到客戶端之前在內(nèi)存中將整個response進行緩存,會增加內(nèi)存的使用。

中國網(wǎng)管論壇bbs.bitsCN.com

    如果只是使用標準的JSF組件,而不是用MyFaces擴展的組件,以t:打頭的,那么就不需要使用這個filter,否則的話,就需要進行配置。
    11. “ExtensionFilter not correctly configured.” Error?
    如果發(fā)生如下的錯誤:
    "java.lang.IllegalStateException: ExtensionsFilter not correctly configured. JSF mapping missing. JSF pages not covered"
    并且所有的配置已經(jīng)正確的設置,那么檢查以下內(nèi)容:
    確保配置正確,參考:http://myfaces.apache.org/tomahawk/extensionsFilter.html
    如果使用Servlet 2.4,那么不能使用jsp:forward或者request.getDispatcher().forward來跳轉(zhuǎn)到某個頁面,因為沒有執(zhí)行extensions filter,作為替代方法,要使用response.sendRedirect方法。
    12. 使用tomahawk:popup標記時,發(fā)生NullPointerException,在HtmlPopupRenderer.encodedEnd
    facet的名字需要硬編碼成”popup”。
    庫的依賴情況
    MyFaces核心包和組件庫。
    當發(fā)布MyFaces類庫的時候,也就是說不是Core框架,它會和當前的MyFaces Core,Sun Mojarra(即Sun JSF RI)的釋放版本兼容。
54com.cn

    同時支持一些其他的版本,但是不做任何保證。
    Getting Started
    開始Apache MyFaces的第一步應該是查看一下樣例應用程序。可以在http://www.irian.at/myfaces.jsf查看這些程序,或者可以通過自定義部署來完成。可以通過以下方式來部署:
    下載Tomcat5.x/Tomcat6.x
    MyFaces例子。下載最新的webapp文件(tomahawk-X.X.X-examples.zip)
    將MyFaces樣例文件解壓縮到指定目錄。
    將任何之前在Tomcat中發(fā)布過的MyFaces應用程序清除,同時清空Tomcat的work目錄。并且保證類路徑或者Tomcat的lib(common/lib or shared/lib)中不存在jsf-api.jar或者jsf-impl.jar(也就是說Sun API和實現(xiàn))。將simple.war文件或者其他的例子拷貝到Tomcat安裝目錄的webapps目錄。啟動Tomcat。
    也可以使用MyFaces 運行Sun JSF RI樣例程序,具體介紹參考這里。
    如何在自定義的web應用程序中使用MyFaces?建議步驟:
    在MyFaces Wiki網(wǎng)站查看與開發(fā)環(huán)境中servlet容器的兼容性
        然后可以使用樣例程序來開始開發(fā),例如blank.war。將blank.war解壓縮后,就構成了需要工作的目錄結(jié)構。 中國網(wǎng)管聯(lián)盟www_bitscn_com
    安裝和配置
    1.     在沒有網(wǎng)絡連接的情況下使用Tomahawk
    tomahawk.jar文件包含了META-INF/faces-config.xml,該文件使用了到web-facesconfig_1_1.dtd的PUBLIC引用。這使得在應用程序服務器啟動的時候,訪問java.sun.com來參考該DTD文件。這個問題的顯示如下(從Tomcat日志中獲取):
    “javax.faces.FacesException:Can’t parse configuration file:jar:file:/<web-context-path>/WEB-INF/lib/tomahawk.jar !/META-INF/faces-config.xml”
    解決這個問題的辦法如下:
    在tomahawk.jar文件中添加META-INF/web-facesconfig_1_1.dtd
    修改同目錄的faces-config.xml的到DTD的引用:
    <!DOCTYPE faces-config SYSTEM "web-facesconfig_1_1.dtd">
    2.     Apache Tomcat作為Servlet容器。
    Apache Tomcat 5.5.x(不包括5.5.9)
    Apache Tomcat 5.5.x可以和MyFaces共同工作,所有需要的jar文件已經(jīng)在MyFaces提供的war文件中包含。 54ne.com
    如果在啟動時看到空白頁面,那么需要移除jsp-2.0.jar和commons.el。因為Tomcat5.5.x將這些文件放在容器外,造成了和MyFaces的war文件提供的jar文件沖突。 54ne.com

 

    專題項目
    1.     JSF狀態(tài)管理
    StateManager管理狀態(tài),但是作為終端用戶,必須告訴它需要保存什么。這可以通過實現(xiàn)Serializable接口(正確的使用transient變量)或者實現(xiàn)StateHolder來完成。
    數(shù)據(jù)在JSF中以兩種不同的方式存儲:在特定范圍的bean中,或者在組件樹中。特定范圍的bean經(jīng)常是自解釋的。組件的狀態(tài)保存在響應中,然后再請求到達時被恢復。有效的方式是讓數(shù)據(jù)存儲在組件的page范圍,只要頁面不改變的話。注意,組件保存值的綁定和方法的綁定,通過使用EL表達式(#{}),所以他們指向的beans不在頁面范圍內(nèi)存儲到組件樹中。
    MyFaces有一個SaveState組件叫做<t:saveState>,允許將數(shù)據(jù)作為組件樹的一部分存儲。
    Immediate屬性是如何工作的?
    immediate屬性可以被用來達成如下的功能:
    允許commandLink或者commandButton來將用戶導航到其他頁面,而不需要處理當前頁面的輸入域中的數(shù)據(jù)。特別是這允許在發(fā)生驗證錯誤的情況下進行導航。典型的例子就是cancel按鈕。
    允許commandLink或者commandButton在忽略一些輸入域的驗證來觸發(fā)后臺邏輯。這是上面所說的更普遍說法。 中國網(wǎng)管聯(lián)盟www_bitscn_com
    使一個或多個輸入組件具有驗證高優(yōu)先級。這樣的話,如果同一個頁面中有些低優(yōu)先級的輸入包含不合法的輸入時,驗證也不會進行。這樣可以減少錯誤消息的顯示。
    在討論immediate之前,首先來看一下JSF請求處理生命周期:
    Restore View – 創(chuàng)建或者回復前一個頁面
    Apply Request Values – 將組件的提交值設置為請求值
    Process Validations – 轉(zhuǎn)換和驗證組件的值。如果提交的值是合法的,那么將組件的值設置為提交的值。
    Update Model Values – 將后臺bean的值設置為組件的值。
    Invoke Application – 執(zhí)行actionListeners和actions。
    Render Response – 返回響應。
    很多開發(fā)人員認為使用immediate標記是用來使組件跳過Process Validations階段。使用immediate屬性的目的是使組件在Apply Request Values階段被處理。
    使用immediate屬性意味著組件的值會在apply-request-values階段被驗證,也就是說,在其他的non-immediate組件的值之前(這些驗證是在process-validators階段被驗證)。任何被標記為immediate的輸入組件如果發(fā)生炎癥錯誤,都會導致處理在完成apply-request-values后跳轉(zhuǎn)到render階段。也就是說,如果任何immediate組件驗證失敗,那么non-immediate組件的錯誤消息不會被顯示。另外,如果immediate組件的新的值和既存的value屬性的值不同,那么會激活一個ValueChangedEvent,但是這個事件會在ApplyRequestValues階段最后執(zhí)行,而不是在ProcessValidations階段最后。特別的,這意味著任意關聯(lián)到這個組件的ValueChangeListener都會在其他的immediate !UICommand組件的ActionListener之前執(zhí)行(假設command組件在頁面的后面發(fā)生)。

網(wǎng)管網(wǎng)bitsCN.com

    將輸入組件設置為immediate并不影響模型的更新,任何的新的值仍然會在Update Model階段被注入(也就是說,在任何immediate命令組件執(zhí)行之后)。注意,也可以使用ValueChangeListener直接更新模型。
    使用immediate屬性使組件ActionListener或者action方法在apply-request-values階段的最后被執(zhí)行。也就是說,在任意非immediate值的驗證和后臺bean被更新之前執(zhí)行。
    如果是返回一個導航字符串的form的action方法,那么:
    任意非null字符串會使得生命周期直接運行到render-response階段,意味著任意非immediate組件的驗證永遠不會被執(zhí)行。這就是為什么immediate命令組件會以自然的方式來實現(xiàn)cancel操作。它甚至在頁面中輸入域驗證失敗的情況。當然,也就沒有什么update model階段,也就是說用戶輸入的數(shù)據(jù)被丟棄。
    null返回值會導致處理正常進行,也就是說,非immediate組件被驗證,然后執(zhí)行update model(如果不發(fā)生驗證錯誤)。
    如果想讓actionListener方法返回void,必須調(diào)用
    facesContext.renderResponse();
    在使用immediate輸入組件時最重要的問題就是用戶新輸入的數(shù)值并不是總能在model中訪問,因為update-model階段還沒有執(zhí)行。
網(wǎng)管網(wǎng)bitsCN.com

    對于頁面中的非immediate輸入組件,immediate命令組件的action方法訪問用戶輸入數(shù)據(jù)的唯一方式就是通過使用組件綁定和通過名稱查詢來獲取指定的UIComponent對象,然后調(diào)用getSubmittedValue方法來獲取用戶提供的原始字符串。這個值沒有被轉(zhuǎn)換成它的目標類型,也不會被驗證。
    對于immediate輸入組件,進行了轉(zhuǎn)換和驗證的步驟,使用對應的UIComponnet組件,是可能獲取轉(zhuǎn)換后的值。如果組件在頁面中位于UICommand組件的前面,并且觸發(fā)了ValueChangeListener,這樣就會執(zhí)行ValueChangeListener。
    警告:如果action方法更新模型,但是不進行導航,那么在輸入組件的值通過驗證并更新模型時都會覆蓋后臺bean的值。
    任何immediate 組件的驗證失敗都不會停止immediate命令組件的執(zhí)行,這和non-immediate輸入組件和命令組件大不相同。
    學習指南
    當學習JSF的時候,不需要仔細查看具體的實現(xiàn),下面建議了一個類/方法的列表,對學習JSF和MyFaces如何實際工作的很有幫助,同時提到了對典型方法的一個簡短描述。
    javax.faces.webapp.FacesServlet
    init方法用于啟動基本的faces。它演示了如何使用FactoryFinder來創(chuàng)建LifeCycle和FacesContext工廠 網(wǎng)管網(wǎng)bitsCN.com
    service方法演示了LifeCycle對象控制整個JSF處理
    javax.faces.component.UIViewRoot
    queueEvent方法在組件決定激活一個value-change事件(或者其他類型的事件)時被調(diào)用。事件隊列的有意思的地方是:
    javax.faces.component.UIInput的驗證方法
    org.apache.myfaces.renderkit.html.HtmlButtonRendererBase的decode方法
    javax.faces.component.UIComponentBase
getRenderer方法演示了如何使用當前視圖中的renderkit-id、組件聲明的組件家族和組件聲明的renderer-type名稱來決定使用哪一個renderer。
    javax.faces.webapp.UIComponentTag
    createComponentInstance演示了在JSP標記引用UIComponent組件并且組建不存在于view眾時,如何實例化這個組件,通過調(diào)用Application.createComponent(String),注意該createComponentInstance方法調(diào)用自己的getComponentType()方法,這個方法典型的實現(xiàn)了JSF終端標記類,例如org.apache.myfaces.taglib.html.HtmlCommandButtonTag。
    javax.faces.componnet.UIInput
    processDecodes、processValidators、processUpdates方法演示了表單數(shù)據(jù)是如何變成模型的數(shù)據(jù),通過轉(zhuǎn)換和驗證的處理。對于多數(shù)的組件,實際的工作過程為Apply Values、Process Validators和Update Model階段。注意,數(shù)據(jù)從表單中開始,加載到組件的提交值字段,轉(zhuǎn)換成組件的本地值字段,然后拷貝到后臺bean。很多條件影響到process的出口,例如rendered state、immediate state、conversion errors和validation errors。
    結(jié)合DataTable和ActionListeners

網(wǎng)管網(wǎng)bitsCN_com


    如果在dataTable的某一行包含command link或者command button,可以從javax.faces.event.ActionListener中輕松的獲取bean:
    <h:dataTable value="#{ResultsBean.hitSet.hits}" var="hit">
     <h:column>
        <h:commandLink>
          <f:actionListener type="net.java.OrderActionListener" />
          <h:outputText value="Order" />
        </h:commandLink>
        ...
     </h:column>
    </h:dataTable>
    可以通過下面的java代碼來獲取bean:
    public class OrderActionListener implements ActionListener {
     public void processAction(ActionEvent anEvent) throws AbortProcessingException {
        YourBeanClass tmpBean = null; 
        // 事件的getComponent方法返回command link或者command button
        UIComponent tmpComponent = anEvent.getComponent();
        // 遍歷command link或者command button的父組件,出口:父組件為UIData
        while (null != tmpComponent && !(tmpComponent instanceof UIData)) {
          tmpComponent = tmpComponent.getParent();
        }
        // 如果事件組件不為空,并且父組件為UIData,那么取每行的數(shù)據(jù),如果是Bean實例,那么強制轉(zhuǎn)換
        if (tmpComponent != null && (tmpComponent instanceof UIData)) {
          Object tmpRowData = ((UIData) tmpComponent).getRowData();
          if (tmpRowData instanceof YourBeanClass) { 網(wǎng)管網(wǎng)bitsCN_com
            tmpBean = (YourBeanClass) tmpRowData;
            //TODO Implementation of your method
          }
        }
        //TODO Exception Handling if UIData not found or tmpRowBean of wrong type
     }
    }
    通過Link或者Button的參數(shù)來執(zhí)行方法
    一個典型的情景:
    表格顯示了對象的集合,需要通過點擊edit link或者button來跳轉(zhuǎn)到要編輯的記錄的詳細頁面。
    如果熟悉Struts或者其他的MVC框架,那么可能會考慮到傳輸一個主鍵來作為請求參數(shù),在請求頁面的URL中被包含。
    <a href="/appContext/someAction.do?id=1234&userAction=prepareEdit">Edit</a>
    可以使用JSTL來生成上面的內(nèi)容:
    <c:url value="someAction.do" var="url"> feedom.net
       <c:param name="id" value="1234" />
       <c:param name="userAction" value="prepareEdit" />
    </c:url>
    <a href="${url}">Edit</a>
    在JSF中,有很多方法來處理這種情況,下面列舉了三種,關于第一種解決方式還存在爭議,這里列舉出來的目的是這可能是開發(fā)人員最先想到的。
    1>     使用<f:factionListener ...>和UIData的getRowData()
    可以參考上面的集成DataTable和ActionListeners來完成。
    2>     使用f:param來傳遞參數(shù)
    使用JSF完成的第一個思路可能就是模擬已經(jīng)將參數(shù)傳遞給了鏈接??梢酝ㄟ^在commandButton或者commandLink中使用f:param標記:
    <t:dataTable var="emp" .... >

 

     <h:commandLink id="editLink" action="#{employeeAction.prepareEdit}">
     <h:outputText value="#{msg.edit}"/>
     <f:param name="id" value="#{emp.id}"/>
    </h:commandLink>

 

    然后獲取處理請求參數(shù)的句柄:

 

    FacesContext context = FacesContext.getCurrentInstance();
    Map map = context.getExternalContext().getRequestParameterMap();
    String employeeID = (String) map.get("id");
    上述的方式是可行的,但是需要開發(fā)人員處理String,可能需要自己編寫轉(zhuǎn)換器。另外,需要添加額外的代碼來獲取map保存的參數(shù)。有更簡潔的方法來完成:
    3>     使用<t:updateActionListener .../>


本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
用JSF和MyFaces上傳文件
Apache myfaces介紹和配置
JSF框架簡介與實例
使用 JavaServer Faces 構建 Apache Geronimo 應用程序,第 2 部分: 在 JavaServer Faces 中使用 Tomahawk
JSF問題集錦
Matrix - 與 Java 共舞 - [翻譯]JSF(JavaServer Faces) 介紹(jsp/servlet 技術)
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服