Laboratório PROGRAMAÇÃO WEB II: Prática 8
Ferramentas utilizadas: • NetBeans;
Cadastro de Contas com Ajax
Nesta aula iremos construir um cadastro de contas bancarias. Este cadastro utiliza um conceito diferente de funcionamento diferente do cadastro de usuários, pois permitirá que o usuário veja o formulário de cadastro e a listagem das contas na mesma página.
Para isso utilizaremos os recursos AJAX do JavaServer Faces, permitindo que a manutenção e a listagem dos registros fiquem na mesma página.
Construção da camada de acesso a dados
- Criação da classe Conta;
- Criação da interface ContaDAO e da classe ContaDAOHibernate Passo 1: Criação da classe Conta
Logo teremos que criar um pacote para guarda as classes.Crie o pacote
br.com.pitagoras.sistfinanceiro.conta. Em seguida cria a classe Conta nesse Pacote.
Código da Classe Conta.java
package br.com.pitagoras.sistfinanceiro.conta;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.OnDeleteAction;
import br.com.pitagoras.sistfinanceiro.usuario.Usuario;
@Entity
public class Conta implements Serializable {
@Id
@GeneratedValue
private Integer conta;
@ManyToOne
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(nullable = false)
private Usuario usuario;
private String descricao;
@Column(nullable = false, updatable = false)
private Date dataCadastro;
private float saldoInicial;
private boolean favorita;
public Integer getConta() {
return conta;
}
public void setConta(Integer conta) {
this.conta = conta;
}
public Usuario getUsuario() {
return usuario;
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public Date getDataCadastro() {
return dataCadastro;
}
public void setDataCadastro(Date dataCadastro) {
this.dataCadastro = dataCadastro;
}
public float getSaldoInicial() {
return saldoInicial;
}
public void setSaldoInicial(float saldoInicial) {
this.saldoInicial = saldoInicial;
}
public boolean isFavorita() {
return favorita;
public void setFavorita(boolean favorita) {
this.favorita = favorita;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((conta == null) ? 0 : conta.hashCode());
result = prime * result + ((dataCadastro == null) ? 0 : dataCadastro.hashCode());
result = prime * result + ((descricao == null) ? 0 : descricao.hashCode());
result = prime * result + (favorita ? 1231 : 1237);
result = prime * result + Float.floatToIntBits(saldoInicial);
result = prime * result + ((usuario == null) ? 0 : usuario.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Conta other = (Conta) obj;
if (conta == null) {
if (other.conta != null)
return false;
} else if (!conta.equals(other.conta))
return false;
if (other.dataCadastro != null)
return false;
} else if (!dataCadastro.equals(other.dataCadastro))
return false;
if (descricao == null) {
if (other.descricao != null)
return false;
} else if (!descricao.equals(other.descricao))
return false;
if (favorita != other.favorita)
return false;
if (Float.floatToIntBits(saldoInicial) != Float.floatToIntBits(other.saldoInicial))
return false;
if (usuario == null) {
if (other.usuario != null)
return false;
} else if (!usuario.equals(other.usuario))
return false;
return true;
}
}
OBS: Não esqueça de organizar o código depois de copiar.
Passo 2: Mapear a nova classe no arquivo Hibernate.
Acesse o arquivo hibernate.cfg.xml e adicione a linha de código em seu arquivo.
Código hibernate.cfg.xml
Passo 3: Criação da interface ContaDAO
No pacote br.com.pitagoras.sistfinanceiro.conta, crie a interface ContaDAO.java, selecione o pacote com o botão direito do mouse, clique em novo e em seguida em outros.
Em Categorias selecione Java e Tipos de Arquivos, selecione Interface Java.
Clique em Finalizar para concluir.
Código ContaDAO.java
package br.com.pitagoras.sistfinanceiro.conta;
import java.util.List;
import br.com.pitagoras.sistfinanceiro.usuario.Usuario;
public interface ContaDAO {
public void salvar(Conta conta);
public void excluir(Conta conta);
public Conta carregar(Integer conta);
public Conta buscarFavorita(Usuario usuario);
}
Passo 4: Criação da classe ContaDAOHibernate
No pacote br.com.pitagoras.sistfinanceiro.conta, crie a classe
ContaDAOHibernate.java, selecione o pacote com o botão direito do mouse, clique em novo e em seguida em outros.
Código ContaDAOHibernate.java
package br.com.pitagoras.sistfinanceiro.conta;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import br.com.pitagoras.sistfinanceiro.usuario.Usuario;
public class ContaDAOHibernate implements ContaDAO {
private Session session;
public void setSession(Session session) {
this.session = session;
}
public void excluir(Conta conta) {
this.session.delete(conta);
}
public void salvar(Conta conta) {
this.session.saveOrUpdate(conta);
public Conta carregar(Integer conta) {
return (Conta) this.session.get(Conta.class, conta);
}
public List<Conta> listar(Usuario usuario) {
Criteria criteria = this.session.createCriteria(Conta.class);
criteria.add(Restrictions.eq("usuario", usuario));
return criteria.list();
}
public Conta buscarFavorita(Usuario usuario) {
Criteria criteria = this.session.createCriteria(Conta.class);
criteria.add(Restrictions.eq("usuario", usuario));
criteria.add(Restrictions.eq("favorita", true));
return (Conta) criteria.uniqueResult();
}
}
Parte 5: Alteração da Classe DAOFactory.java
Abaixo segue o código completo da classe DAOFactory.java e as linhas em amarelo são as linhas que devemos alterar.
Código DAOFactory.java
package br.com.pitagoras.sistfinanceiro.util;
import br.com.pitagoras.sistfinanceiro.usuario.*;
import br.com.pitagoras.sistfinanceiro.conta.*;
public class DAOFactory {
UsuarioDAOHibernate usuarioDAO = new UsuarioDAOHibernate();
usuarioDAO.setSession(HibernateUtil.getSessionFactory().getCurrentSession());
return usuarioDAO;
}
public static ContaDAO criarContaDAO() {
ContaDAOHibernate contaDAO = new ContaDAOHibernate();
contaDAO.setSession(HibernateUtil.getSessionFactory().getCurrentSession());
return contaDAO;
}
}
Parte 6: Construção da Camada de Regra de negócio
Geralmente as classes de regra de Negócio (RN) geralmente só farão o repasse da chamada para as classes DAO, pois a maioria das operações é simplesmente para buscar, salvar ou excluir dados. Porém, em ContaRN teremos alguma regra de negócio nos métodos salvar e tornarFavorita, em que é atribuída a data atual para a data de cadastro e é alterado o indicador de favorita de uma determinada conta.
Crie a classe ContaRN a seguir no pacote br.com.pitagoras.sistfinanceiro.conta.
Código ContaRN.java
package br.com.pitagoras.sistfinanceiro.conta;
import java.util.Date;
import java.util.List;
import br.com.pitagoras.sistfinanceiro.usuario.Usuario;
import br.com.pitagoras.sistfinanceiro.util.DAOFactory;
private ContaDAO contaDAO;
public ContaRN() {
this.contaDAO = DAOFactory.criarContaDAO();
}
public List<Conta> listar(Usuario usuario) {
return this.contaDAO.listar(usuario);
}
public Conta carregar(Integer conta) {
return this.contaDAO.carregar(conta);
}
public void salvar(Conta conta) {
conta.setDataCadastro(new Date());
this.contaDAO.salvar(conta);
}
public void excluir(Conta conta) {
this.contaDAO.excluir(conta);
}
public void tornarFavorita(Conta contaFavorita) {
Conta conta = this.buscarFavorita(contaFavorita.getUsuario());
if (conta != null) {
conta.setFavorita(false);
this.contaDAO.salvar(conta);
}
contaFavorita.setFavorita(true);
this.contaDAO.salvar(contaFavorita);
public Conta buscarFavorita(Usuario usuario) {
return this.contaDAO.buscarFavorita(usuario);
}
}
Parte 7: Construção da Camada de Visualização
Chegou a hora de construir a tela de cadastro de contas. É nesse momento que começaremos a trabalhar com o JSF para a conta. Seguindo a mesma sequência apresentada para a criação da interface para o usuário.
Vamos iniciar criando uma classe bean que chamaremos de ContextoBean.java. Essa classe será uma classe de infraestrutura. No pacote
br.com.pitagoras.sistfinanceiro.web, crie a classe ContextoBean.java
Código ContextoBean.java
package br.com.pitagoras.sistfinanceiro.web;
import java.io.Serializable;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import br.com.pitagoras.sistfinanceiro.conta.Conta;
import br.com.pitagoras.sistfinanceiro.conta.ContaRN;
import br.com.pitagoras.sistfinanceiro.usuario.Usuario;
import br.com.pitagoras.sistfinanceiro.usuario.UsuarioRN;
@ManagedBean
@SessionScoped
private static final long serialVersionUID = -2071855184464371947L;
private int codigoContaAtiva = 0;
public Usuario getUsuarioLogado() {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext external = context.getExternalContext();
String login = external.getRemoteUser();
if (login != null) {
UsuarioRN usuarioRN = new UsuarioRN();
return usuarioRN.buscarPorLogin(login);
}
return null;
}
public Conta getContaAtiva() {
Conta contaAtiva = null;
if (this.codigoContaAtiva == 0) {
contaAtiva = this.getContaAtivaPadrao();
} else {
ContaRN contaRN = new ContaRN();
contaAtiva = contaRN.carregar(this.codigoContaAtiva);
}
if (contaAtiva != null) {
this.codigoContaAtiva = contaAtiva.getConta();
return contaAtiva;
}
return null;
}
private Conta getContaAtivaPadrao() {
ContaRN contaRN = new ContaRN();
Usuario usuario = this.getUsuarioLogado();
contaAtiva = contaRN.buscarFavorita(usuario);
if (contaAtiva == null) {
List<Conta> contas = contaRN.listar(usuario);
if (contas != null && contas.size() > 0) {
contaAtiva = contas.get(0);
}
}
return contaAtiva;
}
public void changeContaAtiva(ValueChangeEvent event) {
this.codigoContaAtiva = (Integer) event.getNewValue();
}
}
Parte 8: Vamos agora estruturar a classe ContaBean, ela fornecerá todos os dados que
a tela de contas irá precisar. No pacote br.com.pitagoras.sistfinanceiro.web, crie a classe ContaBean.java
Código ContaBean.java
package br.com.pitagoras.sistfinanceiro.web;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import br.com.pitagoras.sistfinanceiro.conta.Conta;
import br.com.pitagoras.sistfinanceiro.conta.ContaRN;
@RequestScoped
public class ContaBean {
private Conta selecionada = new Conta();
private List<Conta> lista = null;
@ManagedProperty(value = "#{contextoBean}")
private ContextoBean contextoBean;
public String salvar() {
this.selecionada.setUsuario(this.contextoBean.getUsuarioLogado());
ContaRN contaRN = new ContaRN();
contaRN.salvar(this.selecionada);
this.selecionada = new Conta();
this.lista = null;
return null;
}
public String excluir() {
ContaRN contaRN = new ContaRN();
contaRN.excluir(this.selecionada);
this.selecionada = new Conta();
this.lista = null;
return null;
}
public String tornarFavorita() {
ContaRN contaRN = new ContaRN();
contaRN.tornarFavorita(this.selecionada);
this.selecionada = new Conta();
return null;
}
public Conta getSelecionada() {
}
public void setSelecionada(Conta selecionada) {
this.selecionada = selecionada;
}
public List<Conta> getLista() {
if (this.lista == null) {
ContaRN contaRN = new ContaRN();
this.lista = contaRN.listar(this.contextoBean.getUsuarioLogado());
}
return this.lista;
}
public void setLista(List<Conta> lista) {
this.lista = lista;
}
public ContextoBean getContextoBean() {
return contextoBean;
}
public void setContextoBean(ContextoBean contextoBean) {
this.contextoBean = contextoBean;
}
}
Parte 9: Criação do Arquivo conta.xhtml
Código – conta.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Cadastro de contas</title>
</h:head>
<h:body>
<h1>Cadastro de contas</h1>
<h:form id="edicao">
<h:messages />
<h:inputHidden value="#{contaBean.selecionada.conta}" />
<h:inputHidden value="#{contaBean.selecionada.favorita}" />
<h:panelGrid columns="2">
<h:outputLabel value="Descrição: " for="descricao" />
<h:inputText id="descricao"
value="#{contaBean.selecionada.descricao}" required="true"
maxlength="45" />
<h:outputLabel value="Saldo Inicial: " for="saldoInicial" />
<h:inputText id="saldoInicial"
value="#{contaBean.selecionada.saldoInicial}" size="10">
<f:convertNumber minFractionDigits="2" />
</h:inputText>
<h:commandButton value="Salvar" action="#{contaBean.salvar}">
<f:ajax execute="@form" render=":edicao :listagem" />
</h:panelGrid>
</h:form>
<h:form id="listagem">
<h:dataTable value="#{contaBean.lista}" var="conta"
rendered="#{not empty contaBean.lista}">
<h:column>
<f:facet name="header">Descrição</f:facet>
#{conta.descricao}
</h:column>
<h:column>
<f:facet name="header">Data Cadastro</f:facet>
<h:outputText value="#{conta.dataCadastro}">
<f:convertDateTime dateStyle="medium" />
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">Saldo Inicial</f:facet>
<h:outputText value="#{conta.saldoInicial}"
style="text-align: right; display:block;">
<f:convertNumber minFractionDigits="2" />
</h:outputText>
</h:column>
<h:column>
<h:commandLink action="#{contaBean.tornarFavorita}">
<f:ajax execute="@this" render=":listagem" />
<h:graphicImage library="imagens"
name="favorita16_#{conta.favorita}.png" />
<f:setPropertyActionListener target="#{contaBean.selecionada}"
value="#{conta}" />
</h:commandLink>
<h:column>
<h:commandLink>
<f:ajax execute="@this" render=":edicao" />
<h:graphicImage library="imagens" name="editar16.png" />
<f:setPropertyActionListener target="#{contaBean.selecionada}"
value="#{conta}" />
</h:commandLink>
</h:column>
<h:column>
<h:commandLink action="#{contaBean.excluir}">
<f:ajax execute="@this" render=":listagem" />
<h:graphicImage library="imagens" name="excluir16.png" />
<f:setPropertyActionListener target="#{contaBean.selecionada}"
value="#{conta}" />
</h:commandLink>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
Parte 10: Alteração do Menu do Sistema. Vamos inserir o código abaixo na página
principal.xhtml.
Código principal.xhtml
Abaixo estamos demonstrando somente um pedaço do código com as parte que deverá ser adicionada, pois o código completo é muito grande. Adicione somente as partes em amarelo.
<h:body>
Usuário logado #{request.remoteUser}
<br />
<h:form>
<h:commandButton value="Conta" action="/restrito/conta" />
<h:selectOneMenu value="#{contextoBean.contaAtiva.conta}"
valueChangeListener="#{contextoBean.changeContaAtiva}"
rendered="#{not empty contextoBean and not empty contextoBean.contaAtiva}"
onchange="submit()">
<f:selectItems value="#{contaBean.lista}" var="conta"
itemValue="#{conta.conta}" itemLabel="#{conta.descricao}" />
</h:selectOneMenu>
Passo 11: Vamos evoluir o cadastro de usuários, para que quando o usuário
cadastrar-se no sistema ele já possa informar pelo menos uma conta bancaria. Isso porque o sistema trabalhará com uma conta ativa.
Para isso vamos fazer a seguinte alteração no Código da Classe UsuarioBean.java
Código UsuarioBean.java
package br.com.pitagoras.sistfinanceiro.web;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import br.com.pitagoras.sistfinanceiro.conta.ContaRN;
import br.com.pitagoras.sistfinanceiro.usuario.Usuario;
import br.com.pitagoras.sistfinanceiro.usuario.UsuarioRN;
@ManagedBean(name = "usuarioBean")
@RequestScoped
public class UsuarioBean {
private Usuario usuario = new Usuario();
private String confirmarSenha;
private List<Usuario> lista;
private String destinoSalvar;
private Conta conta = new Conta();
public String novo() {
this.destinoSalvar = "usuariosucesso";
this.usuario = new Usuario();
this.usuario.setAtivo(true);
return "/publico/usuario";
}
public String editar() {
this.confirmarSenha = this.usuario.getSenha();
return "/publico/usuario";
}
public String salvar() {
FacesContext context = FacesContext.getCurrentInstance();
String senha = this.usuario.getSenha();
if (!senha.equals(this.confirmarSenha)) {
FacesMessage facesMessage = new FacesMessage("A senha não foi confirmada corretamente");
return null;
}
UsuarioRN usuarioRN = new UsuarioRN();
usuarioRN.salvar(this.usuario);
if (this.conta.getDescricao() != null) {
this.conta.setUsuario(this.usuario);
this.conta.setFavorita(true);
ContaRN contaRN = new ContaRN();
contaRN.salvar(this.conta);
}
return this.destinoSalvar;
}
public String excluir() {
UsuarioRN usuarioRN = new UsuarioRN();
usuarioRN.excluir(this.usuario);
this.lista = null;
return null;
}
public String ativar() {
if (this.usuario.isAtivo())
this.usuario.setAtivo(false);
else
this.usuario.setAtivo(true);
UsuarioRN usuarioRN = new UsuarioRN();
usuarioRN.salvar(this.usuario);
return null;
public List<Usuario> getLista() {
if (this.lista == null) {
UsuarioRN usuarioRN = new UsuarioRN();
this.lista = usuarioRN.listar();
}
return this.lista;
}
public String atribuiPermissao(Usuario usuario, String permissao) {
this.usuario = usuario;
java.util.Set<String> permissoes = this.usuario.getPermissao();
if (permissoes.contains(permissao)) {
permissoes.remove(permissao);
} else {
permissoes.add(permissao);
}
return null;
}
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public String getConfirmarSenha() {
return confirmarSenha;
}
this.confirmarSenha = confirmarSenha;
}
public String getDestinoSalvar() {
return destinoSalvar;
}
public void setDestinoSalvar(String destinoSalvar) {
this.destinoSalvar = destinoSalvar;
}
public Conta getConta() {
return conta;
}
public void setConta(Conta conta) {
this.conta = conta;
}
}
Passo 12: Agora para finalizar iremos alterar o formulário do cadastro de usuários. Vamos inserir um panelGroup logo abaixo de panelGrid.
Código usuário.xhtml – panelGroup.
<h:panelGroup rendered="#{empty usuarioBean.usuario.codigo}">
<fieldset>
<legend>Conta Inicial</legend>
<h:panelGrid columns="2">
<h:outputLabel value="Descrição: " for="descricao" />
value="#{usuarioBean.conta.descricao}" required="true"
maxlength="45" />
<h:outputLabel value="Saldo Inicial: " for="saldoInicial" />
<h:inputText id="saldoInicial"
value="#{usuarioBean.conta.saldoInicial}" size="10">
<f:convertNumber minFractionDigits="2" />
</h:inputText>
</h:panelGrid>
</fieldset>
</h:panelGroup>
OBS: Não se esqueça de organizar o código após adiciona-lo no arquivo.