Saltar al contenido

¿Cómo usar PrimeFaces p: fileUpload? El método Listener nunca se invoca o UploadedFile es null / arroja un error / no utilizable

Te damos la bienvenida a nuestra comunidad, en este sitio vas a encontrar la solucíon a lo que estás buscando.

Solución:

Cómo configurar y solucionar problemas depende de la versión de PrimeFaces y JSF.

Todas las versiones de PrimeFaces

Los siguientes requisitos se aplican a todas las versiones de PrimeFaces:

  1. los enctype attribute de El debe configurarse en multipart/form-data. Cuando esto está ausente, la carga ajax puede funcionar, pero el comportamiento general del navegador no está especificado y depende de la composición del formulario y la marca / versión del navegador web. Solo especifíquelo siempre para estar seguro.

  2. Cuando usas mode="advanced" (es decir, carga ajax, este es el valor predeterminado), luego asegúrese de tener un en la plantilla (maestra). Esto garantizará que se incluyan correctamente los archivos JavaScript necesarios. Esto no es necesario para mode="simple" (carga no ajax), pero esto rompería la apariencia y la funcionalidad de todos los demás componentes de PrimeFaces, por lo que no querrá perderse eso de todos modos.

  3. Cuando usas mode="simple" (es decir, carga que no es ajax), entonces ajax debe estar deshabilitado en cualquier botón / enlace de comando PrimeFaces por ajax="false", y debes usar con en lugar de .

Por lo tanto, si desea la carga (automática) de archivos con soporte ajax (tenga en cuenta el !):


     // For PrimeFaces version older than 8.x this should be fileUploadListener instead of listener.

public void upload(FileUploadEvent event) 
    UploadedFile uploadedFile = event.getFile();
    String fileName = uploadedFile.getFileName();
    String contentType = uploadedFile.getContentType();
    byte[] contents = uploadedFile.getContents(); // Or getInputStream()
    // ... Save it, now!

O si desea cargar un archivo que no sea ajax:


    
    

private transient UploadedFile uploadedFile; // +getter+setter

public void upload() 
    String fileName = uploadedFile.getFileName();
    String contentType = uploadedFile.getContentType();
    byte[] contents = uploadedFile.getContents(); // Or getInputStream()
    // ... Save it, now!

Tenga en cuenta que relacionados con ajax attributes tal como auto, allowTypes, update, onstart, oncomplete, etc son ignorado en mode="simple". Por tanto, no es necesario especificarlos en tal caso.

También tenga en cuenta que debe leer el contenido del archivo inmediatamente dentro de los métodos mencionados anteriormente y no en un método bean diferente invocado por una solicitud HTTP posterior. Esto se debe a que el contenido del archivo cargado tiene un alcance de solicitud y, por lo tanto, no está disponible en una solicitud HTTP posterior / diferente. Cualquier intento de leerlo en una solicitud posterior probablemente terminará con java.io.FileNotFoundException en el archivo temporal.


PrimeFaces 8.x

La configuración es idéntica a la información de la versión 5.x a continuación, pero si no se llama a su oyente, verifique si el método attribute se llama listener y no (como en las versiones anteriores a 8.x) fileUploadListener.


PrimeFaces 5.x

Esto hace no requiere cualquier configuración adicional si está utilizando JSF 2.2 y su faces-config.xml también se declara conforme a la versión JSF 2.2. Tú haces no necesita el filtro de carga de archivos PrimeFaces y también lo hace no necesita el primefaces.UPLOADER parámetro de contexto en web.xml. En caso de que no tenga claro cómo instalar y configurar correctamente JSF según el servidor de destino utilizado, diríjase a ¿Cómo instalar y configurar correctamente las bibliotecas JSF a través de Maven? y la sección “Instalación de JSF” de nuestra página wiki de JSF.

Sin embargo, si aún no está utilizando JSF 2.2 y no puede actualizarlo (debería ser fácil cuando ya esté en un contenedor compatible con Servlet 3.0), entonces debe registrar manualmente el filtro de carga de archivos PrimeFaces a continuación en web.xml (analizará la solicitud de varias partes y completará el mapa de parámetros de solicitud normal para que FacesServlet puede seguir trabajando como de costumbre):


    primeFacesFileUploadFilter
    org.primefaces.webapp.filter.FileUploadFilter


    primeFacesFileUploadFilter
    facesServlet

los valor de facesServlet debe coincidir exactamente con el valor en el entrada de la javax.faces.webapp.FacesServlet en el mismo web.xml. Entonces, si es, por ejemplo, Faces Servlet, luego debe editarlo en consecuencia para que coincida.


PrimeFaces 4.x

La misma historia que PrimeFaces 5.x se aplica también a 4.x.

Solo existe un problema potencial para obtener el contenido del archivo cargado por UploadedFile#getContents(). Esto volverá null cuando se usa la API nativa en lugar de Apache Commons FileUpload. Necesitas usar UploadedFile#getInputStream() en lugar de. Consulte también ¿Cómo insertar una imagen cargada desde p: fileUpload como BLOB en MySQL?

