Archive for agosto, 2010

Utilizando o componente <t:inputFileUpload>

<t:inputFileUpload> é um componente da biblioteca Tomahawk (grupo Apache), responsável por fazer upload de um arquivo em sua página JSF. Ele é idêntico ao componente HTML <input type=”file”>, porém internamente é totalmente compátivel com o Java Server Faces, suprindo a ausência de um componente deste tipo na implementação padrão do JSF.
Em comparação ao componente <rich:fileUpload> da biblioteca RichFaces ele possui poucas funcionalidades, mas dependendo da sua necessidade ele pode servir perfeitamente.

Componente inputFileUpload

Principais Funcionalidades

  • Restringe tamanho de arquivo
  • Define o tipo de armazenamento (pasta temporária ou memória)

Configuração

Antes de usar o componente é necessário a configuração do ExtensionFilter em seu web.xml.
O ExtensionFilter é um filtro do MyFaces que fornece suporte a componentes do Tomahawk e será extremamente necessário para nosso componente de upload.
Uma observação importante é que este filtro deve ser mapeado junto com o Faces Servlet. Por exemplo,  se sua aplicação JSF está sendo mapeada para *.jsf, todas as requisições que passarem por essa extensão devem passar pelo ExtensionFilter também.

web.xml   
<!-- Extensions Filter -->
<filter>
	<filter-name>extensionsFilter</filter-name>
        <filter-class>org.apache.myfaces.component.html.util.ExtensionsFilter</filter-class>
        <init-param>
            <param-name>uploadMaxFileSize</param-name>
            <param-value>100m</param-value>
            <description>
               Define o tamanho máximo que o arquivo pode ter.
               Formato: 10 - 10 bytes
                        10k - 10 KB
                        10m - 10 MB
                        1g - 1 GB
            </description>
        </init-param>
        <init-param>
            <param-name>uploadThresholdSize</param-name>
            <param-value>100k</param-value>
            <description>
               Define o tipo de armazenamento baseado no tamanho.
               Se o arquivo estiver abaixo deste tamanho ele será armazenado na memória
               Se o arquivo estiver acima será armazenado no disco (pasta temporária)
               Formato: 10 - 10 bytes
                        10k - 10 KB
                        10m - 10 MB
                        1g - 1 GB
            </description>
        </init-param>
        <!--
        <init-param>
            <param-name>uploadRepositoryPath</param-name>
            <param-value>/temp</param-value>
            <description>
               Define o caminho onde os arquivos serão armazenados.
               Este parâmetro está comentado pois não é muito útil,
               Sem este parâmetro, os arquivos já serão armazenados por padrão na pasta temporária (propriedade java.io.tmpdir da JVM que roda seu servidor de aplicação) 
            </description>
        </init-param>
	-->
</filter>
 
<filter-mapping>
	<filter-name>extensionsFilter</filter-name>
	<!--
	    Coloque abaixo o nome do servlet que receberá todas as requisições JSF de sua aplicação, normalmente ele é definido como "Faces Servlet" e estará mapeado para *.jsf
	-->
	<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

Outra configuração básica mas muito importante, é a definição do atributo enctype em seu formulário (<h:form>) com o valor “multipart/form-data”. Ele indica que no envio do formulário conterá dados binários.
Por exemplo:

<h:form enctype="multipart/form-data">
...
</h:form>

Atributos do componente

 Após configurá-lô, basta utilizá-lô em sua página JSF com os atributos de sua escolha. Segue abaixo uma lista com as principais características deste componente.

Modo de usar: <t:inputFileUpload atributo=”valor” />

accept
Propriedade misteriosa, até o JSF 1.2 este atributo não servia para nada, a própria documentação não diz nada a respeito
OBS: Alguns tutoriais podem informar que este atributo serve para restringir extensões de arquivos, mas simplesmente não tem efeito nenhum

storage=”default/memory/file”
Define como será o armazenamento do arquivo enviado. Existem 3 opções:

  • default : O arquivo obedecerá a configuração definida no ExtensionFilter pelo uploadThresholdSize
  • memory: O arquivo será carregado na memória. Cuidado ao forçar esta opção quando for enviar arquivos grandes, uma exceção OutOfMemory é facilmente causada
  • file: O arquivo será armazenado em disco

