Hoje vamos analisar o componente de upload de arquivos do Primefaces. O HTML oferece a tag de entrada de arquivo para selecionar o arquivo, mas precisamos de muito mais para fazer o upload de um arquivo para o servidor. O Primefaces removeu esse fardo ao fornecer um componente de FileUpload pronto para uso que ajuda a criar uma IU bonita com suporte backend para fazer upload de arquivos para o servidor.
Primefaces FileUpload
Vamos analisar os recursos do componente de upload de arquivos do Primefaces que você pode usar em sua aplicação. Este tutorial pressupõe que você tenha conhecimento básico do Primefaces, caso contrário, consulte o Exemplo do Primefaces.
Informações básicas sobre o 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 do 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. |
Exemplo de Upload de Arquivo PrimeFaces
Para utilizar o FileUpload, você precisa fornecer o mecanismo FileUpload adicionando o parâmetro de implantação web primefaces.UPLOADER que pode ter os seguintes valores: web.xml
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>auto|native|commons</param-value>
</context-param>
- auto: Este é o modo padrão e o PrimeFaces tenta detectar o melhor método verificando o ambiente de tempo de execução, se o tempo de execução do JSF for pelo menos 2.2, o uploader nativo é selecionado, caso contrário, será utilizado o commons.
- nativo: O modo nativo usa a API Part do servlet 3.x para fazer upload dos arquivos e se o tempo de execução do JSF for inferior a 2.2, uma exceção será lançada.
- commons: Esta opção escolhe o Commons FileUpload, e requer a seguinte configuração do filtro em seu descritor de implantação.
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>
Observe que o servlet-name deve corresponder ao nome configurado do servlet JSF, que é Faces Servlet neste caso. Alternativamente, você pode fazer uma configuração com base no padrão de URL também.
Upload de Arquivo Simples do PrimeFaces
O modo de upload de arquivo simples funciona em navegadores mais antigos, com uma entrada de arquivo cujo valor deve ser uma instância UploadedFile. Os uploads Ajax não são suportados no upload simples. Veja abaixo esses arquivos necessários para fazer um exemplo de upload de arquivo simples. 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>
Como resumo:
- O motor FileUpload do Primefaces usado é auto.
- O atributo value do componente fileUpload está associado à instância UploadedFile.
- O uso do fileUpload requer incluir o componente fileUpload dentro de um formulário, seu enctype é multipart/form-data.
- A ação fictícia fornecida é usada para imprimir o nome e o tamanho do arquivo enviado.
Onde, o resultado da demonstração será: O botão de entrada simples foi renderizado no seu navegador.
E uma vez que você clicou na Ação Simulada uma método de ação simulada é executado e as informações do arquivo enviado são impressas no seu console como abaixo.
Upload de Arquivo Avançado do Primefaces
O componente FileUpload fornece uma visualização simples e uma visualização avançada. Escolher a visualização avançada torna o único caminho disponível para acessar arquivos enviados através do FileUploadListener. O ouvinte será processado assim que o arquivo for enviado e um FileUploadEvent for passado como parâmetro para o ouvinte. Veja abaixo os arquivos necessários que ajudam você a usar o modo avançado. 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){
// Obter arquivo enviado do FileUploadEvent
this.file = e.getFile();
// Imprimir as informações do arquivo
System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
}
}
Em resumo:
- Nem o web.xml nem o pom.xml foram mencionados, porque não foram alterados.
- O atributo de valor do componente FileUpload está associado à instância UploadedFile, pois o componente também é ouvido pelo FileUploadListener.
- O FileUploadListener recebe um FileUploadEvent como parâmetro.
- Depois de clicar na ação Upload, o FileUploadListener será executado e um FileUploadEvent será criado e passado.
Onde, o resultado da demonstração será uma nova visualização do componente de upload com dois botões adicionais; um para fazer upload e o último para cancelar.
É importante notar os seguintes pontos como resultado da execução:
- O arquivo carregado é passado dentro do FileUploadEvent e pode ser acessado invocando e.getFile() contra o objeto de evento que retorna uma instância UploadedFile.
- O processo de upload será cancelado completamente se você clicou em Cancelar em vez de Upload. Cancelar o upload impedirá que o ouvinte seja invocado.
Uploads de Múltiplos Arquivos Primefaces
Enviar vários arquivos usando o componente FileUpload é aplicável para que vários arquivos possam ser selecionados no diálogo do navegador. Uploads múltiplos não são suportados em navegadores antigos. Defina o atributo múltiplo como verdadeiro para permitir seleções múltiplas de arquivos, no entanto, seleções múltiplas de arquivos não significam que todos os arquivos serão enviados para o servidor em uma única solicitação. No entanto, eles serão enviados um por um. Veja abaixo a mudança necessária que torna as seleções múltiplas aplicáveis. 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){
// Obtenha o arquivo enviado do FileUploadEvent
this.file = e.getFile();
// Imprima as informações do arquivo
System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
}
}
Onde, o resultado da execução do aplicativo parece abaixo:
É importante notar os seguintes pontos da demonstração:
- Cancelar o envio usando o botão Cancelar deve nos levar a cancelar o processo de envio de todos os arquivos.
- Clicar no ícone X ao lado de cada arquivo que será enviado fará com que apenas o arquivo correspondente seja cancelado.
- Assim que você clicar em Ação de Envio, o ouvinte será invocado pelo número de arquivos que forem carregados.
Primefaces Auto File Upload
O comportamento padrão requer que os usuários acionem o processo de upload. Você pode alterar isso definindo auto como true. Os uploads automáticos são acionados assim que os arquivos são selecionados na caixa de diálogo. Veja abaixo a alteração necessária que torna o upload automático aplicável. 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>
Onde o resultado da execução da aplicação parece com o seguinte:
Depois de clicar em Abrir na sua janela do navegador, o processo de upload é iniciado instantaneamente.
Primefaces File Upload Atualização Parcial da Página
Depois de concluído o processo de envio de arquivos, você pode usar o Primefaces PPR (Renderização Parcial de Página) para atualizar qualquer componente na página. O componente FileUpload está equipado com o atributo update para esse fim. O exemplo a seguir exibe uma mensagem “Arquivo enviado com sucesso” usando o componente growl após o envio do arquivo. O componente Growl será discutido posteriormente ao abordarmos as mensagens. O trecho de código a seguir ajuda a exibir uma mensagem assim que o arquivo é enviado. 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){
// Obtenha o arquivo enviado do FileUploadEvent
this.file = e.getFile();
// Imprima as informações do arquivo
System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
// Adicione a mensagem
FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("File Uploaded Successfully"));
}
}
O resultado da execução será semelhante ao seguinte: Uma mensagem foi adicionada ao FacesContext e o componente FileUpload define o atributo update, o que fará com que a mensagem seja renderizada por meio do mecanismo Ajax. O comportamento Ajax será discutido posteriormente em um tutorial separado.
Filtros de Upload de Arquivos
Os usuários podem ser restritos a selecionar apenas os tipos de arquivo que você configurou, o exemplo abaixo demonstra como aceitar apenas imagens. 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>
E o resultado da execução parece abaixo
Limite de Tamanho e Limite de Arquivo de Upload de Arquivo Primefaces
Às vezes, você precisa restringir o tamanho do arquivo enviado ou o número de arquivos a serem enviados. Fazer essas restrições não é um grande problema com o componente Primefaces FileUpload. Você pode alcançar essas restrições fornecendo os atributos sizeLimit & fileLimit respectivamente contra o próprio FileUpload. Seguem os fragmentos de código que mantêm seus usuários restritos: 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>
Quando você tenta carregar mais de três arquivos ou quando o tamanho do arquivo excede o limite, mensagens de erro serão exibidas como abaixo:
Mensagem de Validação de Upload de Arquivo do Primefaces
Mensagem de Arquivo Inválido, Mensagem de Tamanho Inválido e Mensagem de Limite de Arquivo opções são fornecidas para exibir mensagens de validação aos usuários. Você pode fornecer qualquer mensagem que desejar para essas validações. Veja abaixo o exemplo fornecido. 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>
Se você notou que as mensagens foram alteradas e forneceram valores de texto diferentes. Se você notar o código do bean gerenciado, não estamos fazendo nada com o arquivo. No entanto, em situações da vida real, podemos usar o método
getInputstream()
do UploadedFile
para obter os dados do arquivo e salvá-lo como arquivo no servidor ou no banco de dados.
Resumo do FileUpload do Primefaces
Este tutorial destina-se a fornecer-lhe uma explicação detalhada completa sobre o uso do componente FileUpload do Primefaces. O componente FileUpload está equipado com muitos recursos que mantêm o seu foco no negócio, em vez de tentar implementar algo semelhante. Você pode baixar o projeto de exemplo a partir do link abaixo e usar outros atributos de fileUpload para aprender mais.
Source:
https://www.digitalocean.com/community/tutorials/primefaces-fileupload-component-example-tutorial