Ejemplo de Tutorial del Componente FileUpload de Primefaces

Hoy vamos a analizar el componente Primefaces FileUpload. HTML te proporciona la etiqueta de entrada de archivo para seleccionar el archivo, pero necesitamos mucho más para subir un archivo al servidor. Primefaces ha eliminado esa carga al proporcionarte un componente FileUpload listo para usar que te ayuda a crear una interfaz de usuario hermosa con soporte backend para subir archivos al servidor.

Carga de archivos Primefaces

Vamos a analizar las características del componente Primefaces FileUpload que puedes utilizar en tu aplicación. Este tutorial asume que tienes conocimientos básicos de Primeface, si no es así, por favor revisa Ejemplo de Primefaces.

Información básica sobre Primefaces FileUpload

Tag fileUpload
Component Class org.primefaces.component.fileupload.FileUpload
Component Type org.primefaces.component.FileUpload
Component Family org.primefaces.component
Renderer Type org.primefaces.component.FileUploadRenderer
Renderer Class org.primefaces.component.fileupload.FileUploadRenderer

Atributos de Primefaces FileUpload

Name Default Type Description
id null String Unique identifier of the component.
rendered true boolean Boolean value to specify the rendering of the component, when set to false component will not be rendered
binding null Object An el expression that maps to a server side UIComponent instance in a backing bean
value null Object Value of the component than can be either an EL expression of a literal text
converter null Converter/String An el expression or a literal text that defines a converter for the component. When it’s an EL expression, it’s resolved to a converter instance. In case it’s a static text, it must refer to a converter id.
immediate false Boolean When set true, process validations logic is executed at apply request values phase for this component
required false Boolean Marks component as required.
validator null MethodExpr A method expression that refers to a method validating the input
valueChangeListener null MethodExpr A method expression that refers to a method for handling a valueChangeEvent
requiredMessage null String Message to be displayed when required field validation fails
converterMessage null String Message to be displayed when conversion fails.
validatorMessage null String Message to be displayed when validation fails.
widgetVar null String Name of the client side widget.
update null String Component(s) to update after fileupload completes.
process null String Component(s) to process in fileupload request.
fileUploadListener null MethodExpr Method to invoke when a file is uploaded.
multiple false Boolean Allows choosing of multi file uploads from native
auto false Boolean When set to true, selecting a file starts the upload process implicitly
label Choose String Label of the browse button.
allowTypes null String Regular expression for accepted file types,
sizeLimit null Integer Individual file size limit in bytes.
fileLimit null Integer Maximum number of files allowed to upload.
style null String Inline style of the component.
styleClass null String Style class of the component.
mode advanced String Mode of the fileupload, can be simple or advanced.
uploadLabel Upload String Label of the upload button.
cancelLabel Cancel String Label of the cancel button.
invalidSizeMessage null String Message to display when size limit exceeds.
invalidFileMessage null String Message to display when file is not accepted.
fileLimitMessage null String Message to display when file limit exceeds.
dragDropSupport true Boolean Specifies dragdrop based file selection from filesystem, default is true and works only on supported browsers
onstart null String Client side callback to execute when upload begins.
onerror null String Callback to execute if fileupload request fails.
oncomplete null String Client side callback to execute when upload ends.
disabled false Boolean Disables component when set true.
messageTemplate {name} {size} String Message template to use when displaying file validation errors
previewWidth 80 Integer Width for image previews in pixels.

Ejemplo de carga de archivos con Primefaces

Para utilizar FileUpload, debes proporcionar el motor FileUpload agregando el parámetro de implementación web primefaces.UPLOADER, que puede tomar los siguientes valores: web.xml

<context-param>
  <param-name>primefaces.UPLOADER</param-name>
  <param-value>auto|native|commons</param-value>
</context-param>
  1. auto: Este es el modo predeterminado y Primefaces intenta detectar el mejor método verificando el entorno en tiempo de ejecución; si el tiempo de ejecución de JSF es al menos 2.2, se selecciona el cargador nativo; de lo contrario, se utiliza commons.
  2. native: El modo nativo utiliza la API Part de servlet 3.x para cargar los archivos y, si el tiempo de ejecución de JSF es menor a 2.2, se genera una excepción.
  3. commons: Esta opción elige commons fileUpload, y requiere la siguiente configuración del filtro en tu descriptor de implementación.

