我有一個JSF 2.0頁面,我想允許GET參數進入,並設置一個bean的值。另外,我想允許從同一頁面上的表單修改該bean,然後使用新的GET參數重定向回到同一頁面。正如你可能期望的那樣,我希望這樣可以將頁面加入書籤。用回發覆蓋JSF viewParam,然後重定向到自己
但是,當原始GET請求包含重新驗證的bean的無效(失敗驗證)參數時,我遇到了問題。起初這個問題對我來說並不明顯,但在查看日誌時,發生了什麼變得非常明顯。當commandButton檢查新近鍵入的值的有效性時,JSF將驗證原始GET參數以及新鍵入的值。由於GET參數首先未通過驗證,因此再次失敗。不幸的是,這阻止了新的價值取代它。
即使GET值有效,它們仍會在驗證新值之前再次檢查,這是浪費時間。有沒有辦法基本上拋棄GET參數,一旦加載,無論他們是否通過驗證,以便只有當前值進行驗證?
詳情:
我包括在主頁上的搜索形式,它確實Ajax驗證(使用h:inputText
和p: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&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)
}
}