Aprenda Java Web JSF

  • Página Inicial
  • Contato!
  • Tudo sobre Java Web JSF Parte 1!
  • Tudo sobre Java Web JSF Parte 2!
  • Tudo sobre Java Web JSF Parte 3!
  • Tudo sobre Java Web JSF Parte 4!
  • Tudo sobre Java Web JSF Parte 3

    Tratando Erros

    O Java já trata erros por padrão para evitar problemas com os aplicativos, diferente de outras linguagens, mas também podemos criar e gerenciar nossas exceções. Para podermos tratar erros corretamente e escrever mensagens no site, vamos começar criando uma classe no pacote util. com o nome ErroSistema, com esse código, onde temos uma herança de Exception (que trata erros e possuí alguns construtores e métodos), esta que herda de Throwable:

    
    package util;
    
    public class ErroSistema extends Exception { 
        public ErroSistema(String message) {
            super(message);
        }
        
        public ErroSistema(String message, Throwable cause) {
            super(message, cause);
        } 
    }
    
    

    E no FabricaConexao, altere o que estiver dentro do if de getConexao(), dessa forma:

    
    public static Connection getConexao() throws ErroSistema {
        if(conexao == null) {
            try {
                Class.forName("com.mysql.jdbc.Driver");
                conexao = DriverManager.getConnection(URL_CONEXAO, USUARIO, SENHA);
            }
            catch(SQLException ex) {
                throw new ErroSistema("Não foi Possível Conectar ao Banco de Dados!", ex);
            }  
            catch(ClassNotFoundException ex) {
                throw new ErroSistema("O Driver do Banco de Dados não foi Encontrado!", ex);
            }   
        }
        return conexao;
    }
    
    

    E também em FecharConexão:

    
    public static void fecharConexao() throws ErroSistema {
        if(conexao != null) {
            try {
                conexao.close();
                conexao = null;
            }
            catch(SQLException ex) {
                throw new ErroSistema("Erro ao Fechar a Conexão do Banco de Dados!", ex);
            }
        }
    }
    
    

    PS: Os erros serão "lançados" pra cima, nesse caso, por isso é necessário indicar o throws no método

    Observe que em CarroDAO, já aparecerá um "erro" em conexao dos métodos como o salvar() e buscar(), mas esse erro foi nós que criamos, para corrigir adicione o throwa ErroSistema em todos os métodos dele, não esqueça das importações.

    Em CarroDAO, aproveitando, crie o método deletar, dessa forma:

    
    public void deletar(Integer idC) throws ErroSistema {
        String sql = "delete from carro where id = ?";
    
        try {
            PreparedStatement ps = conexao.prepareStatement(sql);
    
            ps.setInt(1, idC);
            ps.execute();
        }
        catch(SQLException ex) {
            throw new ErroSistema("Erro ao Deletar o Carro!", ex);
        }
    }
    
    

    E altere o Catch de salvar(), assim:

    
    catch(SQLException ex) {
        throw new ErroSistema("Erro ao Tentar Salvar!", ex);
    }
    
    

    E em buscar(), retirando também o retorno dele:

    
    catch(SQLException ex) {
        throw new ErroSistema("Erro ao Buscar os Dados!", ex);
    }
    
    

    Agora, no CarroBean, crie um método para adicionar mensagens, dessa forma:

    
    public void adicionarMensagem(String sumario, String detalhe, FacesMessage.Severity tipoErro) { // Importe
        FacesContext context = FacesContext.getCurrentInstance(); // Importe
        FacesMessage message = new FacesMessage(tipoErro, sumario, detalhe);
    
        context.addMessage(null, message);
    }
    
    

    E adicione try catch nos outros métodos (retire a inicialização no atributo private de carD e deixe somente o do construtor), e crie o deletar(), dessa forma:

    
    public void adicionar() {
        try {
            carD.salvar(car);
            car = new Carro();
            adicionarMensagem("Salvo!", "Carro Salvo com Sucesso!", FacesMessage.SEVERITY_INFO);
        }
        catch(ErroSistema ex) {
            adicionarMensagem(ex.getMessage(), ex.getCause().getMessage(), FacesMessage.SEVERITY_ERROR);
        }
    }
    
    public void listar() {
        try {
            carros = carD.buscar();
            if(carros == null || carros.isEmpty()) {
                adicionarMensagem("Nenhum Dado Encontrado!", "Sua Busca não Retornou Nenhum Dado!", FacesMessage.SEVERITY_WARN);
            }
        }
        catch(ErroSistema ex) {
            adicionarMensagem(ex.getMessage(), ex.getCause().getMessage(), FacesMessage.SEVERITY_ERROR);
        }
    }
    
    public void deletar(Carro c) {
        try {
            carD.deletar(c.getId());
            adicionarMensagem("Deletado!", "Carro Deletado com Sucesso!", FacesMessage.SEVERITY_INFO);
        }
        catch(ErroSistema ex) {
            adicionarMensagem(ex.getMessage(), ex.getCause().getMessage(), FacesMessage.SEVERITY_ERROR);
        }
    }
    
    public void editar(Carro c) {
        car = c;
    }
    
    

    No XHTML, coloque essa tag debaix da toolbarGroup:

    
    <p:messages autoUpdate="true" showDetail="true"></p:messages>
    
    

    E dentro do dataTable, logo abaixo do botão de editar, coloque isso:

    
    <p:column>
        <p:commandButton value="Deletar" action="#{carroBean.deletar(carroForm)}" update="@form"></p:commandButton>
    </p:column>
    
    

    Implementando CRUD

    O CRUD é usado para criar um modelo genérico que atenda boa parte das telas do nosso projeto, diminuindo a codificação.

    CRUD é uma sigla para Creat Read Update Delete, no caso, o Create seria como o insert do SQL e o Read seria como o select do mesmo.

    Para trabalharmos com CRUD, precisamos criar umas peças-chaves para isso. Vamos usar o modelo Generics do Java. Toda classe DAO que criamos deverá implementar essa nossa interface.

    Devemos também criar um CrudBean genérico para isso também, com a mesma interface DAO e também com o Generics. Os métodos controlarão a tela.

    Vamos criar no pacote dao a interface CrudDAO, com esse código:

    
    package dao;
    
    import java.util.List;
    import util.ErroSistema;
    
    public interface CrudDAO<E> { // O E dentro das tags representa nossa entidade, substituida pela classe
        public void salvar(E entidade) throws ErroSistema;
        public void deletar(E entidade) throws ErroSistema;
        public List<E> buscar() throws ErroSistema;
    }
    
    

    Volte na classe CarroDAO, e coloque a implementação dessa interface (com public class CarroDAO implements CrudDAO<Carro>) e os override nos métodos buscar() e salvar().

    PS: No método deletar() devemos fazer uma alteração dessa forma:

    
    @Override
    public void deletar(Carro car) throws ErroSistema {
        String sql = "delete from carro where id = ?";
    
        try {
            PreparedStatement ps = conexao.prepareStatement(sql);
    
            ps.setInt(1, car.getId());
            ps.execute();
        }
        catch(SQLException ex) {
            throw new ErroSistema("Erro ao Deletar o Carro!", ex);
        }
    }
    
    

    Crie uma classe CrudBean no pacote bean e salve esse código:

    
    package beans;
    
    public class CrudBean {
        private String estadoTela = "buscar"; // Inseri, Edita, Busca
        
        public boolean isInseri() {
            return estadoTela.equals("inserir"); // Se for igual ao estadoTela retona true, senão retorna false.
        }
        public boolean isEdita() {
            return estadoTela.equals("editar");
        }
        public boolean isBusca() {
            return estadoTela.equals("buscar");
        }
        
        public void mudaParaInserir() {
            estadoTela = "inserir";
        }
        
        public void mudaParaEditar() {
            estadoTela = "editar";
        }
        
        public void mudaParaBuscar() {
            estadoTela = "buscar";
        }
    }   
    
    

    E em CarroBean, apague tudo de dentro da classe, e coloque o extends para herança do CrudBean.

    Num XHTML denominado controle-tela, coloque esse código:

    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <ui:decorate xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" template="template.xhtml">
        <h1>Bem-Vindo ao Sistema</h1>
        <h:form>
            <p:commandButton value="Mudar para Inserir" action="#{carroBean.mudaParaInserir()}" update="@form"></p:commandButton>
            <p:commandButton value="Mudar para Editar" action="#{carroBean.mudaParaEditar()}" update="@form"></p:commandButton>
            <p:commandButton value="Mudar para Buscar" action="#{carroBean.mudaParaBuscar()}" update="@form"></p:commandButton>
            
            <h:outputText value="Inserir" rendered="#{carroBean.inseri}"></h:outputText>
            <h:outputText value="Editar" rendered="#{carroBean.edita}"></h:outputText>
            <h:outputText value="Buscar" rendered="#{carroBean.busca}"></h:outputText>
            
            <h1><h:outputText value="Só Aparece Quando não for Buscar" rendered="#{carroBean.busca == false}"></h:outputText></h1>
            <h1><h:outputText value="Só Aparece Quando for Buscar" rendered="#{carroBean.busca == true}"></h:outputText></h1>
        </h:form>
    </ui:decorate>
    
    

    Isso acima é útil para mostrar variados estados no nosso site, dá pra usar com outros recursos.

    Altere o CrudBean dessa forma:

    
    package beans;
    
    import dao.CrudDAO;
    import java.util.List;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.faces.application.FacesMessage;
    import javax.faces.context.FacesContext;
    import util.ErroSistema;
    
    public abstract class CrudBean<E, D extends CrudDAO> {
        private String estadoTela = "buscar";
        private E entidade;
        private List<E> entidadeList;
        
        public void novo() {
            entidade = criarNovaEntidade();
            mudaParaInserir();
        }
        
        public void salvar() {
            try {
                getDao().salvar(entidade); // Esses métodos vem da interface.
                entidade = criarNovaEntidade();
                adicionarMensagem("Salvo com Sucesso!", FacesMessage.SEVERITY_INFO);
                mudaParaBuscar();
            }
            catch(ErroSistema ex) {
                adicionarMensagem(ex.getMessage(), FacesMessage.SEVERITY_ERROR);
            }
        }
        
        public void editar(E ent) {
            this.entidade = ent;
            mudaParaEditar();
        }
        
        public void deletar(E ent) {
            try {
                getDao().deletar(ent);
                entidadeList.remove(ent);
                adicionarMensagem("Deletado com Sucesso!", FacesMessage.SEVERITY_INFO);
            }
            catch(ErroSistema ex) {
                adicionarMensagem(ex.getMessage(), FacesMessage.SEVERITY_ERROR);
            }
        }
        
        public void buscar() {
            if(isBusca() == false) {
                mudaParaBuscar();
                return;
            }
            try {
                entidadeList = getDao().buscar();
                if(entidadeList == null || entidadeList.size() < 1) {
                    adicionarMensagem("Não Temos Nada Cadastrado", FacesMessage.SEVERITY_WARN);
                }
            }
            catch(ErroSistema ex) {
                Logger.getLogger(CrudBean.class.getName()).log(Level.SEVERE, null, ex);
                adicionarMensagem(ex.getMessage(), FacesMessage.SEVERITY_ERROR);
            }
        }
        
        public void adicionarMensagem(String mensagem, FacesMessage.Severity tipoErro) {
            FacesMessage fm = new FacesMessage(tipoErro, mensagem, null);
            FacesContext.getCurrentInstance().addMessage(null, fm);
        }
        
        // Responsável por criar os métodos nas classes bean.
        public abstract D getDao();
        public abstract E criarNovaEntidade();
        
        public boolean isInseri() {
            return estadoTela.equals("inserir"); // Se for igual ao estadoTela retona true, senão retorna false.
        }
        public boolean isEdita() {
            return estadoTela.equals("editar");
        }
        public boolean isBusca() {
            return estadoTela.equals("buscar");
        }
        
        public void mudaParaInserir() {
            estadoTela = "inserir";
        }
        
        public void mudaParaEditar() {
            estadoTela = "editar";
        }
        
        public void mudaParaBuscar() {
            estadoTela = "buscar";
        }
    
        public String getEstadoTela() {
            return estadoTela;
        }
    
        public void setEstadoTela(String estadoTela) {
            this.estadoTela = estadoTela;
        }
    
        public E getEntidade() {
            return entidade;
        }
    
        public void setEntidade(E entidade) {
            this.entidade = entidade;
        }
    
        public List<E> getEntidadeList() {
            return entidadeList;
        }
    
        public void setEntidadeList(List<E> entidadeList) {
            this.entidadeList = entidadeList;
        }
    }   
    
    

    Altere também o CarroBean dessa forma:

    
    package beans;
    
    import classes.Carro;
    import dao.CarroDAO;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.SessionScoped;
    import util.ErroSistema;
    
    @SessionScoped
    @ManagedBean
    public class CarroBean extends CrudBean<Carro, CarroDAO> {
        private CarroDAO carD;
        
        @Override
        public CarroDAO getDao() {
            if(carD == null) {
                try {
                    carD = new CarroDAO();
                }
                catch(ErroSistema ex) {
                    Logger.getLogger(CarroBean.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            
            return carD;
        }
    
        @Override
        public Carro criarNovaEntidade() {
            return new Carro();
        }
    }
    
    

    E no gerenciar-carro, altere o XHTML substituindo o car por entidade, e o carros por entidadeList, apenas nessas linhas indicadas abaixo:

    
    <p:toolbarGroup>
        <p:commandButton value="Novo" action="#{carroBean.novo()}" update="@form"></p:commandButton>
        <p:commandButton value="Salvar" action="#{carroBean.salvar()}" disabled="#{carroBean.busca == true}" update="@form"></p:commandButton>
        <p:commandButton value="Buscar" action="#{carroBean.buscar()}" update="@form"></p:commandButton>
    </p:toolbarGroup>
    <p:panelGrid columns="2" rendered="#{carroBean.busca == false}">
         <h:outputLabel value="Modelo"></h:outputLabel>
         <p:inputText value="#{carroBean.entidade.modelo}"></p:inputText>
         <h:outputLabel value="Fabricante"></h:outputLabel>
         <p:inputText value="#{carroBean.entidade.fabricante}"></p:inputText>
         <h:outputLabel value="Cor"></h:outputLabel>
         <p:inputText value="#{carroBean.entidade.cor}"></p:inputText>
         <h:outputLabel value="Ano"></h:outputLabel>
         <p:inputMask mask="9999" value="#{carroBean.entidade.ano}"></p:inputMask>
     </p:panelGrid>
     <p:dataTable value="#{carroBean.getEntidadeList()}" var="carroForm" rendered="#{carroBean.busca == true}">
    
    

    Agora crie uma nova tabela no banco de dados, com esse código:

    
    use sistema_carros;
    create table usuario (
        id int not null auto_increment,
        login varchar(20),
        senha varchar(32),
        primary key(id)
    )
    default charset = utf8;
    
    

    Crie no pacote classes uma classe com o nome Usuario, com esse código:

    
    package classes;
    
    import java.util.Objects;
    
    public class Usuario {
        private Integer id; // Use Integer por este criar objeto e permitir o valor null
        public String login;
        public String senha;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getLogin() {
            return login;
        }
    
        public void setLogin(String login) {
            this.login = login;
        }
    
        public String getSenha() {
            return senha;
        }
    
        public void setSenha(String senha) {
            this.senha = senha;
        }
    
        @Override
        public int hashCode() {
            int hash = 5;
            hash = 89 * hash + Objects.hashCode(this.id);
            hash = 89 * hash + Objects.hashCode(this.login);
            hash = 89 * hash + Objects.hashCode(this.senha);
            return hash;
        }
    
        @Override
        public boolean equals(Object obj) {
            if(this == obj) {
                return true;
            }
    
            if(obj == null) {
                return false;
            }
    
            if(getClass() != obj.getClass()) {
                return false;
            }
    
            final Usuario other = (Usuario)obj;
    
            if(!Objects.equals(this.login, other.login)) {
                return false;
            }
    
            if(!Objects.equals(this.senha, other.senha)) {
                return false;
            }
    
            if(!Objects.equals(this.id, other.id)) {
                return false;
            }
            return true;
        }
    }
    
    

    Crie no pacote dao uma classe com nome UsuarioDAO, com esse código:

    
    package dao;
    
    import classes.Usuario;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    import util.ErroSistema;
    import util.FabricaConexao;
    
    public class UsuarioDAO implements CrudDAO<Usuario> {
        private Connection conexao = null;
    
        public UsuarioDAO() throws ErroSistema {
            conexao = FabricaConexao.getConexao();
        }
    
        @Override
        public void salvar(Usuario ent) throws ErroSistema {
            String sql;
    
            try {
                PreparedStatement ps;
                
                if(ent.getId() == null) {
                    sql = "insert into usuario (login, senha) values (?, ?)";
    
                    ps = conexao.prepareStatement(sql);
                }
                else {
                    sql = "update usuario set login = ?, senha = ? where id = ?";
    
                    ps = conexao.prepareStatement(sql);
                    ps.setInt(3, ent.getId());
                }
                
                ps.setString(1, ent.getLogin());
                ps.setString(2, ent.getSenha());
                ps.execute();
                
                FabricaConexao.fecharConexao();
            }
            catch(SQLException ex) {
                throw new ErroSistema("Erro ao Tentar Salvar!", ex);
            }  
        }
        
        @Override
        public List<Usuario> buscar() throws ErroSistema { // Importe
            String sql = "select * from usuario";
    
            try {
                PreparedStatement ps = conexao.prepareStatement(sql);
                ResultSet results = ps.executeQuery(); // Importe
                List<Usuario> usuarios = new ArrayList<>(); // Importe
                
                while(results.next()) {
                    Usuario user = new Usuario();
                    
                    user.setId(results.getInt("id")); // Isso pega o valor da coluna id da tabela.
                    user.setLogin(results.getString("login"));
                    user.setSenha(results.getString("senha"));
                    
                    usuarios.add(user);
                }
                return usuarios;
            }
            catch(SQLException ex) {
                throw new ErroSistema("Erro ao Buscar os Dados!", ex);
            }
        }
        
        @Override
        public void deletar(Usuario ent) throws ErroSistema {
            String sql = "delete from usuario where id = ?";
    
            try {
                PreparedStatement ps = conexao.prepareStatement(sql);
    
                ps.setInt(1, ent.getId());
                ps.execute();
            }
            catch(SQLException ex) {
                throw new ErroSistema("Erro ao Deletar o Usuário!", ex);
            }
        }
    }
    
    

    E na beans, uma classe com o nome UsuarioBean com esse código:

    
    package beans;
    
    import classes.Usuario;
    import dao.UsuarioDAO;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.SessionScoped;
    
    @ManagedBean
    @SessionScoped
    public class UsuarioBean extends CrudBean<Usuario, UsuarioDAO> {
        private UsuarioDAO userD;
    
        @Override
        public UsuarioDAO getDao() {
            if(userD == null) {
                try {
                    userD = new UsuarioDAO();
                }
                catch(ErroSistema ex) {
                    Logger.getLogger(UsuarioBean.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            
            return userD;
        }
    
        @Override
        public Usuario criarNovaEntidade() {
            return new Usuario();
        }
    }
    
    

    Agora vá em controle-tela.xhtml e coloque o código assim:

    
    <ui:decorate xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" template="template.xhtml">
        <h1>Bem-Vindo ao Sistema</h1>
        <h:form>
            <p:messages autoUpdate="true" showDetail="true"></p:messages>
            <p:fieldset legend="Objetos">
                <p:toolbarGroup>
                    <p:commandButton value="Novo" action="#{usuarioBean.novo()}" update="@form"></p:commandButton>
                    <p:commandButton value="Salvar" action="#{usuarioBean.salvar()}" disabled="#{usuarioBean.busca == true}" update="@form"></p:commandButton>
                    <p:commandButton value="Buscar" action="#{usuarioBean.buscar()}" update="@form"></p:commandButton>
                </p:toolbarGroup>
                <p:panelGrid columns="2" rendered="#{usuarioBean.busca == false}">
                    <h:outputLabel></h:outputLabel>
                    <p:inputText value="#{usuarioBean.entidade.login}"></p:inputText>
                    <h:outputLabel></h:outputLabel>
                    <p:password value="#{usuarioBean.entidade.senha}"></p:password>
                </p:panelGrid>
                <p:dataTable value="#{usuarioBean.getEntidadeList()}" var="usuarioForm" rendered="#{usuarioBean.busca == true}">
                    <p:column>
                        <p:commandButton value="Editar" action="#{usuarioBean.editar(usuarioForm)}" update="@form"></p:commandButton>
                        <p:commandButton value="Deletar" action="#{usuarioBean.deletar(usuarioForm)}" update="@form"></p:commandButton>
                    </p:column>
                    <p:column headerText="Login">
                        #{usuarioForm.login}
                    </p:column>
                    <p:column headerText="Senha">
                        #{usuarioForm.senha}
                    </p:column>
                </p:dataTable>
            </p:fieldset>
        </h:form>
    </ui:decorate>