web.xml

<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>

Observa que el nombre del servlet debe coincidir con el nombre configurado del servlet JSF, que en este caso es Faces Servlet. Alternativamente, también puedes realizar una configuración basada en el patrón de URL.

Primefaces Simple File Upload

El modo de carga de archivo simple funciona en navegadores antiguos, con una entrada de archivo cuyo valor debe ser una instancia de UploadedFile. Las cargas Ajax no son compatibles en la carga simple. Mira abajo para ver los archivos necesarios para hacer una muestra de carga de archivo simple. index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data">
				<p:fileUpload value="#{fileUploadManagedBean.file}"  mode="simple"></p:fileUpload>
				<p:separator/>
				<h:commandButton value="Dummy Action" action="#{fileUploadManagedBean.dummyAction}"></h:commandButton>
		</h:form>
	</h:body>
</html>
package com.journaldev.prime.faces.beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.primefaces.model.UploadedFile;

@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
	UploadedFile file;

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	public String dummyAction(){
		System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
		return "";
	}
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns="https://java.sun.com/xml/ns/javaee" xmlns:web="https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="https://java.sun.com/xml/ns/javaee
	https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5" metadata-complete="true">
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>/faces/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.xhtml</url-pattern>
	</servlet-mapping>
	<context-param>
		<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
		<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
		<param-value>client</param-value>
	</context-param>
	<context-param>
		<param-name>primefaces.UPLOADER</param-name>
		<param-value>auto</param-value>
	</context-param>
	<listener>
		<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
	</listener>
</web-app>

pom.xml

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.journaldev</groupId>
  <artifactId>Primefaces-FileUpload-Sample</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Primefaces-FileUpload-Sample Maven Webapp</name>
   <url>https://maven.apache.org</url>
	<repositories>
		<repository>
			<id>prime-repo</id>
			<name>PrimeFaces Maven Repository</name>
			<url>https://repository.primefaces.org</url>
			<layout>default</layout>
		</repository>
	</repositories>
	<dependencies>
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<!-- Faces Implementation -->
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-impl</artifactId>
			<version>2.2.4</version>
		</dependency>
		<!-- Faces Library -->
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-api</artifactId>
			<version>2.2.4</version>
		</dependency>
		<!-- Primefaces Version 5 -->
		<dependency>
			<groupId>org.primefaces</groupId>
			<artifactId>primefaces</artifactId>
			<version>5.0</version>
		</dependency>
		<!-- JSP Library -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.1</version>
		</dependency>
		<!-- JSTL Library -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.1.2</version>
		</dependency>
	</dependencies>
</project>

En resumen:

  1. El motor de FileUpload de Primefaces que se utiliza es auto.
  2. El atributo value del componente fileUpload está asociado con la instancia UploadedFile.
  3. El uso de fileUpload requiere incluir el componente fileUpload dentro de un formulario, su enctype es multipart/form-data.
  4. Se proporciona una acción ficticia para imprimir el nombre y el tamaño del archivo cargado.

Donde, el resultado de la demo será: El botón de entrada simple se ha renderizado en su navegador. Y una vez que haya hecho clic en la Acción Ficticia, se ejecuta un método de acción ficticia y la información del archivo cargado se imprime en su consola como se muestra a continuación.

Carga de Archivos Avanzada de Primefaces

El componente FileUpload te proporciona una vista simple y una vista avanzada. La elección de la vista avanzada hace que la única forma disponible de acceder a los archivos cargados sea a través del FileUploadListener. El listener se procesará tan pronto como se cargue el archivo y se haya pasado un FileUploadEvent como parámetro al listener. Observa a continuación los archivos necesarios que te ayudarán a usar el modo avanzado. index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced"
								fileUploadListener="#{fileUploadManagedBean.fileUploadListener}"></p:fileUpload>
		</h:form>
	</h:body>
