2011-11-15 245 views
2

我有一個頁面,有一個輸入欄和一個按鈕。單擊該按鈕會根據輸入字段中輸入的值生成PDF報告。我的問題在於,輸入字段需要一些特殊的格式,而且我有一個驗證器,如果所需的格式不存在,將會觸發。如何在提交表單提交文件下載後清除驗證錯誤?

假設我在字段中輸入了一個無效值,然後單擊該按鈕。由於驗證,PDF報告將不會生成,並且該字段會如預期的那樣變爲紅色。但是,然後輸入一個正確的值(字段仍爲紅色)並按下按鈕。報告生成但字段保持紅色。這是因爲我在PDF生成後使用了FacesContext.getCurrentInstance()。responseComplete(),所以正常的Faces生命週期已被繞過,驗證錯誤的清除不再針對此請求觸發。

如何生成PDF報告但仍強制Faces確定應清除驗證錯誤?謝謝!

回答

0

這不能在一個HTTP響應中完成。您需要讓客戶端發送兩個請求,以便您可以返回兩個響應;一個清除錯誤,另一個返回PDF。你只需要在bean的action方法中做一些返工,並且可能添加一個servlet文件服務。

基本上,您需要將PDF存儲在本地(臨時)磁盤位置或可能存儲在內存中,並讓JSF有條件地呈現一些JavaScript,然後下載PDF。可以通過指向本地磁盤位置的servlet或其他webapp上下文來下載PDF。

E.g.

<h:form> 
    ... 
    <h:commandButton value="Download" action="#{bean.submit}" /> 
    <h:panelGroup rendered="#{not empty bean.pdfURL}"> 
     <script>window.location = '#{bean.pdfURL}';</script> 
    </h:panelGroup> 
</h:form> 

public void submit() { 
    // Create PDF and store as byte[] in memory, or as File on disk. 
    // Then create an unique URL to the PDF. 
    pdfURL = externalContext.getRequestContextPath() + "/pdf/" + pdfID; 
} 

應該產生一個成功的形式在以下提交(這也應該清除驗證錯誤!)

<script>window.location = '/contextname/pdf/uniquefilename.pdf';</script> 

如果您註冊了/some/path/to/pdf作爲另一個webapp上下文在服務器配置中,那麼你可以將File存儲在那裏,它將被下載。但是,如果你不能,因爲你必須在服務器配置無法控制,那麼你需要創建它映射在/pdf/*的URL模式和不喜歡的東西在doGet()方法如下一個servlet:

String filename = request.getPathInfo().substring(1); 
File pdf = new File("/some/path/to/pdf", filename); 

response.setHeader("Content-Type", "application/pdf"); 
response.setHeader("Content-Length", String.valueOf(file.length())); 

InputStream input = new FileInputStream(pdf); 
OutputStream output = response.getOutputStream(); 
// Now just write input to output. 
+0

感謝BalusC,我認爲也許可以通過一些JSF技巧在一個請求中完成它。我明天肯定會給你一個想法,謝謝。 – user790399