Académique Documents
Professionnel Documents
Culture Documents
htm
Bom, neste tópico iremos direto ao assunto. Meu obje vo é demonstrar a criação de um CRUD em
poucos passos, u lizando Java com recursos de JPA, JSF na arquitetura MVC.
http://www.linu.com.br/papers/paper020.htm 1/35
14/02/2019 www.linu.com.br/papers/paper020.htm
Faremos o sistema para Manter Telefones. A única classe do modelo será essa. Outras classes
serão necessárias para compor a arquitetura. Ao final do desenvolvimento, teremos as classes de
modelo (essa), as classes Data Access Object (para persistência), as classes Business Object (para
as regras de negócio) e as classes View (Beans para controle da interface com usuário e sessão).
Entre elas, serão necessárias algumas interfaces Java para padrões de projeto adequados ao
exemplo. Para a criação deste diagrama, u lizei o Jude (h p://jude.change-vision.com/jude-
web/index.html), que além de facilitar a criação gráfica do modelo, gera código Java.
Obs. Desconsidere a modelagem apresentada, pois o ideal seria termos um objeto Cliente
relacionado com Telefone, mas como este é um simples exemplo acadêmico, temos só Telefone.
http://www.linu.com.br/papers/paper020.htm 2/35
14/02/2019 www.linu.com.br/papers/paper020.htm
id integer not null,
ddd char(2) not null,
numero char(8) not null,
nome varchar(40) not null,
constraint pk_telefones primary key (id)
);
Observe que, por opção, não criaremos um auto-incremento no banco. Isto será gerenciado pelo
próprio Toplink. Portanto, será necessária a criação da tabela e inserção abaixo.
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT DECIMAL(38), PRIMARY
KEY (SEQ_NAME));
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 1);
Essa tabela é u lizada para controlar o auto-incremento, independente do banco. Criada essas
duas tabelas, poderemos par r para o desenvolvimento. Alguns detalhes importantes são: o
usuário e senha do meu banco são, respec vamente, pgadmin e pgadmin – vamos precisar dessa
informação para a criação do arquivo persistence.xml.
U lizei a ferramenta phpPgAdmin para a criação do banco e geração das tabelas
(h p://phppgadmin.sourceforge.net/).
Neste ponto, teremos nosso projeto Web criado. Vamos acrescentar a opção de persistência de
dados JPA com a sequência abaixo.
1. Na aba Projetos (à esquerda da interface do Netbeans), clique com o botão direito no nome
do projeto (mycrud), selecione a opção Novo, e o submenu Outro...
2. Na aba Categorias, selecione Persistence
3. Na aba Tipos de arquivos selecione a opção Unidade de persistência
4. Clique em Próximo >
5. Defina o valor de Nome da unidade de persistência como default
6. Em Conexão de banco de dados, selecione a opção Nova conexão com banco de dados...
7. Em Nome, selecione a opção PostgreSQL
8. Em URL do banco de dados, defina o valor jdbc:postgresql://localhost:5432/mycrud
9. Em Nome do usuário e Senha, defina respec vamente, pgadmin e pgadmin. Lembre-se que
meu banco está configurado com esse usuário. Faça suas adaptações, se necessário.
10. Marque a opção Lembrar senha
11. Clique em OK
http://www.linu.com.br/papers/paper020.htm 3/35
14/02/2019 www.linu.com.br/papers/paper020.htm
Neste momento, o arquivo persistence.xml será criado. Por enquanto, podemos fechá-lo. Feche
também o arquivo welcomeJSF.jsp. Posteriormente vamos excluí-lo.
Vamos agora adicionar a biblioteca de conexão com o PostgreSQL.
Observe que criamos cada uma das camadas do padrão MVCP – model, view, controller e
persistence. Neste ponto, estamos prontos para começar a codificação Java (enfim...).
8. Clique em Finalizar
// InterfacePojo.java
package model;
Lembre-se sempre de salvar as alterações (menu Arquivo, opção Salvar todos). Vamos agora criar
o Pojo (model) do objeto Telefone.
// Telefone.java
package model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity(name = "Telefone")
@Table(name = "telefones")
@NamedQueries( {
@NamedQuery(
name="selectTelefone",
query = "select obj from Telefone obj"
)
}
)
public class Telefone implements Serializable, InterfacePojo {
@Id
@GeneratedValue
@Column(name = "id")
private int id;
// Métodos da InterfacePojo
@Override
public int getCode() { return this.getId(); }
@Override
public void setCode(int code) { this.setId( code ); }
@Override
public String getDescribe() { return this.getNome(); }
@Override
public void setDescribe(String describe) {
this.setNome( describe );
}
// Métodos da InterfacePojo
// Métodos de formatação
public String getNumeroFormatado() {
return "(" + this.getDdd() + ") " + this.getNumero();
}
// Métodos de formatação
Através destes códigos, o Objeto poderá ser manipulado no banco pelo Toplink. O caso do
@Override é indiferente para o serviço de persistência. Observe também que, por se tratar de um
Pojo, simples ge ers e se ers são suficientes (e por padrão, necessários) para o código. O modelo
é definido com classes neste design.
http://www.linu.com.br/papers/paper020.htm 6/35
14/02/2019 www.linu.com.br/papers/paper020.htm
O fato de o objeto ser Serializable e possuir o atributo serialVersionUID permite sua migração
entre Container's, com a aplicação de JNDI. Não trabalharemos com esse recurso neste material.
Veja mais em h p://www.jspbrasil.com.br/mostrar/27
Salve as alterações.
Vamos agora alterar o arquivo de persistência para que o objeto Telefone possa ser manipulado.
O código deste arquivo mostra ao Toplink como trabalhar com o banco de dados. Mostra também,
quais classes poderão ser manipuladas. Neste caso, só a classe Telefone.
Salve as alterações e vamos prosseguir para a camada de persistência.
O que é um Singleton?
Trata-se de uma classe com métodos está cos criados para manter um único objeto DAO para
todas as classes que precisarem dele. Observando o código da classe, será mais fácil entender a
filosofia. Vamos criar o arquivo DAO.
// Dao.java
http://www.linu.com.br/papers/paper020.htm 7/35
14/02/2019 www.linu.com.br/papers/paper020.htm
package persistence;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceException;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;
@PersistenceUnit
public class Dao {
public Dao() {}
@SuppressWarnings("unchecked")
public Object searchObjectByCode(Class objectClass, Object objectId)
throws PersistenceException {
try {
Object object = em.find( objectClass , objectId );
em.clear();
return object;
} catch (Exception e) {
throw new PersistenceException( "Não foi possível obter o objeto!" );
}
}
// MyCrudException.java
package util;
http://www.linu.com.br/papers/paper020.htm 9/35
14/02/2019 www.linu.com.br/papers/paper020.htm
// Number.java
package util;
Este objeto faz a verificação necessária para nosso sistema. Essas duas classes compõem no pacote
u l. Agora vamos para a implementação mais importante do projeto: as regras do negócio.
http://www.linu.com.br/papers/paper020.htm 10/35
14/02/2019 www.linu.com.br/papers/paper020.htm
// InterfaceBo.java
package controller;
import java.util.List;
import model.InterfacePojo;
import util.MyCrudException;
1. Após expandir o item Pacotes de códigos-fonte da aba Projetos, clique com o botão direito
sobre o pacote controller
2. Selecione a opção Novo e o submenu Classe java...
3. Em Nome da classe digite Bo
4. Clique em Finalizar
// Bo.java
package controller;
import java.util.List;
import javax.persistence.PersistenceException;
import model.InterfacePojo;
import persistence.Dao;
import util.MyCrudException;
http://www.linu.com.br/papers/paper020.htm 11/35
14/02/2019 www.linu.com.br/papers/paper020.htm
private String namedQuery;
@Override
public void create(InterfacePojo pojo) throws MyCrudException {
try {
validate( pojo );
Dao.getDataAccessObject().create( pojo );
} catch (PersistenceException e) {
throw new MyCrudException( e.getMessage() );
}
}
@Override
public List<?> read() throws MyCrudException {
try {
return Dao.getDataAccessObject().read( this.namedQuery );
} catch (PersistenceException e) {
throw new MyCrudException( e.getMessage() );
}
}
@Override
public List<?> executeQuery(String ejbQL, String parameter[])
throws MyCrudException {
try {
return Dao.getDataAccessObject().executeQuery(ejbQL, parameter);
} catch (Exception e) {
throw new MyCrudException( e.getMessage() );
}
}
@Override
public void update(InterfacePojo pojo) throws MyCrudException {
try {
validate( pojo );
Dao.getDataAccessObject().update( pojo );
} catch (PersistenceException e) {
throw new MyCrudException( e.getMessage() );
}
}
@Override
public void destroy(InterfacePojo pojo) throws MyCrudException {
try {
Dao.getDataAccessObject().destroy( pojo );
} catch (PersistenceException e) {
throw new MyCrudException( e.getMessage() );
}
}
@Override
public Object searchObjectByCode(Class objectClass, Object id)
throws MyCrudException {
try {
return Dao.getDataAccessObject().searchObjectByCode( objectClass , id );
} catch (PersistenceException e) {
throw new MyCrudException( e.getMessage() );
}
}
@Override
public void validate(InterfacePojo pojo) throws MyCrudException {}
http://www.linu.com.br/papers/paper020.htm 12/35
14/02/2019 www.linu.com.br/papers/paper020.htm
Este código implementa a captura das Excep ons geradas pelo DAO, além de implementar um
método de validação (ainda sem qualquer procedimento). O próximo objeto a ser implementado
será o objeto mais importante do código, pois será através dele que as regras de negócio serão
implementadas. Se você observou o código até o momento, pode reparar que foram u lizadas
poucas condições (if). Dentro do possível controlamos as regras de desenvolvimento com opções
de orientação a objetos. A grande massa de condições estruturadas ocorrerá no código de regras
de negócio. A princípio, vamos implementar apenas os códigos básicos de validação – campos em
branco ou com valor não compa vel com o banco. Vamos colocar outras regras de negócio no
final deste estudo, para mostrar simulações mais prá cas.
1. Após expandir o item Pacotes de códigos-fonte da aba Projetos, clique com o botão direito
sobre o pacote controller
2. Selecione a opção Novo e o submenu Classe java...
3. Em Nome da classe digite TelefoneBo
4. Clique em Finalizar
Subs tua a implementação default do Netbeans do arquivo criado pelo código abaixo:
// TelefoneBo.java
package controller;
import model.InterfacePojo;
import model.Telefone;
import util.Number;
import util.MyCrudException;
public TelefoneBo() {
super( "selectTelefone" );
}
@Override
public void validate(InterfacePojo pojo) throws MyCrudException {
Telefone telefone = (Telefone) pojo;
// Validação do DDD
Number ddd = new Number( 2 , telefone.getDdd() );
if ( !ddd.validate() )
throw new MyCrudException( "Valor do DDD inválido!" );
// Validação do DDD
// Validação do Número
Number numero = new Number( 8 , telefone.getNumero() );
if ( !numero.validate() )
throw new MyCrudException( "Valor do Número inválido!" );
// Validação do Número
// Validação do Nome
if ( telefone.getNome() == null )
throw new MyCrudException( "Valor do Nome inválido!" );
if (
( telefone.getNome().length() < 1 ) ||
( telefone.getNome().length() > 40 )
) throw new MyCrudException( "Valor do Nome inválido!" );
// Validação do Nome
http://www.linu.com.br/papers/paper020.htm 13/35
14/02/2019 www.linu.com.br/papers/paper020.htm
Vamos observar alguns fatores: como você observou, a maior parte da programação ocorre no
objeto Bo. Essas funções serão herdadas pelo TelefoneBo, sendo que, como sobrescrevemos o
método validate (e incluímos o @Override), quando um TelefoneBo es ver no Run Time, o método
sobrescrito será u lizado no lugar do escrito no Bo. Isso significa que, quando for u lizada o
método create (por exemplo), sua chamada à validate fará referência ao método de TelefoneBo.
No final deste projeto, mostraremos outras validações. Agora entraremos na úl ma camada.
1. Após expandir o item Pacotes de códigos-fonte da aba Projetos, clique com o botão direito
sobre o pacote view
2. Selecione a opção Novo e o submenu Classe java...
3. Em Nome da classe digite ViewManager
4. Clique em Finalizar
// ViewManager.java
package view;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import model.InterfacePojo;
http://www.linu.com.br/papers/paper020.htm 14/35
14/02/2019 www.linu.com.br/papers/paper020.htm
this.formView = false;
this.formCreate = false;
this.formRead = false;
this.formUpdate = false;
this.formDestroy = false;
}
Este código contém os procedimentos que indicam quais partes da página JSP será exibida para os
usuários. Por exemplo, a página de leitura dos dados (consulta) mostrará uma tabela (DataTable)
contendo os dados e esta só será exibida quando isFormRead retornar true (o que ocorre, neste
caso). Agora vamos construir o objeto de controle do objeto POJO. Ela também possui alguns
métodos que precisam ser sobrescritos (createNewPojo(), getObjectBySession() e setPojo()).
Vamos observá-los adiante.
1. Após expandir o item Pacotes de códigos-fonte da aba Projetos, clique com o botão direito
sobre o pacote view
2. Selecione a opção Novo e o submenu Classe java...
3. Em Nome da classe digite PojoManager
4. Clique em Finalizar
// PojoManager.java
package view;
http://www.linu.com.br/papers/paper020.htm 15/35
14/02/2019 www.linu.com.br/papers/paper020.htm
import controller.Bo;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.ServletRequest;
import model.InterfacePojo;
import util.MyCrudException;
private Bo bo;
private InterfacePojo pojo;
@Override
public void setPojo(InterfacePojo pojo) {
this.pojo = pojo;
}
public Bo getBo() {
return this.bo;
}
http://www.linu.com.br/papers/paper020.htm 16/35
14/02/2019 www.linu.com.br/papers/paper020.htm
super.showMessage(FacesMessage.SEVERITY_WARN,
null, e.getMessage());
}
}
@Override
public InterfacePojo getObjectBySession() {
InterfacePojo value = null;
try {
value = (InterfacePojo) ((ServletRequest)
FacesContext.getCurrentInstance().getExternalContext().getRequest()).getAttribute("pojo");
} catch (IllegalStateException e) {
this.showMessage(FacesMessage.SEVERITY_WARN,
null, "Não foi possível obter o objeto!" );
} finally {
return value;
}
}
http://www.linu.com.br/papers/paper020.htm 17/35
14/02/2019 www.linu.com.br/papers/paper020.htm
princípio, somente ele deveria ter essa necessidade). Como você pode observar, as duas úl mas
classes são abstratas (não podem ser instanciadas). Isso deve ser assim pelo fato delas serem
genéricas.
Vamos implementar agora, uma classe específica para Telefone que herdará todo o
comportamento de PojoManager (e por consequência, ViewManager).
1. Após expandir o item Pacotes de códigos-fonte da aba Projetos, clique com o botão direito
sobre o pacote view
2. Selecione a opção Novo e o submenu Classe java...
3. Em Nome da classe digite TelefoneManager
4. Clique em Finalizar
// TelefoneManager.java
package view;
import controller.TelefoneBo;
import model.Telefone;
public TelefoneManager() {
super( "Telefone" , new TelefoneBo() , new Telefone() );
}
@Override
public void createNewPojo() {
Telefone telefone = new Telefone();
super.setPojo( telefone );
}
Como você pode observar, esta é uma simples classe que apenas sobrescreve o constructor – para
definir as variáveis de instância para o ViewManager – e o createNewPojo() - u lizado para criar
um novo pojo Telefone. Esta classe será nosso Bean de Sessão, porém, não será acessada
diretamente. Criaremos uma classe chamada SessionBean que controlará todos os Beans da
aplicação. Neste caso, como só temos um Bean, o TelefoneManager, que por sua vez, possui
acesso direto ao Telefone, este será gerenciado pela SessionBean.
1. Após expandir o item Pacotes de códigos-fonte da aba Projetos, clique com o botão direito
sobre o pacote view
2. Selecione a opção Novo e o submenu Classe java...
3. Em Nome da classe digite SessionBean
4. Clique em Finalizar
// SessionBean.java
package view;
public SessionBean() {
http://www.linu.com.br/papers/paper020.htm 18/35
14/02/2019 www.linu.com.br/papers/paper020.htm
this.telefoneBean = new TelefoneManager();
}
Para torná-la acessível pelos JSP's, precisamos adicioná-la ao faces-config.xml. Para trabalhar com
esse arquivo, execute:
1. Após expandir o item Arquivos de configuração da aba Projetos, dê dois cliques sobre o
arquivo faces-config.xml
No início, será mostrada a IDE de organização dos JSP e navegação, porém, vamos trabalhar
diretamente com o código. Clique (na parte superior do editor) na aba XML. O conteúdo do
arquivo deverá ficar igual ao código mostrado abaixo:
Observe que foi acrescentado uma dire va <managed-bean> que indicará o arquivo java que será
acessível pelo JSP. Esse parâmetro indica o seguinte:
· Item <managed-bean-name> : nome acessível pelas tags do JSP. Ou seja, se quisermos obter
um atributo con do em SessionBean, o mesmo deverá (por padrão) ter o método
getAtributo(). Se quisermos definir um valor para esse atributo, precisaremos do setAtributo().
Por exemplo, no código JSP, vamos acessar o atributo ddd do pojo telefone com a sintaxe:
SessionBean.telefoneBean.pojo.ddd
Ou seja, podemos referenciar SessionBean pois o mesmo está no faces-config.xml. SessionBean
possui um atributo telefoneBean, que é acessível pelo getTelefoneBean(). Que por sua vez
possui um método getPojo() - herdado do PojoManager – que retorna o Pojo no run me – que
se trata de um Telefone (pois TelefoneManager instancia o pojo Telefone em seu constructor).
Por úl mo, Telefone possui o método getDdd() que retorna o valor do atributo e setDdd() que
define o valor do atributo. Esse acesso, por exemplo, poderia estar associado a um
componente input do po text, indicando que o valor escrito no componente, será guardado
(ou buscado) do Pojo Telefone. Veremos o código JSP adiante.
· Item <managed-bean-class> : indica – com o pacote – a classe associada ao Bean estabelecido.
· Item <managed-bean-scope> : indica o escopo deste Bean. Pode-se definir session, request ou
applica on, cada um com sua u lidade. Se u lizarmos request, o bean tem seu ciclo de vida
para uma única requisição, ou seja, ao “postarmos” uma página, o container instancia o Bean
e realiza o procedimento. Em seguida o Bean é descartado. O session, mantém o Bean no
container enquanto a sessão do usuário es ver a va. Quando a sessão for finalizada, o
container finaliza a vida dele (não do usuário - do bean, é claro). O escopo applica on dará ao
Bean, tempo de vida durante toda a aplicação. Este é um caso muito par cular, que precisa ser
u lizado com cuidado, pois todos u lizaram de um mesmo recurso no sistema (o que se faz
http://www.linu.com.br/papers/paper020.htm 19/35
14/02/2019 www.linu.com.br/papers/paper020.htm
necessário, em alguns casos). Como nosso telefoneBean guardará vários estados da JSP,
durante toda a sessão, vamos u lizar o escopo session.
Você deve estar se perguntando: porque não definir TelefoneManager diretamente no faces-
config.xml ao invés de criar SessionBean. Bom, com uma única classe a ser gerenciada na sessão,
realmente não precisamos de SessionBean. Porém, imagine que o sistema tenha dezenas de
Beans, sendo todos com escopo de sessão. Para cada JSP que o usuário trabalhar, um Bean será
instanciado no container. Ou seja, se o usuário acessar a tela de Telefones, o container instancia
TelefoneManager. Se o usuário acessar a tela de Clientes (se exis sse, por exemplo), o container
instancia o Bean ClienteManager, só que, neste momento, não é mais necessário que
TelefoneManager con nue na memória. Que iria liberá-lo? Nosso SessionBean. Quando o usuário
acessar uma nova página JSP, o SessionBean teria o cuidado de liberar da memória (com o código
“telefoneBean = null;”, por exemplo) os Beans que ele não precisa mais. Atenção, o EJB 3 fornece
Beans de sessão em seu framework, porém não veremos isso neste estudo (quem sabe
futuramente?). Por fim, vamos criar a tela JSP.
1. Após expandir o item Páginas web, da aba Projetos, clique com o botão direito do mouse no
diretório WEB-INF
2. Selecione a opção Novo, item Outro...
3. Na caixa Categorias, selecione Outro
4. Na caixa Tipos de arquivos, selecione Diretório
5. Clique em Próximo >
6. Em Nome da pasta, entre com tags
7. Clique em Finalizar
Todas as nossas tags serão guardadas aqui. Vamos criar a tag header.
1. Na aba Projetos, abra o item Páginas web, em seguida, abra o diretório WEB-INF
2. Clique com o botão direito no diretório tags, selecione a opção Novo, item Outro...
3. Na caixa Categorias, selecione Web
4. Na caixa Tipos de Arquivos, selecione Arquivo de marcação (Tag)
5. Clique em Próximo >
6. Em Nome do arquivo de marcação, defina o valor header
7. Clique em Finalizar
<table>
<tr>
<td width="20%" bgcolor="#898989"> </td>
<td align="center" bgcolor="#aeaeae">
<font class="title"> MyCRUD </font>
</td>
<td width="20%" bgcolor="#898989"> </td>
</tr>
</table>
http://www.linu.com.br/papers/paper020.htm 20/35
14/02/2019 www.linu.com.br/papers/paper020.htm
1. Na aba Projetos, abra o item Páginas web, em seguida, abra o diretório WEB-INF
2. Clique com o botão direito no diretório tags, selecione a opção Novo, item Outro...
3. Na caixa Categorias, selecione Web
4. Na caixa Tipos de Arquivos, selecione Arquivo de marcação (Tag)
5. Clique em Próximo >
6. Em Nome do arquivo de marcação, defina o valor footer
7. Clique em Finalizar
<table>
<tr>
<td bgcolor="#898989" height="3"></td>
</tr>
</table>
/* style.css */
img.link {
border: 0px;
}
table {
border-collapse: collapse;
border: 0px;
padding: 0px;
background: white;
width: 500px;
}
http://www.linu.com.br/papers/paper020.htm 21/35
14/02/2019 www.linu.com.br/papers/paper020.htm
table.empty {
border-collapse: collapse;
border: 0px;
padding: 0px;
width: 100%;
}
table.data {
border-collapse: collapse;
padding: 0px;
background-color: white;
width: 100%;
}
.form {
font: 12px Arial, sans-serif;
}
.footer {
text-align: right;
padding: 8px;
}
.header {
text-align: left;
font-weight: bold;
color: grey;
font: 14px Arial, sans-serif;
}
font.title {
font-weight: bold;
color: white;
font: 14px Arial, sans-serif;
}
.tableHeader {
color: black;
font: 12px Arial, sans-serif;
}
.tableData {
color: blue;
font: 12px Arial, sans-serif;
}
.severityInformation {
text-align: center;
font: 11px Arial, sans-serif;
font-weight: bold;
color: #2222aa;
}
.severityWarning {
text-align: center;
font: 11px Arial, sans-serif;
font-weight: bold;
color: #aaaa22;
}
.severityError {
text-align: center;
font: 11px Arial, sans-serif;
font-weight: bold;
http://www.linu.com.br/papers/paper020.htm 22/35
14/02/2019 www.linu.com.br/papers/paper020.htm
color: #aa2222;
}
Neste caso, vamos salvar as imagens diretamente no diretório onde está guardado o projeto. Caso
você não saiba onde está, clique com o botão direito no projeto mycrud (na aba Projetos),
selecione o menu Propriedades. No campo Pasta do projeto estará definido o caminho. Vamos
supor que seu projeto esteja no path abaixo:
/home/guilherme/desenvolvimento/java/netbeans/mycrud
/home/guilherme/desenvolvimento/java/netbeans/mycrud/web/img
Ou seja, exatamente no diretório que você criou. As imagens estão dispostas abaixo:
Vamos agora para a criação do nosso arquivo JSP. Primeiramente, vamos excluir o arquivo
welcomeJSF.jsp. Para isso, execute:
Subs tua o código gerado pelo conteúdo abaixo (que é grande, alias):
http://www.linu.com.br/papers/paper020.htm 23/35
14/02/2019 www.linu.com.br/papers/paper020.htm
<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="css/style.css">
<title>MyCRUD</title>
</head>
<body>
<my:header />
<table>
<tr>
<td>
<f:view>
<h:form id="editForm">
<h:dataTable styleClass="data"
footerClass="footer" headerClass="header"
value="#{SessionBean.telefoneBean.list}"
var="pojo" rendered="#{SessionBean.telefoneBean.formRead}">
<f:facet name="header">
<h:outputText value="#{SessionBean.telefoneBean.titleForm}" />
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="Nome" styleClass="tableHeader"/>
</f:facet>
<h:outputText value="#{pojo.nome}" styleClass="tableData"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Telefone" styleClass="tableHeader"/>
</f:facet>
<h:outputText value="#{pojo.numeroFormatado}" styleClass="tableData"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Opções" styleClass="tableHeader"/>
</f:facet>
<h:commandLink actionListener="#{SessionBean.telefoneBean.setFormView}">
<h:graphicImage styleClass="link" value="img/lupa.gif" />
</h:commandLink>
<h:commandLink actionListener="#{SessionBean.telefoneBean.setFormUpdate}">
<h:graphicImage styleClass="link" value="img/floppy.gif" />
</h:commandLink>
<h:commandLink actionListener="#{SessionBean.telefoneBean.setFormDestroy}">
<h:graphicImage styleClass="link" value="img/delete.gif" />
</h:commandLink>
</h:column>
<f:facet name="footer">
<h:commandButton
actionListener="#{SessionBean.telefoneBean.setFormCreate}"
value="Inserir" />
</f:facet>
</h:dataTable>
<h:panelGrid columns="2"
rendered="#{!SessionBean.telefoneBean.formRead}"
styleClass="empty" footerClass="footer"
headerClass="header">
<f:facet name="header">
<h:outputText value="#{SessionBean.telefoneBean.titleForm}" />
http://www.linu.com.br/papers/paper020.htm 24/35
14/02/2019 www.linu.com.br/papers/paper020.htm
</f:facet>
<h:column>
<h:outputText value="DDD" styleClass="form" />
</h:column>
<h:column>
<h:inputText
disabled="#{SessionBean.telefoneBean.formDestroy or SessionBean.telefoneBean.formView}"
value="#{SessionBean.telefoneBean.pojo.ddd}"
maxlength="2" />
</h:column>
<h:column>
<h:outputText value="Número" styleClass="form" />
</h:column>
<h:column>
<h:inputText
disabled="#{SessionBean.telefoneBean.formDestroy or SessionBean.telefoneBean.formView}"
value="#{SessionBean.telefoneBean.pojo.numero}"
maxlength="8" />
</h:column>
<h:column>
<h:outputText value="Nome" styleClass="form" />
</h:column>
<h:column>
<h:inputText
disabled="#{SessionBean.telefoneBean.formDestroy or SessionBean.telefoneBean.formView}"
value="#{SessionBean.telefoneBean.pojo.nome}"
maxlength="40" />
</h:column>
<f:facet name="footer">
<h:panelGrid styleClass="empty">
<h:column>
<h:commandButton
actionListener="#{SessionBean.telefoneBean.setFormRead}"
value="Voltar" />
<h:commandButton
actionListener="#{SessionBean.telefoneBean.create}"
value="Inserir"
rendered="#{SessionBean.telefoneBean.formCreate}" />
<h:commandButton
actionListener="#{SessionBean.telefoneBean.update}"
value="Alterar"
rendered="#{SessionBean.telefoneBean.formUpdate}" />
<h:commandButton
actionListener="#{SessionBean.telefoneBean.destroy}"
value="Excluir"
rendered="#{SessionBean.telefoneBean.formDestroy}" />
</h:column>
</h:panelGrid>
</f:facet>
</h:panelGrid>
<my:footer />
</h:form>
</f:view>
</td>
</tr>
</table>
http://www.linu.com.br/papers/paper020.htm 25/35
14/02/2019 www.linu.com.br/papers/paper020.htm
</body>
</html>
1. Após expandir o item Arquivos de configuração da aba Projetos, dê dois cliques sobre o
arquivo web.xml
Entre na aba XML (parte superior do editor) e subs tua o conteúdo pelo código abaixo:
Vamos compreender o código da JSP. Acho que será mais didá co, entender o que ocorre quando
executamos este aplica vo. Neste ponto, o mesmo já está pronto para ser executado. Você poderá
executar através do menu Executar, submenu Executar projeto principal. Quando fizer isso, o
Netbeans levantará o container Tomcat, e abrirá um navegador. Algo similar ao mostrado abaixo
aparecerá em sua tela:
Vejamos os detalhes:
1. Quando o usuário acessa essa JSP, o container instancia SessionBean (com escopo de sessão).
2. Através das taglib no início do arquivo, definimos os namespace's – ou seja, quais tag
poderemos u lizar no JSP (que na verdade, é um JSF – Java ServerFaces).
3. Observe que através de <%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>, podemos
http://www.linu.com.br/papers/paper020.htm 26/35
14/02/2019 www.linu.com.br/papers/paper020.htm
http://www.linu.com.br/papers/paper020.htm 27/35
14/02/2019 www.linu.com.br/papers/paper020.htm
12. Abaixo, na definição do <h:panelGrid..., o JSP não fará usa reenderização, pois o valor
retornado em isFormRead() é true, e o código !SessionBean.telefoneBean.formRead,
definido em rendered, pega o inverso (pelo símbolo !) de true
13. Mais abaixo, em <my:footer />, nossa tag footer será exibida
14. O código <h:messages..., mostrará as mensagens enviadas pelo código showMessage() de
ViewManager (quando forem enviadas, o que neste momento, não ocorreu)
15. O restante do código fecha as tags JSP e HTML
Como não existem objetos no banco, nada foi retornado. Se clicarmos em Inserir, a tela abaixo
(similar, pois a tela mostrada já contém dados digitados e ações realizadas) será exibida:
http://www.linu.com.br/papers/paper020.htm 28/35
14/02/2019 www.linu.com.br/papers/paper020.htm
Esse fluxo é exatamente o mesmo que ocorre em Update (exceto pelo fato de que em vez de
create(), é coordenado por update()). No procedimento de exclusão, algo similar acontece, porém,
http://www.linu.com.br/papers/paper020.htm 29/35
14/02/2019 www.linu.com.br/papers/paper020.htm
o método validate() não é chamado. Outras telas representa vas do processo são mostradas
abaixo.
Ao voltarmos para a consulta, o registro será exibido com suas respec vas opções. Se clicarmos
em excluir (ícone lixeira), a tela abaixo será exibida:
http://www.linu.com.br/papers/paper020.htm 30/35
14/02/2019 www.linu.com.br/papers/paper020.htm
o usuário para a tela de consulta. Porém, como update() também exibe uma mensagem, a mesma
será exibida na tela de consulta (conforme a tela abaixo). Se houvesse algum problema no
processo, setFormRead() não seria executado e o usuário permaneceria na tela de atualização.
Nosso CRUD telefone está pronto. Conforme falado, vamos voltar ao código de TelefoneBo para
aplicar algumas regras de negócio mais complexas.
Atenção: SEMPRE que você alterar o código (seja de JSP e, principalmente, Java) feche o
navegador e execute (faça o deploy – publicação) a aplicação novamente.
Agora que já sabemos nossas regras de negócio (importan ssimas, aliás), vamos ao que interessa.
Edite o código de TelefoneBo para que o mesmo fique igual ao contexto mostrado abaixo.
// TelefoneBo.java
package controller;
import java.util.List;
import model.InterfacePojo;
import model.Telefone;
import util.Number;
import util.MyCrudException;
http://www.linu.com.br/papers/paper020.htm 31/35
14/02/2019 www.linu.com.br/papers/paper020.htm
public TelefoneBo() {
super( "selectTelefone" );
}
@Override
public void validate(InterfacePojo pojo) throws MyCrudException {
Telefone telefone = (Telefone) pojo;
// Validação do DDD
Number ddd = new Number( 2 , telefone.getDdd() );
if ( !ddd.validate() )
throw new MyCrudException( "Valor do DDD inválido!" );
// Validação do DDD
// Validação do Número
Number numero = new Number( 8 , telefone.getNumero() );
if ( !numero.validate() )
throw new MyCrudException( "Valor do Número inválido!" );
// Validação do Número
// Validação do Nome
if ( telefone.getNome() == null )
throw new MyCrudException( "Valor do Nome inválido!" );
if (
( telefone.getNome().length() < 1 ) ||
( telefone.getNome().length() > 40 )
) throw new MyCrudException( "Valor do Nome inválido!" );
// Validação do Nome
// Regras de Negócios
this.invalidDdd( telefone );
this.luckVersusDartvaider( telefone );
// Regras de Negócios
try {
if ( telefone.getNome().toUpperCase().equals( "LUCK" ) )
parameter[ 0 ] = "DARTVAIDER";
else
parameter[ 0 ] = "LUCK"
;
List<Telefone> collection = (List<Telefone>)
super.executeQuery( ejbQL , parameter );
if ( !collection.isEmpty() )
throw new MyCrudException( "May The Force Be With You!" );
} catch (Exception e) {
throw new MyCrudException( e.getMessage() );
}
}
http://www.linu.com.br/papers/paper020.htm 32/35
14/02/2019 www.linu.com.br/papers/paper020.htm
@Override
public void destroy(InterfacePojo pojo) throws MyCrudException {
try {
super.destroy( pojo );
} catch (Exception e) {
throw new MyCrudException( e.getMessage() );
}
}
Vamos ao seu entendimento. Para a primeira regra de negócio (DDD 22 inválido), uma simples
verificação no pojo Telefone cadastrado (ou atualizado), onde comparamos o valor de getDdd()
com 22, fará com que uma excep on seja disparada. Neste caso, observe como ficaria a tela:
A próxima regra, que impede que estejam registrados os telefones de Luck e Dartvaider ao
mesmo tempo, foi criada da seguinte maneira. Caso Luck já es vesse cadastrado (ou seja,
cadastre Luck agora), ao tentarmos cadastrar Dartvaider, o fluxo abaixo ocorre:
http://www.linu.com.br/papers/paper020.htm 33/35
14/02/2019 www.linu.com.br/papers/paper020.htm
Como você pode observar, essa regra de negócio precisou realizar uma consulta mais específica
no banco. Vamos, por fim, para a úl ma regra. Como o sistema necessita de no mínimo um
registro no banco, precisamos realizar essa regra no momento da exclusão de registros. Como
faremos? Como você pode observar no código, o método destroy() de Bo foi sobrescrito em
TelefoneBo e, através deste recurso acrescentamos a verificação da quan dade de registros
através de consulta ao banco. A lógica da regra é simples e por isso não vou descrevê-la aqui.
Observe o código que você compreenderá perfeitamente o que acontece. Como exemplo, tente
excluir todos os registros e observe o vai acontecer quando você for tentar excluir o úl mo
registro:
Para fazer um sisteminha podre desses eu preciso implementar isso tudo (Conclusão)?
http://www.linu.com.br/papers/paper020.htm 34/35
14/02/2019 www.linu.com.br/papers/paper020.htm
A programação OO de Java, por si só requer uma quan dade maior de código para os sistemas
simples como esse. Com o padrão MVC isso ocorre com mais impacto. Porém, neste exemplo, nós
implementamos um Model com uma única classe. Imagine um sistema com 100 classes de
modelo. Qual seria seu trabalho, a par r do que foi feito aqui, para implementar as outras 99
classes? Essa é a pergunta que você precisa responder! Por exemplo, para criar um CRUD Cliente,
criaríamos a classe Cliente.java no pacote model, a classe CienteBo.java no pacote controller e a
classe ClienteManager.java no pacote view. Como você pode observar, o código para implementar
essas classes é mínimo. Por fim, você cria um gerenciamento para ClienteManager em
SessionBean.java (criando um clienteBean, instanciando-o no constructor, e criando um método
getClienteBean()) e colocaria uma referência para o mesmo no arquivo persistence.xml. Por
úl mo, você criaria a página crudCliente.jsp (que aliás, é muito similar à crudTelefone.jsp). Você é
capaz de fazer isso em no máximo 30 minutos. Experimente! Você verá o ganho de produção
conquistado ao desenvolver projetos Web com Java, EJB 3 no padrão MVC.
http://www.linu.com.br/papers/paper020.htm 35/35