Cómo utilizar PrimeFaces p:fileUpload? Escucha método nunca se invoca o UploadedFile es null / lanza un error / no utilizable

Estoy tratando de cargar un archivo con PrimeFaces, pero la fileUploadListener método no se invoca después de la subida de los acabados.

Aquí está a la vista:

<h:form>
    <p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload}"
        mode="advanced" 
        update="messages"
        sizeLimit="100000" 
        allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>

    <p:growl id="messages" showDetail="true"/>
</h:form>

Y el frijol:

@ManagedBean
@RequestScoped
public class FileUploadController {

    public void handleFileUpload(FileUploadEvent event) {
        FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

}

He colocado un punto de interrupción en el método, pero nunca llamó. Cuando se utiliza mode="simple" y ajax="false", se ha invocado, pero quiero que funcione en el modo avanzado. Estoy usando Netbeans y Glassfish 3.1.

10 Kommentare

  1. 214

    Cómo configurar y solucionar problemas de <p:fileUpload> depende de PrimeFaces versión.

    Todos PrimeFaces versiones

    Los siguientes requisitos se aplican a todos los PrimeFaces versiones:

    1. La enctype atributo de la <h:form> necesita ser configurada para multipart/form-data. Cuando este está ausente, el ajax carga puede funcionar, pero en general el comportamiento del explorador es indeterminado y depende de la forma de composición y webbrowser hacer/versión. Acaba de especificar siempre en el lado seguro.

    2. Cuando se utiliza mode="advanced" (es decir, ajax upload, este es el valor predeterminado), a continuación, asegúrese de que usted tiene una <h:head> en el (maestro) de la plantilla. Esto asegurará que los archivos JavaScript se incluyen correctamente. Esto no es necesario para mode="simple" (no-ajax upload), pero esto podría romper la mirada n’visual y la funcionalidad de todos los otros componentes de PrimeFaces, por lo que no se quiere perder de todos modos.

    3. Cuando se utiliza mode="simple" (es decir, no-ajax upload), entonces ajax debe ser desactivado en cualquier PrimeFaces botones de comando/enlaces por ajax="false", y debe utilizar <p:fileUpload value> con <p:commandButton action> en lugar de <p:fileUpload fileUploadListener>.

    Así que, si quieres (auto) carga de archivos con soporte para ajax (mente la <h:head>!):

    <h:form enctype="multipart/form-data">
        <p:fileUpload fileUploadListener="#{bean.upload}" auto="true" />
    </h:form>
    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 quieres no-ajax file upload:

    <h:form enctype="multipart/form-data">
        <p:fileUpload mode="simple" value="#{bean.uploadedFile}" />
        <p:commandButton value="Upload" action="#{bean.upload}" ajax="false" />
    </h:form>
    private UploadedFile uploadedFile; //+getter+setter
    
    public void upload() {
        String fileName = uploadedFile.getFileName();
        String contentType = uploadedFile.getContentType();
        byte[] contents = uploadedFile.getContents(); //Or getInputStream()
        //... Save it, now!
    }

    Nota de que el ajax relacionados con atributos tales como auto, allowTypes, update, onstart, oncomplete, etc son ignorado en mode="simple". Así que no hace falta especificar en tal caso.

    También tenga en cuenta que usted debe leer el contenido del archivo inmediatamente dentro de los citados métodos y no en otro bean método invocado por una posterior solicitud HTTP. Esto es debido a que el archivo subido contenido es un ámbito de petición y por lo tanto no está disponible en una tarde/diferentes solicitud HTTP. Cualquier intento de leer en una solicitud posterior más probable es que terminan con java.io.FileNotFoundException en el archivo temporal.


    PrimeFaces 5.x

    Esto no requiere ninguna configuración adicional si usted está usando JSF 2.2 y su faces-config.xml también se declara conforme JSF 2.2 versión. Usted no necesita la PrimeFaces cargar el archivo de filtro en todo. En caso de que no está claro cómo instalar y configurar JSF dependiendo del servidor de destino utilizado, de la cabeza a La manera correcta de instalar y configurar JSF de bibliotecas a través de Maven? y «La instalación de JSF» sección de nuestro JSF página de la wiki.

