2012-02-25 66 views
0

我有一個JSF 2.0頁面,我想允許GET參數進入,並設置一個bean的值。另外,我想允許從同一頁面上的表單修改該bean,然後使用新的GET參數重定向回到同一頁面。正如你可能期望的那樣,我希望這樣可以將頁面加入書籤。用回發覆蓋JSF viewParam,然後重定向到自己

但是,當原始GET請求包含重新驗證的bean的無效(失敗驗證)參數時,我遇到了問題。起初這個問題對我來說並不明顯,但在查看日誌時,發生了什麼變得非常明顯。當commandButton檢查新近鍵入的值的有效性時,JSF將驗證原始GET參數以及新鍵入的值。由於GET參數首先未通過驗證,因此再次失敗。不幸的是,這阻止了新的價值取代它。

即使GET值有效,它們仍會在驗證新值之前再次檢查,這是浪費時間。有沒有辦法基本上拋棄GET參數,一旦加載,無論他們是否通過驗證,以便只有當前值進行驗證?

詳情:

我包括在主頁上的搜索形式,它確實Ajax驗證(使用h:inputTextp:commandButton(Primefaces),標準Bean驗證,但是當我用h:commandButton這也失敗了),以確保用戶提交數據(不是空白)。一旦成功確認,該頁面使用操作重定向:

listing?faces-redirect=true&includeViewParams=true 

形式:

<h:form id="search"> 
    <p:messages id="qError" /> 
    <h:inputText value="#{pageSearchBean.search}" id="q" 
       validator="#{pageSearchBean.validateSearchNotBlank}" /> 
    <p:commandButton value="Find" action="#{pageSearchBean.searchAction}" 
        update="qError" /> 
</h:form> 

(注:如果我從h:inputText刪除validator只要我離開的問題仍然發生,甚至它在viewParam

這部分工作完美。一旦成功,頁面將按照預期重定向到listing.jsf?q=xyz,並插入傳入的值(輸入pageSearchBean,然後根據preRenderView事件進行搜索。如果我在主頁上輸入了一個無效值,那麼按鈕會正確地通知我該數據是無效的;修正之後,然後將其正確重定向到listing.jsf?q=whatever+I+typed

從GET參數的翻譯豆:現在

<f:metadata> 
    <f:viewParam name="q" value="#{pageSearchBean.search}" 
       validator="#{pageSearchBean.validateSearchNotBlank}" /> 
    <f:event type="preRenderView" listener="#{pageSearchBean.doSearch}" /> 
</f:metadata> 

,列表頁面上,我重用確切相同的搜索form/Facelet通過導入相同的Facelet,但我也顯示實際搜索模擬的結果幾乎每個搜索頁面都使用過。

原樣,頁面總是做仔細檢查

public class PageSearchBean implements Serializable 
{ 
    protected static final Log LOGGER = 
      LogFactory.getLog(PageSearchBean.class); 

    protected final List<Page> results = new ArrayList<Page>(); 
    protected String search = ""; 

    public String getSearch() 
    { 
     // all logging just to watch how things are requested 
     LOGGER.fatal(String.format("getSearch() = '%s'", search)); 

     return search; 
    } 

    public void setSearch(String search) 
    { 
     LOGGER.fatal(String.format("setSearch('%s')", search)); 

     this.search = search; 
    } 

    public List<Page> getResults() 
    { 
     return results; 
    } 

    public void doSearch() 
    { 
     LOGGER.fatal(String.format("doSearch() for '%s'", getSearch())); 

     // generate random data/search results (if we haven't already 
     // and we have search terms) 
    } 

    public String searchAction() 
    { 
     LOGGER.fatal("searchAction()"); 

     return "listing?faces-redirect=true&amp;includeViewParams=true"; 
    } 

    public void validateSearchNotBlank(FacesContext context, 
             UIComponent validate, 
             Object value) 
      throws ValidatorException 
    { 
     LOGGER.fatal(String.format("validate('%s')", value)); 

     // throws new ValidatorException when blank (null or all whitespace) 
    } 
} 

回答

1

一個沒有吸引力的解決方案是,以避免在JSF級的GET參數的驗證,並簡單地驗證在二傳手的水平值(忽略無效數據)。

由於我願意接受我的用例的未設置參數,所以這裏是一個好的解決方法。不過,我希望有一個更有用的解決方案,可以避免使用驗證混淆setter,因爲JSF頁面無法無法驗證。