2012-02-07 91 views
5

我知道如何使用Primefaces或使用Tomahawk來完成文件上傳,但是,我正在使用Apache Commons FileUpload進行文件上傳,到目前爲止,我還是有點道路塊。即使我的表單使用multipart/form-data,當我提交表單時,內容類型將變爲application/x-www-form-urlencoded。這裏是我的代碼如何使用Apache Commons FileUpload獲取JSF上傳文件

<h:body> 
    <h:form enctype="multipart/form-data"> 
     Upload File 
     <input type="file" name="file"/> 
     <p:commandButton value="Submit" action="#{viewBean.submit}"/> 
    </h:form> 
</h:body> 

這裏是我的ViewBean

@ManagedBean 
@ViewScoped 
public class ViewBean implements Serializable { 
    public void submit() { 
     String url = "/FileUploadServlet"; 
     FacesContext context = FacesContext.getCurrentInstance(); 
     try { 
      String contentType = context.getExternalContext().getRequestContentType(); 
      context.getExternalContext().dispatch(url); 
     } catch (Exception e) { 
      logger.log(Level.SEVERE, "Exception when calling Servlet", e); 
     } finally { 
      context.responseComplete(); 
     } 
    } 
} 

所以,當我嘗試打印內容類型上面,這表明application/x-www-form-urlencoded。如果我把ajax="false"p:commandButton,那麼submit()方法甚至沒有被調用,但如果我拿出enctype="multipart/form-data"(仍保留ajax="false"),然後submit()被調用,但它不是多部分,它是application/x-www-form-urlencoded,所以Apache的百科全書文件上傳拋出一個異常因爲它不是多部分。看起來像我所做的,我似乎不能得到多部分的要求。請幫助

回答

12

所以當我嘗試打印上面的內容類型時,它顯示了application/x-www-form-urlencoded。

<p:commandButton>默認發送1 XMLHttpRequest水平的AJAX請求。這是不是支持multipart/form-data。只有level 2 XMLHttpRequest支持它,但它僅在最新的瀏覽器(也支持HTML5的瀏覽器)中受支持,並且未在JSF JS API或PrimeFaces JS API中實現。


如果我把AJAX = 「假」 給我的電話號碼:的commandButton,然後提交()方法,甚至不調用

然而,這樣一個fullworthy multipart/form-data被髮送。提交方法未被調用僅僅是因爲2.2版之前的JSF不支持multipart/form-data請求出箱。 JSF默認使用底層HTTP Servlet請求中的request.getParameter()getParameterMap()收集提交的數據。但是,當使用application/x-www-form-urlencoded以外的編碼時,將返回null。由於JSF根據提交的數據確定要調用的操作方法,因此當數據爲null時,它將無法找到並調用它。

從理論上講,如果你創建一個Filter它使用Apache的百科全書文件上傳或新的Servlet 3.0 request.getPart()/getParts()方法提取從multipart/form-data請求中的數據和包裝與覆蓋getParameter()調用自定義實現當前的HTTP Servlet請求其中提供了提取的數據的映射,然後JSF將能夠根據getParameter()調用的結果完成所需的工作。您可以在this article中找到一個使用Servlet 3.0 API的具體示例,以及稍微更改爲使用this answer中的Apache Commons FileUpload的相同示例。

即將推出的JSF 2.2將會有一個新的<h:inputFile>組件,它可以綁定到一個Servlet 3.0 Part屬性。

<h:form enctype="multipart/form-data"> 
    <h:inputFile value="#{bean.file}" /> 
    <h:commandButton value="submit" action="#{bean.submit}" /> 
</h:form> 

private Part file; 

JSF 2.2最終版本計劃於第一季度的後期結束,但目前作爲一個快照發布。

+0

非常感謝。知道所有這些信息是非常好的。 – 2012-02-07 14:44:29

+0

不客氣。 – BalusC 2012-02-07 15:24:29

+0

@BalusC我按照你所說的創建了一個'Filter',但是如果'h:form'具有'enctype =「multipart/form-data」',那麼action方法不會被觸發。我在JSF 1.2中。你能告訴我爲什麼會發生這種情況嗎?我已經問了這個問題[這裏](http://stackoverflow.com/questions/14242293/hcommandbutton-is-not-firing-action-if-the-hform-has-enctype-multipart-form-d) – 2013-01-09 18:00:24

相關問題