    Si usted está sin embargo no usando JSF 2.2 todavía y no se puede actualizar (debe ser sin esfuerzo cuando ya en un Servlet 3.0 compatible contenedor), entonces usted necesita para registrar manualmente el siguiente PrimeFaces cargar el archivo de filtro en web.xml (se va a analizar la parte de varias solicitar y rellenar la solicitud regular mapa de parámetro para que FacesServlet puede seguir trabajando como de costumbre):

    <filter>
        <filter-name>primeFacesFileUploadFilter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>primeFacesFileUploadFilter</filter-name>
        <servlet-name>facesServlet</servlet-name>
    </filter-mapping>

    La <servlet-name> valor de facesServlet debe coincidir exactamente con el valor en el <servlet> entrada de la javax.faces.webapp.FacesServlet en el mismo web.xml. Por lo tanto, si por ejemplo,Faces Servlet, entonces usted necesita para editar en consecuencia para que coincida.


    PrimeFaces 4.x

    La misma historia como PrimeFaces 5.x se aplica en 4.x así.

    Sólo hay un potencial problema en conseguir el archivo cargado de contenido por UploadedFile#getContents(). Esto devolverá null cuando los nativos de la API se utiliza en lugar de Apache Commons FileUpload. Usted necesidad de utilizar UploadedFile#getInputStream() lugar. Véase también Cómo insertar imagen cargada de p:fileUpload como BLOB de MySQL?

    Otro problema potencial con la API nativa se manifiesta cuando la carga componente está presente en un formulario en el que diferentes «normal» de la petición ajax se desencadena que no proceso la carga de los componentes. Véase también Carga de archivos no funciona con AJAX en PrimeFaces 4.0/JSF 2.2.x – javax.servlet.ServletException: La solicitud de tipo de contenido no es un multipart/form-data.

    Tanto de los problemas también se puede resolver cambiando de Apache Commons FileUpload. Ver PrimeFaces 3.x de la sección de detalle.


    PrimeFaces 3.x

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

    Usted necesita las siguientes bibliotecas:

    Aquellos que deben estar presentes en la webapp tiempo de ejecución de la ruta de clases. Cuando se utiliza Maven, asegúrese de que estén al menos en tiempo de ejecución ámbito (ámbito predeterminado de compilar también es bueno). Cuando manualmente llevar alrededor de los Frascos, asegúrese de que terminen en /WEB-INF/lib carpeta.

    Cargar el archivo de registro de filtro de detalle se puede encontrar en PrimeFaces 5.x la sección de arriba. En caso de que usted está utilizando PrimeFaces 4+ y que te gustaría explícitamente el uso de Apache Commons FileUpload en lugar de JSF 2.2 /Servlet 3.0 nativo de carga de archivos, entonces usted necesita junto a las mencionadas bibliotecas y filtro también el siguiente contexto param en web.xml:

    <context-param>
        <param-name>primefaces.UPLOADER</param-name>
        <param-value>commons</param-value><!-- Allowed values: auto, native and commons. -->
    </context-param>

    Solución de problemas

    En caso de que aún así no funciona, he aquí otra de las posibles causas ajenas a la PrimeFaces de configuración:

