2012-02-07 11 views
5

So come eseguire il caricamento di file usando Primefaces o usando Tomahawk, tuttavia, sto cercando di caricare file usando Apache Commons FileUpload e fino ad ora ho un po 'di strada bloccare. Anche se il mio modulo utilizza multipart/form-data, quando invio il mio modulo, il tipo di contenuto diventa application/x-www-form-urlencoded. Qui è il mio codiceCome caricare JSF con Apache Commons FileUpload

<h:body> 
    <h:form enctype="multipart/form-data"> 
     Upload File 
     <input type="file" name="file"/> 
     <p:commandButton value="Submit" action="#{viewBean.submit}"/> 
    </h:form> 
</h:body> 

Ecco il mio ViewBean

@ManagedBean 
@ViewScoped 
public class ViewBean implements Serializable { 
    public void submit() { 
     String url = "/FileUploadServlet"; 
     FacesContext context = FacesContext.getCurrentInstance(); 
     try { 
      String contentType = context.getExternalContext().getRequestContentType(); 
      context.getExternalContext().dispatch(url); 
     } catch (Exception e) { 
      logger.log(Level.SEVERE, "Exception when calling Servlet", e); 
     } finally { 
      context.responseComplete(); 
     } 
    } 
} 

Così, quando provo a stampare tipo sopra il contenuto, ha mostrato application/x-www-form-urlencoded. Se metto ajax="false" al mio p:commandButton, allora il metodo submit() è nemmeno invocato, ma se prendo enctype="multipart/form-data" (ancora mantenere ajax="false"), quindi submit() viene invocato, ma non è più parti, è application/x-www-form-urlencoded, così comuni apache fileupload generano un'eccezione dal momento che non è multipart. Sembra che qualunque cosa faccia, non riesco a ottenere il requrest in più parti. Per favore aiuto

risposta

12

Così quando provo a stampare il tipo di contenuto sopra, mostrava application/x-www-form-urlencoded.

Il <p:commandButton> invia per default una richiesta AJAX di livello 1 XMLHttpRequest. Questo è non supporto multipart/form-data. Solo level 2 XMLHttpRequest lo supporta, ma è supportato solo nei browser più recenti (quelli che supportano anche HTML5) e non è implementato nell'API JSF JSF né nell'API JS PrimeFaces.


Se metto ajax = "false" al mio p: commandButton, poi il submit() metodo non è nemmeno invocato

In questo modo però un fullworthy multipart/form-datasarà essere inviato. Il fatto che il metodo submit non venga richiamato è solo perché JSF precedente alla versione 2.2 non supporta le richieste multipart/form-data. JSF raccoglie i dati inviati per impostazione predefinita utilizzando request.getParameter() e getParameterMap() sulla richiesta del servlet HTTP sottostante. Tuttavia, questo restituirà null quando è stata utilizzata una codifica diversa da application/x-www-form-urlencoded. Poiché JSF determina il metodo di azione da richiamare in base ai dati inviati, non sarà in grado di individuarlo e richiamarlo quando i dati sono null.

In teoria, se si crea una Filter che utilizza Apache Commons FileUpload o il nuovo Servlet 3.0 request.getPart()/getParts() metodi per estrarre i dati dalla richiesta multipart/form-data e avvolge la richiesta servlet HTTP corrente con un'implementazione personalizzata che sostituisce i getParameter() chiamate in cui è stata fornita una mappatura dei dati estratti, quindi JSF sarà in grado di eseguire il lavoro richiesto in base ai risultati delle chiamate getParameter(). È possibile trovare un esempio concreto utilizzando l'API Servlet 3.0 in this article e lo stesso esempio che è leggermente modificato per utilizzare Apache Commons FileUpload in this answer.

Il prossimo JSF 2.2 avrà un nuovo componente <h:inputFile> che è associabile a una proprietà Servlet 3.0 Part.

<h:form enctype="multipart/form-data"> 
    <h:inputFile value="#{bean.file}" /> 
    <h:commandButton value="submit" action="#{bean.submit}" /> 
</h:form> 

con

private Part file; 

JSF 2.2 versione finale è prevista per la fine del fine del 1 ° trimestre, ma è attualmente disponibile come versione istantanea.

+0

Grazie mille. È molto bello sapere tutte queste informazioni. –

+0

Prego. – BalusC

+0

@BalusC Ho fatto come hai detto di creare un 'Filtro', ma il metodo di azione non si attiva se' h: form' ha 'enctype =" multipart/form-data "'. Sono in JSF 1.2. Puoi dirmi perché questo sta accadendo? Ho posto la domanda [qui] (http://stackoverflow.com/questions/14242293/hcommandbutton-is-not-firing-action-if-the-hform-has-enctype-multipart-form-d) –