value=”#{meuBean.arquivoUpload}”
Faz uma referência a um objeto UploadedFile que será instanciado automaticamente após o envio do formulário

Atributos Genéricos

Como todo componente JSF, o <t:inputFileUpload> também possui sua enorme lista de atributos padrões do JSF e HTML, como por exemplo: binding, converter, converterMessage, disabled, id, immediate, label, maxlength, readonly, rendered, required, requiredMessage, size, style, styleClass, title, validator, validatorMessage.

Eventos

Possui também uma lista de eventos para executar ações JavaScript, que são eles: onblur, onchange, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup, onmousedown, onmousemove, onmouseout, onmouseover, onmouseout, onselect.

Código Exemplo

<h:form enctype="multipart/form-data">
	<t:inputFileUpload id="fileupload" value="#{meuBean.arquivo}" />
	<h:commandButton value="Enviar" action="#{meuBean.enviar}" />
</h:form>
import org.apache.myfaces.custom.fileupload.UploadedFile;
 
public class MeuBean {
	private UploadedFile arquivo;
 
	public UploadedFile getArquivo() {
		return arquivo;
	}
 
	public void setArquivo(UploadedFile arquivo) {
		this.arquivo = arquivo;
	}
 
	public String enviar() {
		System.out.println("Nome do arquivo enviado: " + arquivo.getName());
		System.out.println("Tipo do arquivo enviado: " + arquivo.getContentType());
		System.out.println("Tamanho do arquivo enviado: " + arquivo.getSize());
		// arquivo.getBytes() retorna o conteúdo do arquivo em um array de bytes
		// arquivo.getInputStream() retorna o conteúdo do arquivo em um InputStream
		// arquivo.getStorageStrategy() retorna um objeto StorageStrategy. Permite obter mais informações e novas ações com o arquivo dependendo do lugar que foi armazenado
 
		return "ok";
	}
}

Possíveis Erros

NullPointerException
Se algum dos métodos do UploadedFile retornar null, como por exemplo o getBytes(), provavelmente você esqueceu de colocar o atributo enctype em seu formulário.

Java Heap Space
Fique atento a memória reservada para sua JVM em seu servidor, é facil atingir um Java Heap Space se você está enviando um arquivo pesado e armazenando-o na memória.

Para Saber Mais

http://myfaces.apache.org/tomahawk-project/tomahawk12/tagdoc/t_inputFileUpload.html
http://balusc.blogspot.com/2008/02/uploading-files-with-jsf.html


Utilizando o componente <rich:fileUpload>

<rich:fileUpload> é um componente do RichFaces introduzido na versão 3.2 que fornece a possibilidade de enviar arquivos ao servidor. Ele utiliza Ajax e estende o comportamento da tag padrão HTML <input type=”file”>.

Principais Funcionalidades

  • Envio de múltiplos arquivos
  • Envio automático ao selecionar um arquivo
  • Restringe tipos de arquivo
  • Restringe tamanho de arquivo
  • Define o tipo de armazenamento (pasta temporária ou memória)
  • Barra de progresso enquanto o arquivo é enviado

Configuração

Devido a grande quantidade de atributos que o componente possui ele se torna facilmente customizável, até o texto dos botões(Add, Stop, Clear) você pode mudar. Existem duas configurações que devem ser feitas inicialmente em seu web.xml.

Você precisa definir parâmetros iniciais para o Ajax4jsf Filter (pode estar com outro nome, mas refere-se ao filtro da classe org.ajax4jsf.Filter). Por exemplo:

web.xml   
<filter>
	<display-name>Ajax4jsf Filter</display-name>
	<filter-name>ajax4jsf</filter-name>
	<filter-class>org.ajax4jsf.Filter</filter-class>
	<init-param>
		<param-name>createTempFiles</param-name>
		<param-value>true</param-value>
	</init-param>
	<init-param>
		<param-name>maxRequestSize</param-name>
		<param-value>20000000</param-value>
	</init-param>
</filter>

Obs: Provavelmente você já tem esse filtro configurado, então apenas adicione as tags <init-param> dentro desta tag <filter>.

