背景
使用JDeveloper 11.1.2.3如下創建使用fileDownloadActionListener
報告下載按鈕:預防房顫:fileDownloadActionListener動作事件
<af:commandButton text="Run Report" id="submitReport">
<af:fileDownloadActionListener method="#{reportBean.run}"/>
</af:commandButton>
在此JSF頁面的頂部如下:
<f:view afterPhase="#{validationBean.afterPhase}" ...>
...
<af:form id="f1">
<f:event listener="#{validationBean.postValidate}" type="postValidate"/>
這個想法是驗證Bean可以捕獲任何驗證問題如下:
public void afterPhase(javax.faces.event.PhaseEvent phaseEvent) {
if (phaseEvent.getPhaseId() == PhaseId.RENDER_RESPONSE) {
FacesContext context = phaseEvent.getFacesContext();
FacesMessage.Severity severity = context.getMaximumSeverity();
if (isSevereError(severity)) {
context.getExternalContext().getSessionMap().put(ERROR_FLAG_NAME, true);
}
}
}
這個按預期工作。當用戶按下按鈕,但窗體有錯誤時,validationError
會話變量設置爲true
。如果表單參數有錯誤,這應該允許框架防止生成報告。
問題
的validationError
會話變量用於通過報告bean的運行方法如下:
public void run(FacesContext facesContext, OutputStream outputStream) {
Object error = facesContext.getExternalContext().getSessionMap().get(ERROR_FLAG_NAME);
if(error != null && error != Boolean.TRUE) {
Report report = null;
try {
report = getReport();
report.setOutputStream(outputStream);
configure(report.getParameters());
report.run();
} catch (Exception e) {
if (report != null && facesContext != null) {
report.publish(e);
}
}
}
else {
facesContext.getExternalContext().getSessionMap().remove(ERROR_FLAG_NAME);
facesContext.renderResponse();
}
}
當在頁面驗證錯誤時,執行facesContext.renderResponse();
代碼,但所得到的網頁是空白的。沒有例外記錄。沒有錯誤產生。
問題,以避免這種情況
一種方法是使用一個隱藏按鈕,自定義的Java,以及一些JavaScript,如在以下頁面描述:
- http://jobinesh.blogspot.ca/2010/01/customizing-execution-of-to-validate.html
- http://tompeez.wordpress.com/2011/07/14/validate-data-before-export-via-afexportcollectionactionlistener-or-affiledownloadactionlistener/
但是,這種機制很複雜。如果頁面可以像往常一樣呈現,我想到的解決方案將起作用。
如何在af:fileDownloadActionListener
事件觸發後強制頁面呈現?