    1. Sólo si estás usando el PrimeFaces cargar el archivo de filtro: Hay otra Filter en su webapp que se ejecuta antes de la PrimeFaces cargar el archivo de filtro y ya ha consumido el cuerpo de solicitud (por ejemplo, llamar a getParameter(), getParameterMap(), getReader(), etcétera. Un cuerpo de solicitud puede ser analizada sólo una vez. Cuando se llama a uno de estos métodos antes de cargar el archivo con el filtro de su trabajo, luego cargar el archivo de filtro se consigue un vacío del cuerpo de solicitud.

      Para solucionar este problema, sería necesario poner el <filter-mapping> de la carga de archivo de filtro antes de el otro filtro en web.xml. Si la solicitud no es un multipart/form-data solicitud, a continuación, cargar el archivo de filtro continuará como si nada hubiera pasado. Si usted usa los filtros que se automágicamente añadido debido a que el uso de anotaciones (por ejemplo, PrettyFaces), es posible que deba agregar explícita pedidos a través de web.xml. Ver Cómo definir servlet filtro de orden de ejecución mediante anotaciones en GUERRA

    2. Sólo si estás usando el PrimeFaces cargar el archivo de filtro: Hay otra Filter en su webapp que se ejecuta antes de la PrimeFaces cargar el archivo de filtro y ha realizado una RequestDispatcher#forward() llamada. Generalmente, reescritura de URL de filtros tales como PrettyFaces hacer esto. Esto desencadena la FORWARD despachador de la policía, pero los filtros de escucha por defecto en REQUEST despachador sólo.

      Para solucionar este problema, sería necesario poner el PrimeFaces cargar el archivo de filtro antes de el reenvío de filtro, o volver a configurar el PrimeFaces cargar el archivo de filtro para escuchar en FORWARD despachador demasiado:

      <filter-mapping>
          <filter-name>primeFacesFileUploadFilter</filter-name>
          <servlet-name>facesServlet</servlet-name>
          <dispatcher>REQUEST</dispatcher>
          <dispatcher>FORWARD</dispatcher>
      </filter-mapping>
    3. Hay un anidada <h:form>. Esto es ilegal en el HTML y el comportamiento del navegador no está especificado. Más que a menudo, el navegador no envía los datos esperados en enviar. Asegúrese de que usted no está de anidación <h:form>. Esto es completamente independientemente de la forma de la enctype. Simplemente no se anidan las formas en absoluto.

    Si sigues teniendo problemas, bueno, depurar el tráfico HTTP. Abra el navegador web del desarrollador del conjunto de herramientas (presione F12 en Chrome/Firebug23+/IE9+) y compruebe la Red/la Red de sección. Si el HTTP parte se ve bien, entonces depurar el código JSF. Poner un punto de interrupción en FileUploadRenderer#decode() y avanzar desde allí.


    Guardar los archivos subidos

    Después de que finalmente tengo que trabajar, la siguiente pregunta debe ser, probablemente, como «¿Cómo y dónde debo guardar el archivo subido?». Bien, continúa aquí: Cómo guardar los archivos subidos en JSF.

    • Otra causa podría ser que usted no se ha registrado la PrimeFaces subir filtro en web.xml como por la PrimeFaces los Usuarios de la Guía. ¿La has leído, de todos modos? Que, sin embargo, no explican por qué mode="simple" que funciona para usted.
    • Sí que he leído y me he registrado en el filtro, pero me di cuenta de que me da un error al iniciar el servidor «GRAVES: WebModule[/EventsCalendary]PWC1270: Excepción de partida filtro de PrimeFaces FileUpload Filtro» me siento tan tonto por no darse cuenta antes. Algunos consejos sobre como solucionar este error?
    • Tal vez el filtro de asignación es incorrecta. Tiene que ser asignada en el <servlet-name> de la FacesServlet como has definida en web.xml. De la cesación de pagos por parte de la mayoría de los IDEs/generadores código para Faces Servlet, pero puede ser tan buena facesServlet o algo que es más que confirmar las convenciones de nomenclatura.
    • No importa resuelto por la adición de commons-fileupload a la ruta de clases y commons-io, hay un lugar donde dice que estas bibliotecas son necesarios? De todos modos, todo parece estar funcionando bien ahora, se llama el método, como se suponía, gracias.
    • Esto se contradice con su declaración de que funciona con mode="simple".
    • Pero era de trabajo, el método estaba siendo llamado, no sé si el archivo estaba siendo cargado, pero el método era, al menos, que se llama.
    • Está bien, pero no me sorprendería si el archivo está vacío. He al menos actualizada la respuesta.
    • Hola @BalusC he probado muchos ejemplos de fileupload pero todos fallaron. La única cosa es que no sé por dónde agregar el XML bits (filtros y asignaciones) en el web.xml. Me refiero a que en virtud de la cual la sección? porque cada vez que inserte el XML bits, el proyecto está marcado en rojo en netbeans. Cualquier sugerencia no?
    • La respuesta debe ser actualizado para las personas que están usando PF 4+, Servlet 3.0+, JSF 2.2+. Ok, no necesitamos usar Apache Commons Carga de Archivos, pero cuando se utiliza Bastante Caras como Filter la p:fileUpload no funciona fuera de la caja con Tomcat 7. Una referencia a esta respuesta debe añadirse: stackoverflow.com/questions/8047173/…
    • Hola @BalusC, por desgracia, ninguna de las configuraciones que se trabaja en JBoss 6.4.0.GA cuando se instala JSF 2.2 como un módulo. He probado con filtro.. sin filtro.. todavía no funciona.
    • publicar los resultados de la solución de problemas, como se sugiere en «Si usted todavía está teniendo problemas».
    • en realidad funcionó….. si puedo especificar explicidly filtro y commons subirlo funciona, pero deja de funcionar en TomEE…
    • Así que todo salió a la situación que me hormigas de la misma config en TomEE y JBoss.. forum.primefaces.org/viewtopic.php?f=3&t=43798
    • Para mí, FileUploadRenderer#decode() fue el rescate de inmediato, debido al tipo de contenido en la org.apache.myfaces.webapp.el filtro.MultipartRequestWrapper regresar WWW_FORM_URLENCODED_TYPE que es «application/x-www-form-urlencoded» – no empiece con «multipart/». Añadir manualmente las Primefaces filtro antes de que otros filtros no funcionan. He quitado la org.apache.myfaces.webapp.el filtro.ExtensionsFilter de la web.xml y, a continuación, PrimeFaces <p:fileUpload> trabajó. Me voy a quitar totalmente Tomahawk desde mi aplicación, ya que no se actualiza y sus características están disponibles en otros lugares.
    • En caso de no ajax file upload mode=»simple», es que hay una solución para utilizar la actualización?
    • Yo tenía el mismo problema – excepto que yo estaba trabajando con Primeface 6.1 y Webshpere COMO 8.5.5 que no es compatible con JSF 2.2. El cambio que hice fueron similares a las indicadas para la versión 5.x.
    • Yo podría subir archivos cuando mi aplicación se ejecuta en Payara 4.xxx. Puedo migrar mi aplicación para Payara 5.183, pero incluso con los no-ajax modo simple, el UploadedFile objeto siempre es null, el archivo nunca se carga, alguna idea?
    • Tenga cuidado, Primefaces 5.3 no se puede comprobar las Versiones posteriores de JSF 2.2. Así, en JSF 2.3 la carga del interruptor de modo a commons si no se declara. Gracias por la punta con el punto de interrupción.

  2. 30

    Está utilizando prettyfaces demasiado? A continuación, establezca despachador para ADELANTE:

    <filter-mapping>
       <filter-name>PrimeFaces FileUpload Filter</filter-name>
       <servlet-name>Faces Servlet</servlet-name>
       <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    • Esto es todavía un problema cuando se utiliza con OCP a escribir. Te debo una cerveza 🙂
  3. 6

    Un punto que me di cuenta con Primefaces 3.4 y Netbeans 7.2:

    Quitar el Netbeans auto-rellenar los parámetros para la función handleFileUpload es decir, (evento) de lo contrario evento podría ser null.

    <h:form>
        <p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload(event)}"
            mode="advanced" 
            update="messages"
            sizeLimit="100000" 
            allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>
    
