Monthly Archives: January 2017

Upload Ajax de Imagem com Preview no Primefaces

Um problema que me deu dor de cabeça:
Fazer upload de imagem via ajax e dar um preview, utilizando o componente fileupload do Primefaces. Já estava me sentindo derrotado com o problema.

O componente é bizonho, (Spoiler alert!) ele não funciona fora de um SessionScoped . Mas, como sou guerreiro, e como a arquitetura da minha aplicação precisa de ManagedBeans com ViewScoped , Entoado por canções de cunho moral, eu insisti e consegui contornar o problema.

Outro alerta de spoiler:
Ainda não testei em plenos vapores de ambiente de produção, se alguém encontrar um erro, por favor relate e talvez em menos de um ano eu responda.

Primeiro passo:

Criar um ManagedBean, do tipo SessionScoped :

@ManagedBean
@SessionScoped
public class ImageBean {
	
	StreamedContent st;
	
	public void uploadImagem(byte[] imagem){
		
		st = new DefaultStreamedContent(new ByteArrayInputStream(imagem));
		
	}
	
	public StreamedContent getSt() {
		return st;
	}
}

Nesse ManagedBean, incluímos um objeto StreamedContent , que vai possibilitar o preview da imagem no  componente graphicimage do Primefaces, e um método que recebe um bytearray que é a imagem. No caso, esse método pode ser adaptado, eu estou utilizando um tipo bytearray porque gravo a imagem no banco.

Depois disso, vamos tratar do nosso ManagedBean da página:

@ManagedBean
@ViewScoped
public class CadastrarPessoaBean {

	@EJB
	PessoaFacade pessoaFacade;
	
	@ManagedProperty(value="#{imageBean}")
	ImageBean imageBean;

	Pessoa pessoa = new Pessoa();

	public void anexaArquivo(FileUploadEvent event) {

		try {
			this.pessoa.setFoto(IOUtils.toByteArray(event.getFile().getInputstream()));
			imageBean.uploadImagem(this.pessoa.getFoto());
		} catch (IOException e) {
			/* Joga alguma mensagem na tela! */
		}

	}

}

Aqui, criei um método chamado anexaArquivo, este método vai primeiro, popular meu objeto Pessoa para salvar a foto em banco, e depois vai popular o ImageBean.

Por fim, adicionamos os componentes nas páginas, e é só aproveitar a magia:

<h:panelGroup id="imagemJogador">
	<p:graphicImage id="foto_jogador" style="max-width: 300px;max-height: 300px;" cache="false" value="#{imageBean.st}">
	</p:graphicImage><br/>
</h:panelGroup>

<p:fileUpload fileUploadListener="#{jogadorCadastrarBean.anexaArquivo}"
mode="advanced" showButtons="false" label="#{lang.procurar}"
update="imagemJogador" auto="true" sizeLimit="#{jogadorCadastrarBean.maxSize}"  allowTypes="/(\.|\/)(gif|jpe?g|png)$/" ></p:fileUpload>
 <p:growl id="messages" showDetail="true" />

Vejam só, o componente p:fileUpload possui um método chamado fileUploadListener, que foi colocado no ManagedBean da página, e o componente p:graphicImage busca o StreamedContent lá no Imagebean

É claro isso é um exemplo cru, eu deixei desta forma para que fique simples e fácil de entender(Eu acho). Algo direto, dentro disso você pode(e DEVE) garantir validações de arquivo, tamanho de arquivo, e etc. dentro do ManagedBean.