2012-12-14 27 views
6

我在Android中有一個客戶端應用程序,它使用HttpURLConnection將文件發送到服務器。服務器使用Apache Commons FileUpload API來解析表單數據值。ServletFileUpload#parseRequest(request)返回一個空的列表

HttpURLConnection發送該請求:

-----------------------------4912995119421 
Content-Disposition: form-data; name="deviceid" 

9428103 
-----------------------------4912995119421 
Content-Disposition: form-data; name="countryid" 

598 
-----------------------------4912995119421 
Content-Disposition: form-data; name="number" 

98621360 
-----------------------------4912995119421 
Content-Disposition: form-data; name="file"; filename="2012-12-08 17.42.18.jpg" 
Content-Type: image/jpeg 

ÿØÿá1 Exif II*  
     @  °  ª  
    ²    ¼  Ä (  1 Ì 2 Ø   i‡ ì %ˆ \ n SAMSUNG GT-S5360L H  H  S5360LUHLB1 2012:12:08 17:42:18 š‚ î ?‚ ö "ˆ  'ˆ È ? 0220? þ ?  ‘  ’ & ’  
’ .   0100     @   °   > £  ¤  ¤  ¤ 6 ¤      
    2012:12:08 17:42:18 2012:12:08 17:42:18  
    d    R98  0100       (   ¤  T.  ÿØÿà JFIF  ÿÛ C @@ÿÛ 
-----------------------------4912995119421-- 

服務器代碼:

String contentType = request.getContentType(); 
    if ((contentType.indexOf("multipart/form-data") == -1)) { 
     response.setStatus(HttpServletResponse.SC_NOT_FOUND); 
     return; 
    } 


    long maxFileSize = (2 * 1024 * 1024); 

    int maxMemSize = (2 * 1024 * 1024); 

    DiskFileItemFactory factory = new DiskFileItemFactory(); 
    // maximum size that will be stored in memory 
    factory.setSizeThreshold(maxMemSize); 

    // Create a new file upload handler 
    ServletFileUpload upload = new ServletFileUpload(factory); 
    // maximum file size to be uploaded. 

    upload.setSizeMax(maxFileSize); 

    List fileItems = upload.parseRequest(request); 
    Iterator i = fileItems.iterator(); 


    //leo primero todas las variables. 

    int deviceID = 0; 
    int countryID = 0; 
    String phoneNumber = ""; 



    while (i.hasNext()) { 
     FileItem fi = (FileItem) i.next(); 

     if (fi.isFormField()) { 
      String variable = fi.getFieldName(); 
      if (variable.equals("deviceid")) { 
       deviceID = Integer.parseInt(fi.getString()); 
      } else if (variable.equals("countryid")) { 
       countryID = Integer.parseInt(fi.getString()); 
      } else if (variable.equals("number")) { 
       phoneNumber = String.valueOf(Long.parseLong(fi.getString())); 
      } 

     } 

    } 

    if (deviceID == 0 || countryID == 0 || phoneNumber.equals("")) { 
     response.setStatus(HttpServletResponse.SC_NOT_FOUND); 
     return; 
    } 

的問題是在該行List fileItems = upload.parseRequest(request);。 返回的列表是空的,我無法獲取表單數據值。

回答

24

如果您已經(隱式)預先解析請求主體,那麼它將在此處爲空。 HTTP請求正文只能被讀取/解析一次(因爲客戶端只發送一次,不會多次發送)。

請求體將被隱式讀取/解析當你調用任何下列方法之前餵養要求通用FileUpload:

request.getParameter(); 
request.getParameterMap(); 
request.getParameterNames(); 
request.getParameterValues(); 
request.getReader(); 
request.getInputStream(); 

你需要絕對確保你事先調用其中任何一種方法(同時檢查所有的servlet過濾器)。

如果你已經確保你沒有這樣做,那麼唯一的其他可能的原因將是一個不正確的邊界標題和/或使用不正確的換行符(它真的是CR + LF,因此不是單獨的LF )。您可以在Using java.net.URLConnection to fire and handle HTTP requests底部的「上傳文件」部分找到一個具體且恰當的示例。

+0

我檢查使用:request.getInputStream() byte [] a = new byte [8096]; int r = 0; ServletInputStream s = request.getInputStream(); String c =「」; ((r = s.read(a))!= -1)c + = new String(a).substring(0,r); } 並收到數據ok。 問題是commond文件上傳不能解析內容。 – toto

+0

那麼,如果你刪除'request.getInputStream()'調用,那麼它應該可以正常工作,正如我的答案中所解釋的那樣。 – BalusC

+0

好吧,我假設你沒有事先調用任何提及的方法。這個問題只能意味着你沒有設置正確的邊界標題,或者你使用了錯誤的換行符。您可以在http://stackoverflow.com/a/2793153底部的「上傳文件」部分找到一個具體且恰當的示例。 – BalusC

0

我也遇到了這個問題,但我找不到任何與讀取請求對象特別相關的東西。我終於得到它通過刪除此塊的工作:

@MultipartConfig(
    location="/tmp", 
    fileSizeThreshold=1024*1024, 
    maxFileSize=1024*1024*5, 
    maxRequestSize=1024*1024*5*5 
) 

顯然,當我一直想讀通過的getParts(),我忘了刪除此請求。我有點新來java,所以我不知道這與ServletFileUpload#parseRequest衝突。無論如何,一旦我擺脫它,parseRequest正確地返回數組。

1

我嘗試過後發現這個問題,我發現它是庫,庫apache服務器與fileupload庫不兼容,所以我刪除庫並從庫服務器Apache中導入。

imports: 
import org.apache.tomcat.util.http.fileupload.FileItem; 
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory; 
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload; 

對不起我的英語

1

如果使用彈簧,檢查是否有在XML文件中的<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />。有一個功能

protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException { 
     if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) { 
      if (request instanceof MultipartHttpServletRequest) { 
       logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " + 
         "this typically results from an additional MultipartFilter in web.xml"); 
      } 
      else { 
       return this.multipartResolver.resolveMultipart(request); 
      } 
     } 
     // If not returned before: return original request. 
     return request; 
    } 

「吃」多部分項目。它會導致三個小時的疼痛。

+0

<3 ....謝謝你...你救了我。 – Cataclysm

-1

我的問題是apache環境。我的Linux服務器上的XML包含上下文

allowCasualMultipartParsing="true"和我的HttpServlet包含

@MultipartConfig(fileSizeThreshold=1024*1024*2,maxFileSize=1024*1024*50,maxRequestSize=1024*1024*50) 

我刪除它,然後它的正常工作。希望這會幫助你。