2012-12-14 4 views
6

Ho un'applicazione client in Android che utilizza HttpURLConnection per inviare file al server. Il server utilizza l'API FileUpload di Apache Commons per analizzare i valori del modulo.ServletFileUpload # parseRequest (richiesta) restituisce una lista vuota

Il HttpURLConnection invia questa richiesta:

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

Il codice del server:

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

Il problema è nella linea List fileItems = upload.parseRequest(request);. L'elenco restituito è vuoto e non riesco a ottenere i valori dei dati del modulo.

risposta

24

Sarà vuoto in quel punto se si è già precedentemente (implicitamente) analizzato il corpo della richiesta. Il corpo della richiesta HTTP può essere letto/analizzato solo una volta (poiché il client l'ha inviato solo una volta e non lo invierà più volte).

Il corpo della richiesta saranno implicitamente lettura/analizzato quando si ha invocato uno dei seguenti metodi prima alimentando la richiesta di Commons FileUpload:

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

È necessario assolutamente sicuri che non sei chiamare in anticipo uno di questi metodi (controllare anche tutti i filtri servlet per essere sicuri).

Se hai già assicurato che non lo stai facendo, allora l'unica altra causa possibile sarebbe un'intestazione del limite errata e/o l'uso di nuove righe non corrette (deve essere davvero CR + LF e quindi non solo LF). È possibile trovare un esempio concreto e corretto nella parte inferiore di Using java.net.URLConnection to fire and handle HTTP requests, nella sezione "Caricamento di file".

+0

ho controllato utilizzando: request.getInputStream() byte [] a = new byte [8096]; int r = 0; ServletInputStream s = request.getInputStream(); Stringa c = ""; while ((r = s.read (a))! = -1) { c + = new String (a) .substring (0, r); } E ricevuto i dati ok. Il problema è che il caricamento del file di comando non può analizzare il contenuto. – toto

+0

Bene, se si rimuove la chiamata 'request.getInputStream()', allora dovrebbe funzionare correttamente, esattamente come spiegato nella mia risposta. – BalusC

+0

Ok, presumo che tu non stia chiamando in anticipo nessuno dei metodi menzionati. Questo problema può quindi significare solo che non hai impostato l'intestazione del limite corretto o quando hai utilizzato le nuove righe errate. Puoi trovare un esempio concreto e corretto nella parte inferiore di http://stackoverflow.com/a/2793153, nella sezione "Caricamento di file". – BalusC

0

Stavo correndo questo problema, ma non sono riuscito a trovare nulla che riguardasse specificamente la lettura dell'oggetto richiesta. Alla fine ho preso a lavorare per la rimozione di questo blocco:

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

quanto pare quando avevo cercato di leggere la richiesta utilizzando getParts(), ho dimenticato di rimuovere questo. Sono un po 'nuovo per Java, quindi non conoscevo questo conflitto con il ServletFileUpload # parseRequest. Ad ogni modo, una volta che mi sono sbarazzato di esso, il parametro parseRequest ha restituito correttamente l'array.

1

Ho avuto lo stesso problema dopo aver provato trovo che era incompatibilità di librerie, server Apache di libreria con libreria fileupload, quindi rimuovo la libreria e importato dal server di libreria 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; 

dispiace il mio inglese

1

Se viene utilizzata la primavera, controllare se c'è un <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> in file xml. C'è una funzione

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

"mangia" gli articoli in più parti. Provoca un dolore di tre ore.

+0

<3 .... Grazie ... mi hai salvato. – Cataclysm

-1

il mio problema è contesto apache.xml sul mio server Linux contiene Contesto

allowCasualMultipartParsing="true" e la mia HttpServlet contiene

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

cancello allora sta funzionando correttamente. Spero che questo ti possa aiutare.