Como usar GraphicImage no Primefaces

Como usar GraphicImage no Primefaces

PrimeFaces

Neste exemplo temos uma alternativa para usar o GraphicImage no PrimeFaces com JSF 2 para mostrar uma imagem gravada no banco de dados.

O GraphicImage é um componente prático porque elimina a necessidade de servlets ou outros artifícios para carregar a imagem.

Um ponto importante é que o GraphicImage não funciona com @ViewScope, que é muito usado nas aplicações com JSF 2. Ele funciona apenas com @SessionScope e @RequestScope. Para resolver esse problema, criei o ImagemProdutoBean, um managed bean com @RequestScope.

Código-fonte

O projeto completo está disponível no GitHub. Além do GraphicImage, o projeto mostra exemplos de outros componentes PrimeFaces, além de soluções simples para problemas comuns de aplicações web.

Persistência

No nosso exemplo vamos criar a classe Produto com o atributo byte[] foto, que deve ter a anotação @Lob. Em alguns bancos de dados temos que definir um tamanho desse arquivo, como é o caso do HSQLDB, que é usado no exemplo. No MySQL não é necessário.


public class Produto {
{...}
@Lob
@Column(length = 1024 * 1024 * 5)
private byte[] especificacaoFabricante;
@Lob
@Column(length = 1024 * 1024 * 5)
private byte[] foto;
{...}
}

JSF

A página produto.xhtml vai mostrar a imagem através do managed bean imagemProdutoBean.


{…}

id=”uploadfotoProduto” /> id=”uploadfotoProduto” /> actionListener=”#{produtoBean.salvar}” icon=”ui-icon-disk”
update=”messages” />

{…}

 

Managed bean

Precisamos de 2 managed beans. O primeiro, ProdutoBean, é para a página XHTML e tem escopo @ViewScoped. O segundo, ImagemProdutoBean é somente para a imagem e pode ser @RequestScoped ou @SessionScoped. Eu prefiro o @RequestScoped, mas fica a critério de cada um.

Observe o método salvar(), que deve ter uma condição para não apagar a imagem já gravada, no caso em que o usuário está fazendo a edição do registro.

Para esse exemplo, o ajax do upload está desabilitado. Para habilitar o ajax, você pode usar essa dica.


@ViewScoped
@ManagedBean
public class ProdutoBean {

{…}

private UploadedFile foto;
private Produto produto;

public void setFoto(UploadedFile foto) {
this.foto = foto;
}

public UploadedFile getFoto() {
return foto;
}

public boolean isExisteFoto() {
try {
return getProduto().getFoto().length > 0;
} catch (Exception e) {
return false;
}
}

public void salvar() {
try {
//
if (getEspecificacaoFabricante() != null
&& getEspecificacaoFabricante().getSize() > 0) {
byte[] dados = IOUtils.toByteArray(getEspecificacaoFabricante()
.getInputstream());
getProduto().setEspecificacaoFabricante(dados);
}
//
if (getFoto() != null && getFoto().getSize() > 0) {
byte[] dados = IOUtils.toByteArray(getFoto().getInputstream());
getProduto().setFoto(dados);
}
//
getProdutoService().salvar(getProduto());
infoMsg(MENSAGEM_SUCESSO_GRAVACAO);
} catch (Exception e) {
errorMsg(e);
}
}

}

GraphicImage no Primefaces

Essa é a abordagem mais simples para mostrar uma imagem no PrimeFaces. E pode ser usada no sistema todo.

Um detalhe é que o PrimeFaces executa duas vezes o método getConteudoImagem() e somente da segunda vez é que a imagem deve ser carregada.

 

package net.marcoreis.ecommerce.controlador;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;

import net.marcoreis.ecommerce.entidades.Produto;
import net.marcoreis.ecommerce.negocio.GenericService;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

@ManagedBean
@RequestScoped
public class ImagemProdutoBean extends BaseBean {
private static final long serialVersionUID = -7524476303834771432L;
private Produto produto;

@PostConstruct
public void init() {
produto = new Produto();
}

public StreamedContent getConteudoImagem() {
try {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
}
String idS = getParametro(“id”);
Long id = Long.parseLong(idS);
produto = (Produto) new GenericService()
.findById(Produto.class, id);
InputStream is = new ByteArrayInputStream(produto.getFoto());
DefaultStreamedContent dsc = new DefaultStreamedContent(is);
return dsc;
} catch (Exception e) {
return new DefaultStreamedContent();
}
}

}

Leave a Reply

Your email address will not be published. Required fields are marked *