</html>
package com.journaldev.prime.faces.beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
	UploadedFile file;

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	public void fileUploadListener(FileUploadEvent e){
		// Obtener archivo cargado del FileUploadEvent
		this.file = e.getFile();
		// Imprimir la información del archivo
		System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
	}
}

Como resumen:

  1. Ni el web.xml ni el pom.xml se han mencionado, porque no han cambiado.
  2. El atributo valor del componente FileUpload está asociado con la instancia UploadedFile, ya que el componente también es escuchado por el FileUploadListener.
  3. FileUploadListener recibe un FileUploadEvent como parámetro.
  4. Una vez que hayas hecho clic en la acción Cargar, se ejecutará el FileUploadListener y se creará y pasará un FileUploadEvent.

Donde, el resultado de la demo será una nueva vista del componente de carga con dos botones adicionales; uno para cargar y el otro para cancelar. Es importante notar los siguientes puntos como resultado de la ejecución:

  1. El archivo cargado se pasa dentro del FileUploadEvent y se puede acceder invocando e.getFile() contra el objeto de evento que devuelve una instancia de UploadedFile.
  2. El proceso de carga se cancelaría por completo si has hecho clic en Cancelar en lugar de Subir. Cancelar la carga evitará que se invoque al oyente.

Cargas múltiples de archivos Primefaces

La carga de varios archivos mediante el componente FileUpload es aplicable para que se puedan seleccionar varios archivos desde el cuadro de diálogo del navegador. Las cargas múltiples no son compatibles con los navegadores antiguos. Establece el atributo multiple en true para habilitar la selección de varios archivos, sin embargo, la selección múltiple de archivos no significa que todos los archivos se enviarán al servidor en una sola solicitud. Sin embargo, se enviarán uno por uno. Observa el cambio necesario que hace posible la selección múltiple a continuación. index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced" multiple="true"
								fileUploadListener="#{fileUploadManagedBean.fileUploadListener}"></p:fileUpload>
		</h:form>
	</h:body>
</html>
package com.journaldev.prime.faces.beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
	UploadedFile file;

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	public void fileUploadListener(FileUploadEvent e){
		// Obtener archivo cargado desde FileUploadEvent
		this.file = e.getFile();
		// Imprimir la información del archivo
		System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
	}
}

Donde, el resultado de ejecutar la aplicación se ve así: Es importante notar los siguientes puntos de la demo:

  1. Cancelar la carga usando el botón Cancelar debería llevarnos a cancelar el proceso de carga de todos los archivos.
  2. Hacer clic en el icono X que está al lado de cada archivo que se vaya a cargar, hará que se cancele únicamente la carga del archivo correspondiente.
  3. Una vez que hayas hecho clic en la acción de Subir, el escuchador será invocado por la cantidad de archivos que se carguen.

Subida Automática de Archivos Primefaces

El comportamiento predeterminado requiere que los usuarios activen el proceso de carga, puedes cambiar esta opción estableciendo auto en verdadero. Las cargas automáticas se activan tan pronto como se seleccionan los archivos del diálogo. Mira a continuación el cambio necesario para que la carga automática sea aplicable. index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced" multiple="true" auto="true"
								fileUploadListener="#{fileUploadManagedBean.fileUploadListener}"></p:fileUpload>
		</h:form>
	</h:body>
</html>

Donde, el resultado de ejecutar la aplicación se ve así: Una vez que hayas hecho clic en Abrir en la ventana de tu navegador, el proceso de carga se iniciará instantáneamente.

Carga parcial de página de carga de archivos Primefaces

Una vez que se completa el proceso de carga de archivos, puede utilizar el PPR (Representación Parcial de Página) de Primefaces para actualizar cualquier componente en la página. El componente FileUpload está equipado con el atributo de actualización con este propósito. El siguiente ejemplo muestra un mensaje “Archivo cargado exitosamente” utilizando el componente growl después de cargar el archivo. El componente Growl se discutirá más adelante al tratar mensajes. El siguiente fragmento de código le ayuda a mostrar un mensaje una vez que se ha cargado el archivo. index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:growl id="msg"></p:growl>
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced"
								fileUploadListener="#{fileUploadManagedBean.fileUploadListener}" update="msg"></p:fileUpload>
		</h:form>
	</h:body>
