quinta-feira, 5 de janeiro de 2012

FileUpload com JSF + Primefaces + Hibernate + MySql

Nesse tutorial, tentarei explicar como fazer o upload de imagem, salvar o arquivo em um diretório e gravar o nome dele no banco (mysql) para depois ser exibido em uma view (usando o JSF).

O projeto que vamos fazer é simples, será o cadastro de um produto com os seguintes atributos:
id, nome, preço e foto do produto.

==> Crie a base de dados ou utilize uma já existente, no meu caso, irei criar uma nova base de dados com o nome fileUpload.

==> Crie um novo projeto web com suporte a JSF, Primefaces e Hibernate (utilizando o banco criado acima).

==> Crie a estrutura de pacotes
- managedBean (controller)
- dao (persistência)
- entidades (POJO)

==> Agora vamos fazer o POJO de produtos. Dentro do pacote entidades crie uma nova classe com o nome Produto


2
5package entidades;
6
7/**
8 *
9 * @author Mara
10 */
11import javax.persistence.*;
12@Entity
13@Table(name="tb_produto")
14public class Produto{
15@Id
16@GeneratedValue(strategy=GenerationType.AUTO)
17@Column(name="prod_id")
18private int id;
19@Column(name="prod_nome")
20private String nome;
21@Column(name="prod_preco")
22private double preco;
23@Column(name="prod_foto")
24private String foto;
25

// Construtor getters e setters
29


Obs.: faça o import das anotações do pacote javax.persistence.*

==> Crie a classe HibernateUtil dentro do pacote dao.
caso tenha dúvida de como implementar a HibernateUtil consulte http://meninajava.blogspot.com/2011/11/configurar-o-hibernate-utilizando.html

==> Adicione o mapeamento da classe Produto no arquivo hibernate.cfg.xml e habilite para hibernate criar automaticamente a tabela no banco.





10<property name="hibernate.hbm2ddl.auto">update</property>
11<mapping class="entidades.Produto"/>
12


Agora vamos fazer a classe ProdutoDao que terá os metódos para persistir e consultar os dados do banco.

==> Dentro do pacote dao, crie uma nova classe com o nome ProdutoDao e implemente pelo menos os metódos de salvar e consultar todos os produtos, para este tutorial iremos utilizar somente estes dois.



3package dao;
4
8import entidades.Produto;
9import java.util.List;
10import org.hibernate.Session;
11
12public class ProdutoDao {
13public void salvar(Produto produto){
14Session session = HibernateUtil.getSession();
15session.beginTransaction().begin();
16session.saveOrUpdate(produto);
17session.getTransaction().commit();
18session.close();
19System.out.println("Salvo com sucesso");
20}
21
22public List<Produto> listar(){
23Session session= HibernateUtil.getSession();
24String sql = "SELECT p FROM Produto p";
25return (List<Produto>) session.createQuery(sql).list();
26}
27}



==> Faça o download de duas bibliotecas extras:




Após baixar os arquivos, adicione as depedências ao seu projeto.


==> Configure o arquivo web.xml adicionando o filter do fileUpload.

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



No post anterior fiz o método de upload do arquivo no mangedBean, para faciliar as futuras implementações desta funcionalidade, criei uma classe UploadArquivo que ficará responsável pelo upload. Assim quando o usuário pressionar o botão salvar do formulário, é armazenado o arquivo e os dados no banco.

==> No pacote managedBean crie uma nova classe com o nome UploadArquivo e implemente o código abaixo.

5package managedBean;
6
7import java.io.File;
8import java.io.FileOutputStream;
9import java.util.logging.Level;
10import java.util.logging.Logger;
11import javax.faces.context.ExternalContext;
12import javax.faces.context.FacesContext;
13import javax.servlet.ServletContext;
14import javax.servlet.http.HttpServletResponse;
15import org.primefaces.event.FileUploadEvent;
16



21public class UploadArquivo {
22private String diretorio;
23private String caminho;
24private byte[] arquivo;
25private String nome;
26
27public UploadArquivo() {
28}


46public String getNome() {
47return nome;
48}



54public String getRealPath() {
55ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
56HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
57
58FacesContext aFacesContext = FacesContext.getCurrentInstance();
59ServletContext context = (ServletContext) aFacesContext.getExternalContext().getContext();
60
61return context.getRealPath("/");
62}
63
64public void fileUpload(FileUploadEvent event, String type, String diretorio) {
65try {
66this.nome = new java.util.Date().getTime() + type;
67this.caminho = getRealPath() + diretorio + getNome();
68this.arquivo = event.getFile().getContents();
69
70File file = new File(getRealPath() + diretorio);
71file.mkdirs();
72
73} catch (Exception ex) {
74System.out.println("Erro no upload do arquivo" + ex);
75}
76}
77
78public void gravar(){
79
80try {
81
82FileOutputStream fos;
83fos = new FileOutputStream(this.caminho);
84fos.write(this.arquivo);
85fos.close();
86
87} catch (Exception ex) {
88System.out.println(ex);
89}
90
91}
92}


Linha 54 - O método getRealPath pega o diretório completo da sua aplicação no servidor.
Linha 64 - O método fileUpload irá fazer o carregamento do arquivo e prepara-lo para ser gravado.
Linha 78 - O método salvar, grava o arquivo no diretório informado.
Os arquivos serão armazenados na pasta build/web/nomediretorio do seu projeto.

==> No pacote managedBean crie uma nova classe com o nome ProdutoManagedBean e implemente o código abaixo.



5package managedBean;
6
7import javax.faces.bean.ManagedBean;
8import javax.faces.bean.SessionScoped;
9import entidades.Produto;
10import dao.ProdutoDao;
11import java.util.ArrayList;
12import java.util.List;
13import org.primefaces.event.FileUploadEvent;
14/**
15 *
16 * @author Mara
17 */
18@ManagedBean(name="produtoMB")
19@SessionScoped
20public class ProdutoManagedBean {
21private Produto produto;
22private List<Produto> listarProdutos;
23private UploadArquivo arquivo = new UploadArquivo();
24
25public ProdutoManagedBean() {
26this.produto = new Produto();
27this.listarProdutos = new ArrayList<Produto>();
28}
29
30public List<Produto> getListarProdutos() {
31return new ProdutoDao().listar();
32//return this.listarProdutos;
33}
34
35public void setListarProdutos(List<Produto> listarProdutos) {
36this.listarProdutos = listarProdutos;
37}
38
39public Produto getProduto() {
40return produto;
41}
42
43public void setProduto(Produto produto) {
44this.produto = produto;
45}
46
47public void uploadAction (FileUploadEvent event){
48this.arquivo.fileUpload(event, ".jpg", "/image/");
49this.produto.setFoto(this.arquivo.getNome());
50}
51
52public void salvar(){
53new ProdutoDao().salvar(produto);
54this.arquivo.gravar();
55
56this.produto = new Produto();
57this.arquivo = new UploadArquivo();
58}
59}



Linha 47 - Método que será chamado pela view para o upload do arquivo. O arquivo será carregado mas ainda não será salvo no diretório.
Linha 54 - Quando o usuário pressionar no botão salvar do formulário, os dados serão persistidos no banco e o arquivo será gravado no diretório.

==> Agora vamos fazer a view, no arquivo index implemente o código abaixo:


1<?xml version='1.0' encoding='UTF-8' ?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml"
4xmlns:p="http://primefaces.prime.com.tr/ui"
5xmlns:h="http://java.sun.com/jsf/html"
6xmlns:f="http://java.sun.com/jsf/core">
7<h:head>
8<title>File Upload</title>
9</h:head>
10<h:body>
11<h1>Inserir Produto</h1>
12<h:form>
13<h:panelGrid columns="2">
14Nome: <h:inputText value="#{produtoMB.produto.nome}"/>
15Preço: <h:inputText value="#{produtoMB.produto.preco}"/>
16
17Foto: <p:fileUpload id="upload" update="foto"
18fileUploadListener="#{produtoMB.uploadAction}" auto="true"/>
19
20<h:commandButton action="#{produtoMB.salvar}" value="Salvar" />
21</h:panelGrid>
22</h:form>
23
24<h2>Produtos Cadastrados</h2>
25<h:form>
26<h:dataTable var="produto" value="#{produtoMB.listarProdutos}" >
27<h:column>
28<f:facet name="header">Foto</f:facet>
29<h:graphicImage value="./image/#{produto.foto}"/>
30</h:column>
31<h:column>
32<f:facet name="header">Nome</f:facet>
33<h:outputText value="#{produto.nome}"/>
34</h:column>
35<h:column>
36<f:facet name="header">Preço</f:facet>
37<h:outputText value="#{produto.preco}"/>
38</h:column>
40</h:dataTable>
41</h:form>
42</h:body>
43</html>
44


Acesse https://github.com/MaraRegina/FileUpload, visualize o projeto completo ou faça o download para testar.