createTempDir
Este parâmetro booleano indica se os arquivos devem ser enviados para uma pasta temporária ou para memória RAM. O caminho da pasta temporária é obtido através da propriedade java.io.tmpdir da JVM, normalmente quando é carregada com o servidor de aplicação é definida como DIRETORIO_DO_SERVIDOR/temp) .
O armazenamento em memória pode ser interessante apenas para arquivos pequenos.

maxRequestSize
Este parâmetro informa o tamanho máximo em bytes que o arquivo enviado pode conter.

Atributos do Componente

Após configurá-lô, basta utilizá-lô em sua página JSF com os atributos de sua escolha. Segue abaixo uma lista com as principais características deste componente.
Modo de usar: <rich:fileUpload atributo=”valor” />

uploadData=”#{managedBean.arquivos}”
Faz uma referência dos arquivos enviados para um atributo de sua classe. Este atributo deve ser uma Collection de UploadItem.

fileUploadListener=”#{managedBean.uploadListener}”
Executa um método logo após o arquivo ser enviado ao servidor. Este método pode ter qualquer nome, mas deve receber apenas um parâmetro do tipo UploadEvent, através desse parâmetro você pode obter mais informações sobre os arquivos enviados.

immediateUpload=”true”
Força o upload automático do arquivo assim que selecionado, não será necessário escolher o arquivo e depois clicar em “Upload”.

autoClear=”true”
Remove os arquivos da lista quando o upload estiver completo.

acceptedTypes=”jpg, png, gif”
Define as extensões que serão aceitas no upload.

maxFilesQuantity=”3″
Define a quantidade máxima de arquivos que poderão ser enviados.

allowFlash=”true”
Utiliza um módulo em flash que adiciona funcionalidades extras. Por exemplo, selecionar vários arquivos de uma só vez, definir quais serão os tipos permitidos já na tela de “Selecionar Arquivo” ou inserir textos informando o status do upload.

Eventos

O componente também possui eventos para executar ações JavaScript. Como por exemplo: onadd, onupload, onuploadcomplete, onuploadcanceled e onerror. Os nomes já são auto-explicativos.

Texto dos Botões

Caso você queira alterar o texto dos botões, você também pode. Existem vários atributos para esta finalidade, são eles: addControlLabel, clearAllControlLabel, clearControlLabel, stopEntryControlLabel e uploadControlLabel.

Código Exemplo

<rich:fileUpload
	id="upload"
	fileUploadListener="#{arquivoBean.listener}"
	maxFilesQuantity="3"
	acceptedTypes="jpg, gif, png, bmp"
/>
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;
 
public class ArquivoBean {
	private UploadItem uploadItem;
 
	public void listener(UploadEvent event) {
		uploadItem = event.getUploadItem();
		System.out.println("Nome do arquivo enviado: " + uploadItem.getFileName());
		System.out.println("Tipo do arquivo enviado: " + uploadItem.getContentType());
		System.out.println("Tamanho do arquivo enviado: " + uploadItem.getFileSize());
		System.out.println("O arquivo foi gravado no disco?: " + uploadItem.isTemp());
		// uploadItem.getFile() retorna um tipo File do arquivo
		// uploadItem.getData() retorna um array de bytes do arquivo
	}
}

Possíveis Erros

NullPointerException
Se você estiver recebendo um objeto UploadItem nulo ou alguma chamada dessa instância retornar nula, fique atento aos seguintes fatores:

  • O método getData() retornará algo somente se o arquivo for gravado na memória (createTempDir definido como false)
  • O método getFile() retornará algo somente se o arquivo for gravado em disco, isto é, na pasta temporária (createTempDir como true)
  • Algumas coisas estranhas podem acontecer se você utilizar um escopo de request para este Managed Bean devido ao grande número de requisições Ajax, o seu objeto UploadItem simplesmente perde a referência, nem mesmo a tag <a4j:keepAlive> consegue guardá-lô, é recomendável que você utilize escopo de sessão para evitar problemas

Java Heap Space
Fique atento a memória reservada para sua JVM em seu servidor, é facil atingir um Java Heap Space se você está enviando um arquivo pesado e armazenando-o na memória.

Para Saber Mais

http://livedemo.exadel.com/richfaces-demo/richfaces/fileUpload.jsf
http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/rich_fileUpload.html

Copyright © 1996-2010 Sudog - Desenvolvendo soluções para programadores. All rights reserved.
iDream theme by Templates Next | Powered by WordPress