</html>
package com.journaldev.prime.faces.beans;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
	UploadedFile file;

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	public void fileUploadListener(FileUploadEvent e){
		// Obtener archivo cargado del FileUploadEvent
		this.file = e.getFile();
		// Imprimir la información del archivo
		System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
		// Agregar mensaje
		FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("File Uploaded Successfully"));
	}
}

Donde el resultado de la ejecución se ve así: Se ha añadido un mensaje al FacesContext y el componente FileUpload define el atributo update que hará que el mensaje se renderice mediante el mecanismo Ajax. El comportamiento Ajax se discutirá más adelante en un tutorial separado.

Filtros de carga de archivos

Los usuarios pueden estar restringidos a seleccionar solo los tipos de archivo que hayas configurado, el ejemplo a continuación muestra cómo aceptar solo imágenes. index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:growl id="msg"></p:growl>
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced" allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
								fileUploadListener="#{fileUploadManagedBean.fileUploadListener}" update="msg"></p:fileUpload>
		</h:form>
	</h:body>
</html>

Y el resultado de la ejecución se ve así

Límite de tamaño de carga de archivos y límite de archivos de carga de Primefaces

A veces, necesitas restringir el tamaño del archivo cargado o el número de archivos que se van a cargar. Hacer tales restricciones no es un gran problema con el componente FileUpload de Primefaces. Puedes lograr estas restricciones proporcionando los atributos sizeLimit y fileLimit respectivamente contra el propio FileUpload. A continuación, se muestran los fragmentos de código que mantienen restringidos a tus usuarios: index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:growl id="msg"></p:growl>
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced" multiple="true" fileLimit="3" sizeLimit="2048"
								fileUploadListener="#{fileUploadManagedBean.fileUploadListener}" update="msg"></p:fileUpload>
		</h:form>
	</h:body>
</html>

Cuando intentas subir más de tres archivos o el tamaño de un archivo supera el límite, se mostrarán mensajes de error como los siguientes:

Mensaje de Validación de Carga de Archivos de Primefaces

invalidFileMessage, invalidSizeMessage y fileLimitMessage. Se proporcionan opciones para mostrar mensajes de validación a los usuarios. Puedes personalizar los mensajes según tus necesidades. Observa el ejemplo proporcionado en index.xhtml.

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:growl id="msg"></p:growl>
				<p:fileUpload value="#{fileUploadManagedBean.file}"
								invalidSizeMessage="JournalDev: Invalid Size"
								invalidFileMessage="JournalDev: Invalid File Type"
								fileLimitMessage="JournalDev: Invalid File Limit"
								mode="advanced" multiple="true" fileLimit="3" sizeLimit="2048"
								allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
								fileUploadListener="#{fileUploadManagedBean.fileUploadListener}"
								update="msg"></p:fileUpload>
		</h:form>
	</h:body>
</html>

Si has notado que los mensajes han cambiado y se han proporcionado diferentes valores de texto. Si notas el código del bean gestionado, no estamos haciendo nada con el archivo. Sin embargo, en situaciones de la vida real, podemos usar el método getInputstream() de UploadedFile para obtener los datos del archivo y guardarlo como archivo en el servidor o en la base de datos.

Resumen de Primefaces FileUpload

Este tutorial tiene la intención de proporcionarte una explicación detallada sobre cómo usar el componente FileUpload de PrimeFaces. El componente FileUpload está equipado con muchas características que te permiten concentrarte en el negocio en lugar de intentar implementar algo similar. Puedes descargar el proyecto de muestra desde el siguiente enlace y utilizar otros atributos de fileUpload para aprender más.

Descargar Proyecto PrimeFaces FileUpload

Source:
https://www.digitalocean.com/community/tutorials/primefaces-fileupload-component-example-tutorial