2014-01-15 89 views
0

我使用的是<h:selectOneMenu>,並附加了valueChangeListener屬性。監聽器調用一些業務代碼(例如數據庫查詢)來基於新的選定值加載其他數據。我注意到,當代碼中發生(意外)異常時,AbortProcessingException會包裝原始異常,然後是日誌,但不會通知用戶出現問題。通過聽衆調用時應如何處理技術例外

有沒有辦法在調用偵聽器時通知用戶某些意外事件發生了致命錯誤?

我從Differences between action and actionListener知道一個動作會更適合這樣的表達,但是我不能在<h:selectOneMenu>中設置動作,而只能是一個偵聽器。我應該如何更改我的頁面,以便在所選項目更改時調用「真實業務操作」(允許失敗的操作)?

回答

0

JSF有一個FacesMessages的概念。這些都是在<h:messages />標籤的幫助下呈現的。經常做的事情是捕捉任何異常,並將一個javax.faces.application.FacesMessage添加到FacesContext中,爲用戶提供他需要的信息(另請參閱"catch exception in managed bean and show message on screen in jsf2")。

FacesContext.getCurrentInstance().addMessage(
    null, 
    new FacesMessage(Severity.INFO, <see details for possible fills>) 
); 

也有推出一個自己的ExceptionHandlerFactory的方式 - 如文章"Global handling of all unchecked/unexpected exceptions in JSF 2"中提到的 - 你檢查這種可能性? (另見this answer/comment to BalcusCs article

作爲可能性二,您可以例如在selectOneMenu得到了改變後使用一個Ajax請求,並觸發與另一個監聽器(它在以後執行,則ValueChangedListener並給出AjaxBehaviorEvent作爲參數,我覺得這是更有幫助的BL - 側)。下面是一些元代碼...

<h:selectOneMenu ...> 
    <f:selectItems ... /> 
    <f:ajax render="..." execute="..." listener="..." /> 
</h:selectOneMenu> 

希望它可以幫助...

+0

我不想內'嘗試{...}趕上(例外){方法addMessage(「錯誤包裝每個監聽器「);}'。我期望與簡單操作相同的行爲:任何致命/意外的異常只能被Web服務器捕獲並顯示錯誤頁面。 – Gaetan

+0

此外,解決方案2仍然調用偵聽器,並且JSF將吞服偵聽器引發的任何異常。 – Gaetan

+0

總是樂意幫助你實現你的目標。沒錯,監聽器通常會吞噬異常,所以解決方案1可以幫助您捕獲異常並通過FacesMessages向用戶發送單個消息。如果你想要一個「一刀切」的解決方案,請調查「ExceptionHandlerFactory」解決方案。你也是正確的,即F:Ajax的監聽器「只是一個傾聽者」,而是因爲它是在生命週期的其他部分執行,它可能給你更多的可能性,例如轉發/重定向。這是你的項目,你的決定。 –