        <p:growl id="messages" showDetail="true"/>
    </h:form>
  4. 0

    Tuve el mismo problema con primefaces 5.3 y me fui a través de todos los puntos descritos por BalusC con ningún resultado. He seguido su consejo de depuración FileUploadRenderer#decode() y he descubierto que mi web.xml fue unproperly conjunto

    <context-param>
      <param-name>primefaces.UPLOADER</param-name>
      <param-value>auto|native|commons</param-value>
    </context-param>

    El param-value debe ser 1 de estos 3 valores, pero no todos ellos!! Todo el context-param sección puede ser eliminado y el valor predeterminado será auto

  5. 0

    bean.xhtml

        <h:form enctype="multipart/form-data">    
    <p:outputLabel value="Choose your file" for="submissionFile" />
                    <p:fileUpload id="submissionFile"
                        value="#{bean.file}"
                        fileUploadListener="#{bean.uploadFile}" mode="advanced"
                        auto="true" dragDropSupport="false" update="messages"
                        sizeLimit="100000" fileLimit="1" allowTypes="/(\.|\/)(pdf)$/" />
    
    </h:form>

    Bean.java

    @ManagedBean

    @ViewScoped
    clase pública de Presentación de implements Serializable {

    private UploadedFile file;
    
    //Gets
    //Sets
    
    public void uploadFasta(FileUploadEvent event) throws FileNotFoundException, IOException, InterruptedException {
    
        String content = IOUtils.toString(event.getFile().getInputstream(), "UTF-8");
    
        String filePath = PATH + "resources/submissions/" + nameOfMyFile + ".pdf";
    
        MyFileWriter.writeFile(filePath, content);
    
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
                event.getFile().getFileName() + " is uploaded.", null);
        FacesContext.getCurrentInstance().addMessage(null, message);
    
    }

    }

    web.xml

        <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    • Puede usted explicar por qué esto es una respuesta? Es sólo el código, no explicación o lo que sea
    • «#{bean.uploadFile}» vs «#{bean.uploadFasta}» , quitar la actualización=»mensajes» y (sólo) que trabaja para mí !
  6. 0

    Ninguna de las sugerencias fueron útiles para mí. Así que tuve que depurar primefaces y encontró la razón de que el problema era:

    java.lang.IllegalStateException: No multipart config for servlet fileUpload

    Luego he añadido la sección en mi faces servlet en el web.xml. Por lo que se ha solucionado el problema:

    <servlet>
        <servlet-name>main</servlet-name>
    
            <servlet-class>org.apache.myfaces.webapp.MyFacesServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
            <multipart-config>
                <location>/tmp</location>
                <max-file-size>20848820</max-file-size>
                <max-request-size>418018841</max-request-size>
                <file-size-threshold>1048576</file-size-threshold>
            </multipart-config>
        </servlet>
  7. 0

    Tuve el mismo problema, debido al hecho de que yo tenía toda la configuración que se describe en este post, pero en mi caso fue porque había dos jquery importaciones (uno de ellos fue primefaces de la consulta) que los conflictos causados por la subida de archivos.

    Ver Primefaces conflicto Jquery

    • No has cogido un error específico en el desarrollo del navegador de la consola, entonces?
    • esto es lo que la consola mostró: Uncaught TypeError: Object [object object] no tiene ningún método ‘fileupload’
  8. 0

    Para las personas que utilizan Tomee o Tomcat y no pueden conseguir trabajo, intente crear context.xml en META-INF y agregar allowCasualMultipartParsing=»true»

    <?xml version="1.0" encoding="UTF-8"?>
    <Context allowCasualMultipartParsing="true">
      <!-- empty or not depending your project -->
    </Context>
    • Este es un trabajo en torno a una incorrecta configuración de filtro/orden.
    • Hola @BalusC, nos puede dar más explicación? Hay una manera mejor de este trabajo alrededor?
    • Ver mi respuesta en esta pregunta.
  9. 0

    Con JBoss 7.2(Resaca) y PrimeFaces 6.0 org.primefaces.webapp.el filtro.FileUploadFilter debe ser eliminado de web.xml y el contexto param cargador de archivos se debe establecer a los nativos:

    <context-param>
        <param-name>primefaces.UPLOADER</param-name>
        <param-value>native</param-value>
    </context-param>
    • Debe? Usted obtener errores específicos si no?
    • Sí, mi FileUploadEvent no invoca, sin que esto cambia.
    • Que no es explícita de error, que es comportamiento inesperado

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea