2012-12-26 7 views
6

Uso l'annotazione Servlet 3 @MultiPartConfig per implementare il caricamento del file nella mia applicazione. Ho bisogno di impostare il parametro location multipart-config al runtime (non hardcode nel parametro annotaion). C'è qualche API per l'accesso programmatico a multipart-config di servlet?Accesso programmatico a MultiPartConfig in Servlet 3.0

Grazie

risposta

5

Il @MultiPartConfig è in realtà solo un'interfaccia marcatore per il contenitore. Quando il servlet viene inizializzato, i valori di annotazione forniti vengono associati ad esso con un oggetto proxy. Quando la richiesta in entrata è multipart/form-data, le parti del caricamento vengono associate alla richiesta e il contenitore esegue il lavoro necessario in base ai valori dell'annotazione e delle parti sulla richiesta. Non è possibile per te intercettare questo processo poiché tutto ciò avviene all'interno del budello del contenitore. Tuttavia, c'è un'alternativa. Richiede l'esecuzione di un'operazione di file system una seconda volta. Poiché hai tutte le parti, puoi ricostruire il file e "ricaricarlo" nella posizione che preferisci. Potrebbe sembrare qualcosa di simile al metodo qui sotto. Tenete a mente, anche se ho provato in fretta in un servlet della mia per dimostrare il concetto non è ovviamente finito codice:

@Override 
protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) 
     throws ServletException, IOException { 

    httpServletResponse.setContentType("text/html"); 
    PrintWriter printWriter = httpServletResponse.getWriter(); 

    InputStream inputStream; 
    FileOutputStream fileOutputStream; 

    for (Part part : httpServletRequest.getParts()) { 

     inputStream = httpServletRequest.getPart(part.getName()).getInputStream(); 
     int i = inputStream.available(); 
     byte[] b = new byte[i]; 
     inputStream.read(b); 
     String fileName = ""; 

     for (String temp : part.getHeader("content-disposition").split(";")) { 
      if (temp.trim().startsWith("filename")) { 
       fileName = temp.substring(temp.indexOf('=') + 1).trim().replace("\"", ""); 
      } 
     } 

     String uploadDir = "/temp"; 
     fileOutputStream = new FileOutputStream(uploadDir + "/" + fileName); 
     fileOutputStream.write(b); 
     inputStream.close(); 
     fileOutputStream.close(); 

     printWriter.write("Uploaded file " + uploadDir + "/" + fileName + "."); 
    } 
} 
+0

Se stai usando @MultiPartConfig e hanno bisogno di un percorso di file runtime poi non hai altra opzione che "ri-caricare" le parti. –

0

ho avuto il tuo stesso problema troppo e la soluzione è semplice: standard di Servlet 3.0 upload di file è non basta: basta afferrare i vasi da Apache Commons FileUpload e il gioco è fatto

basta guardare a questo cristallo chiaro esempio con Streaming API

ServletFileUpload upload = new ServletFileUpload(); 

    // Parse the request 
    FileItemIterator iter = upload.getItemIterator(request); 
    while (iter.hasNext()) { 
     FileItemStream item = iter.next(); 
     String name = item.getFieldName(); 
     InputStream stream = item.openStream(); 
     if (item.isFormField() == false) 
      System.out.println("File field " + name + " with file name " 
      + item.getName() + " detected."); 
      FileOutputStream fos = new FileOutputStream("your_location"); 
      Streams.copy (stream, fos, true); 

     } 
    } 
+0

La domanda riguardava @MultiPartConfig e il caricamento del file, che non hai risolto. Stai anche eseguendo lo streaming da un elemento già presente nella richiesta (caricato in memoria) e ciò significa che lo stai leggendo semplicemente "ri-caricamento" di nuovo. –

+0

@Brian Reindel non è il caso, non sto "ri-caricando" di nuovo, con l'API Streaming quello che faccio è un parsing diretto della richiesta senza file temporanei o cache nella memoria. Di fatto, questo è il vantaggio dell'API Streaming: elaborazione efficiente e più rapida della memoria, consultare http://commons.apache.org/proper/commons-fileupload/streaming.html –

+0

Supponendo che tu sia in un servlet e utilizzi un contenitore, come è arrivato l'elemento del file nella richiesta? I byte sono già caricati in memoria. Non stai trasmettendo i contenuti in tempo reale mentre vengono caricati. Hai ragione sul fatto che il vantaggio del tuo approccio rispetto a FileUpload è perché in quel caso il file deve prima essere scritto sul file system. Non sono d'accordo sul fatto che dover gestire due file su disco sia problematico. Tuttavia, la domanda riguardava specificamente l'annotazione @MultiPartConfig e il percorso di runtime del file, e non semplicemente il caricamento di file in generale. –

Problemi correlati