2012-12-14 9 views
6

Ich habe eine Client-Anwendung in Android, die HttpURLConnection verwendet, um Dateien an den Server zu senden. Der Server verwendet die Apache Commons FileUpload-API zum Analysieren der Formulardatenwerte.ServletFileUpload # parseRequest (Anfrage) gibt eine leere Liste zurück

The HttpURLConnection sendet diese Anfrage:

-----------------------------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-- 

Der Server-Code:

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; 
    } 

Das Problem in der Leitung ist List fileItems = upload.parseRequest(request);. Die zurückgegebene Liste ist leer und ich kann die Formulardatenwerte nicht abrufen.

Antwort

24

Es ist zu diesem Zeitpunkt leer, wenn Sie den Anfragetext bereits (implizit) geparst haben. Der HTTP-Anfragetext kann nur einmal gelesen/geparst werden (da der Client es nur einmal gesendet hat und nicht mehrmals sendet).

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

Sie müssen sich absolut sicher, dass Sie nicht sind machen:

Der Antrag Körper wird implizit/analysiert gelesen werden, wenn Sie eine der folgenden Methoden vor Fütterung der Antrag auf Commons Fileupload haben aufgerufen Aufruf einer dieser Methoden im Voraus (überprüfen Sie auch alle Servlet-Filter, um sicher zu sein).

Wenn Sie bereits sichergestellt haben, dass Sie das nicht tun, dann wäre die einzige andere mögliche Ursache ein falscher Begrenzungskopf und/oder falsche Zeilenumbrüche (es muss wirklich CR + LF sein und somit nicht alleine LF). Ein konkretes Beispiel finden Sie am Ende von Using java.net.URLConnection to fire and handle HTTP requests unter dem Abschnitt "Hochladen von Dateien".

+0

Ich überprüft mit: request.getInputStream() byte [] a = neues Byte [8096]; int r = 0; ServletInputStream s = request.getInputStream(); Zeichenfolge c = ""; while ((r = s.read (a))! = -1) { c + = neuer String (a) .substring (0, r); } Und erhielt die Daten in Ordnung. Das Problem ist, dass der Commond File Upload den Inhalt nicht parsen kann. – toto

+0

Nun, wenn Sie diesen 'request.getInputStream()' Aufruf entfernen, dann sollte es gut funktionieren, genau wie in meiner Antwort erklärt. – BalusC

+0

Okay, ich gehe davon aus, dass Sie vorher keine der genannten Methoden aufrufen. Dieses Problem kann dann nur bedeuten, dass Sie den richtigen Begrenzungsheader nicht festgelegt haben oder wenn Sie die falschen Zeilenumbrüche verwendet haben. Ein konkretes Beispiel finden Sie am Ende von http://stackoverflow.com/a/2793153 unter dem Abschnitt "Hochladen von Dateien". – BalusC

0

Ich lief auch in dieses Problem, aber ich konnte nichts finden, das speziell auf das Lesen des Anfrageobjekts bezogen ist. Ich habe es endlich, indem diesen Block zu arbeiten:

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

Anscheinend, wenn ich die Anfrage zu lesen versucht hatte, durch getParts() verwendet, ich habe vergessen, diese zu entfernen. Ich bin ein bisschen neu in Java, also wusste ich nicht, dass das mit dem ServletFileUpload # parseRequest in Konflikt steht. Wie auch immer, sobald ich es los war, gab die parseRequest das Array korrekt zurück.

1

Ich hatte das gleiche Problem nach dem Versuch, ich finde, dass es Inkompatibilität von Bibliotheken, Bibliothek Apache-Server mit Fileupload-Bibliothek war, so dass ich die Bibliothek entfernen und von dem Bibliotheksserver Apache importiert.

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; 

leid mein Englisch

1

Wenn Feder verwendet wird, ob es eine <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> in XML-Datei ist. Es gibt eine Funktion

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; 
    } 

"isst" die mehrteiligen Elemente. Es verursacht einen dreistündigen Schmerz.

+0

<3 .... Danke ... du rette mich. – Cataclysm

-1

mein Problem ist Apache Kontext.xml auf meinem Linux-Server enthält Context

allowCasualMultipartParsing="true" und meine HttpServlet enthält

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

ich es löschen dann richtig es funktioniert. Hoffe das wird dir helfen.

Verwandte Themen