2012-02-07 46 views
5

Sé cómo subir archivos usando Primefaces o usando Tomahawk, sin embargo, intento cargar archivos usando Apache Commons FileUpload y hasta ahora estoy teniendo un poco de camino bloquear. Aunque mi formulario use multipart/form-data, cuando envío mi formulario, el tipo de contenido se convierte en application/x-www-form-urlencoded. Aquí está mi códigoCómo obtener JSF para subir archivos 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> 

aquí está mi 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(); 
     } 
    } 
} 

Así que cuando intento imprimir el contenido tipo anterior, que mostró application/x-www-form-urlencoded. Si pongo ajax="false" a mi p:commandButton, entonces el método submit() está ni siquiera invocado, pero si saco enctype="multipart/form-data" (aún mantienen ajax="false"), entonces submit() se invoca pero no se multiparte, es application/x-www-form-urlencoded, por lo que apache commons fileupload lanzan una excepción ya que no es multiparte Parece que todo lo que hago, parece que no puedo obtener el pedido múltiple. Por favor ayuda

Respuesta

12

Así que cuando intento imprimir el contenido tipo anterior, que mostró application/x-www-form-urlencoded.

El <p:commandButton> envía por defecto una solicitud de ajax de nivel 1 XMLHttpRequest. Esto no admite multipart/form-data. Solo level 2 XMLHttpRequest lo admite, pero solo se admite en los navegadores más nuevos (aquellos que también son compatibles con HTML5) y no se implementa en JSF JS API ni en PrimeFaces JS API.


Si pongo ajax = "false" para mi t: commandButton, entonces el presente() método no es ni siquiera invocado

esta manera sin embargo, un fullworthy multipart/form-datase ser enviado. Que el método de envío no se invoca es solo porque JSF anterior a la versión 2.2 no admite multipart/form-data solicitudes fuera de la caja. JSF recopila los datos enviados por defecto utilizando request.getParameter() y getParameterMap() en la solicitud de servlet HTTP subyacente. Sin embargo, esto devolverá null cuando se haya utilizado una codificación distinta de application/x-www-form-urlencoded. Como JSF determina el método de acción invocado a partir de los datos enviados, no podrá localizarlo e invocarlo cuando los datos estén null.

En teoría, si se crea un Filter que utiliza Apache Commons FileUpload o el nuevo Servlet 3.0 request.getPart()/getParts() métodos para extraer los datos de la solicitud multipart/form-data y envuelve la petición de servlet HTTP actual con una implementación personalizada que anula los getParameter() llamadas en el que se ha proporcionado un mapeo de los datos extraídos, entonces JSF podrá realizar el trabajo necesario en función de los resultados de las llamadas getParameter(). Puede encontrar un ejemplo concreto que utiliza la API de Servlet 3.0 en this article y el mismo ejemplo que se ha modificado ligeramente para utilizar Apache Commons FileUpload en this answer.

El próximo JSF 2.2 tendrá un nuevo componente <h:inputFile> que se puede enlazar a una propiedad 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 versión final está prevista para el extremo tardío de Q1, pero está disponible actualmente como una liberación instantánea.

+0

Muchas gracias. Es muy bueno saber toda esta información. –

+0

De nada. – BalusC

+0

@BalusC Hice lo que me dijo para crear un 'Filtro', pero el método de acción no se activa si' h: form' tiene 'enctype =" multipart/form-data "'. Estoy en JSF 1.2. ¿Puedes decirme por qué sucede esto? He hecho la pregunta [aquí] (http://stackoverflow.com/questions/14242293/hcommandbutton-is-not-firing-action-if-the-hform-has-enctype-multipart-form-d) –

Cuestiones relacionadas