Otro problema potencial que se manifestará con la API nativa es cuando el componente de carga está presente en un formulario en el que se activa una solicitud ajax “regular” diferente que no procesa el componente de carga. Consulte también La carga de archivos no funciona con AJAX en PrimeFaces 4.0 / JSF 2.2.x – javax.servlet.ServletException: el tipo de contenido de la solicitud no es un multipart / form-data.

Ambos problemas también se pueden resolver cambiando a Apache Commons FileUpload. Consulte la sección PrimeFaces 3.x para obtener más detalles.


PrimeFaces 3.x

Esta versión no es compatible con la carga de archivos nativos JSF 2.2 / Servlet 3.0. Debe instalar manualmente Apache Commons FileUpload y registrar explícitamente el filtro de carga de archivos en web.xml.

Necesita las siguientes bibliotecas:

  • commons-fileupload.jar
  • commons-io.jar

Esos deben estar presentes en la ruta de clases en tiempo de ejecución de la aplicación web. Al usar Maven, asegúrese de que tengan al menos un ámbito de tiempo de ejecución (el ámbito de compilación predeterminado también es bueno). Cuando transporte manualmente los JAR, asegúrese de que terminen en /WEB-INF/lib carpeta.

El detalle del registro del filtro de carga de archivos se puede encontrar en la sección PrimeFaces 5.x aquí arriba. En caso de que esté usando PrimeFaces 4+ y le gustaría usar explícitamente Apache Commons FileUpload en lugar de la carga de archivos nativos JSF 2.2 / Servlet 3.0, entonces necesita junto a las bibliotecas mencionadas y filtrar también el siguiente parámetro de contexto en web.xml:


    primefaces.UPLOADER
    commons


Solución de problemas

En caso de que aún no funcione, aquí hay otras posibles causas no relacionadas con la configuración de PrimeFaces:

  1. Solo si está utilizando el filtro de carga de archivos PrimeFaces: hay otro Filter en tu aplicación web que se ejecuta antes de el filtro de carga de archivos PrimeFaces y ya ha consumido el cuerpo de la solicitud, por ejemplo, llamando getParameter(), getParameterMap(), getReader(), etcétera. El cuerpo de una solicitud solo se puede analizar una vez. Cuando llama a uno de esos métodos antes de que el filtro de carga de archivos haga su trabajo, entonces el filtro de carga de archivos obtendrá un cuerpo de solicitud vacío.

    Para solucionar este problema, debe poner el del filtro de carga de archivos antes de el otro filtro en web.xml. Si la solicitud no es una multipart/form-data solicitud, entonces el filtro de carga de archivos continuará como si no hubiera pasado nada. Si usa filtros que se agregan automágicamente porque usan anotaciones (por ejemplo, PrettyFaces), es posible que deba agregar un orden explícito a través de web.xml. Consulte Cómo definir el orden de ejecución del filtro de servlets mediante anotaciones en WAR

  2. Solo si está utilizando el filtro de carga de archivos PrimeFaces: hay otro Filter en tu aplicación web que se ejecuta antes de el filtro de carga de archivos PrimeFaces y ha realizado una RequestDispatcher#forward() llama. Por lo general, los filtros de reescritura de URL como PrettyFaces hacen esto. Esto desencadena el FORWARD despachador, pero los filtros escuchan por defecto en REQUEST despachador solamente.

    Para solucionar este problema, debe colocar el filtro de carga de archivos PrimeFaces antes de el filtro de reenvío, o para reconfigurar el filtro de carga de archivos PrimeFaces para escuchar FORWARD despachador también:

     
         primeFacesFileUploadFilter
         facesServlet
         REQUEST
         FORWARD
     
    
  3. Hay un anidado . Esto es ilegal en HTML y el comportamiento del navegador no está especificado. La mayoría de las veces, el navegador no enviará los datos esperados al enviarlos. Asegúrate de no anidar . Esto es completamente independientemente de la forma enctype. Simplemente no anide formas en absoluto.

Si aún tiene problemas, depure el tráfico HTTP. Abra el conjunto de herramientas para desarrolladores del navegador web (presione F12 en Chrome / Firebug23 + / IE9 +) y verifique la sección Red / Red. Si la parte HTTP se ve bien, depure el código JSF. Ponga un punto de ruptura en FileUploadRenderer#decode() y avanzar desde allí.


Guardando el archivo subido

Después de que finalmente lo hayas hecho funcionar, tu próxima pregunta probablemente será como “¿Cómo / dónde guardo el archivo cargado?”. Bueno, continúe aquí: Cómo guardar el archivo cargado en JSF.

¿También estás usando caras bonitas? Luego configure el despachador en FORWARD:


   PrimeFaces FileUpload Filter
   Faces Servlet
   FORWARD

Un punto que noté con Primefaces 3.4 y Netbeans 7.2:

Elimine los parámetros autocompletados de Netbeans para la función handleFileUpload ie (evento) de lo contrario, el evento podría ser null.


    

    

Calificaciones y reseñas

Recuerda algo, que tienes autorización de añadir una valoración certera si chocaste tu dilema justo a tiempo.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 4)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *