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