2010-07-26 24 views
54

是否有任何方便的方法來讀取和解析傳入請求中的數據?在Servlet中解析傳入的多部分/表單數據參數的便捷方法

E.g客戶端啓動後請求

URLConnection connection = new URL(url).openConnection(); 
connection.setDoOutput(true); 
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 
PrintWriter writer = null; 
try { 
    OutputStream output = connection.getOutputStream(); 
    writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important! 
    // Send normal param. 
    writer.println("--" + boundary); 
    writer.println("Content-Disposition: form-data; name=\"param\""); 
    writer.println("Content-Type: text/plain; charset=" + charset); 
    writer.println(); 
    writer.println(param); 

我不能使用request.getParameter("paramName")得到PARAM。下面的代碼

BufferedReader reader = new BufferedReader(new InputStreamReader(
    request.getInputStream())); 
    StringBuilder sb = new StringBuilder(); 
    for (String line; (line = reader.readLine()) != null;) { 
    System.out.println(line); 

    } 

但是顯示我

-----------------------------29772313742745 
Content-Disposition: form-data; name="name" 
J.Doe 
-----------------------------29772313742745 
Content-Disposition: form-data; name="email" 
[email protected] 
-----------------------------29772313742745 

什麼是解析傳入的請求的最佳方式的內容?我不想寫我自己的解析器,可能有一個現成的解決方案。

回答

71

multipart/form-data編碼的請求確實不是默認支持的3.0版之前的Servlet API。 Servlet API默認使用application/x-www-form-urlencoded編碼解析​​參數。當使用不同的編碼時,request.getParameter()調用將全部返回null。當你已經使用Servlet 3.0(Glassfish 3Tomcat 7等)時,你可以使用HttpServletRequest#getParts()來代替。有關擴展示例,另請參閱this blog

在Servlet 3.0之前,解析multipart/form-data請求的de facto標準將使用Apache Commons FileUpload。請仔細閱讀用戶指南常見問題部分,瞭解如何使用它。我已經在here之前發佈了一個代碼示例的答案(它也包含一個針對Servlet 3.0的示例)。

+1

要小心。 apache網站上的一些文檔是錯誤的。例如,他們說你可以在一個FileItemFactory對象上調用setRepository(),因爲任何實現FileItemFactory的對象只有一個方法:createItem()。所以一定要閱讀javadocs。 – Cheruvim 2014-01-22 23:09:07

+1

'getParts()'總是返回零個項目。爲什麼很難在Java和Servlet 3.0中檢索多部分表單?不敢相信! – basZero 2016-09-23 13:08:37

+0

@basZero:重複問題的答案已經解釋了它何時爲空。 – BalusC 2016-09-23 13:15:15

16

解決方案:

解決方案A:

  1. 下載http://www.servlets.com/cos/index.html
  2. 調用getParameters()上com.oreilly.servlet.MultipartRequest

解決方案B:

  1. 下負載http://jakarta.Apache.org/commons/fileupload/
  2. 調用readHeaders()在 org.apache.commons.fileupload.MultipartStream

溶液C:

  1. 下載http://users.boone.net/wbrameld/multipartformdata/
  2. 調用的getParameter上 com.bigfoot.bugar.servlet.http.MultipartFormData

解決方案D:

使用Struts。 Struts 1.1自動處理它。

參考:http://www.jguru.com/faq/view.jsp?EID=1045507

+4

請提供一些解決方案,因爲此鏈接將來可能會隨時被淘汰。這會吸引負面評價。 – 2014-03-02 07:11:48

2

並不總是有一個上傳的前一個servlet(我可以使用例如過濾器)。 或者可能是相同的控制器(同樣是一個過濾器或一個servelt)可以提供很多操作,所以我認爲依賴於該servlet配置來使用getPart方法(僅適用於Servlet API> = 3.0),我不知道,我不喜歡。

一般來說,我更喜歡獨立的解決方案,能夠獨自生活,在這種情況下,http://commons.apache.org/proper/commons-fileupload/就是其中之一。

List<FileItem> multiparts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request); 
    for (FileItem item : multiparts) { 
     if (!item.isFormField()) { 
      //your operations on file 
     } else { 
      String name = item.getFieldName(); 
      String value = item.getString(); 
      //you operations on paramters 
     } 
} 
相關問題