Vous êtes sur la page 1sur 35

14/02/2019 www.linu.com.br/papers/paper020.

htm

Desenvolvendo um CRUD para Web com Java, PostgreSQL e Netbeans

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.

Por que construir um CRUD?


Em termos de desenvolvimento, um CRUD estabelece os procedimentos básicos operacionais para
um componente de um sistema. Por componente, u lizando orientação a objetos, entendemos
como um objeto pertencente ao modelo (um Cliente, um Produto, por exemplo). Por
procedimentos básicos, entendemos como as operações de inclusão (create), seleção (read),
atualização (update) e exclusão (destroy) associadas a um desses objetos. Todo sistema possui seus
CRUDs. Ao mostrar um exemplo de criação de CRUD, temos base para a criação de várias etapas
de um sistema.
Mais detalhes podem ser vistos em: h p://pt.wikipedia.org/wiki/CRUD

Por que u lizar a linguagem Java?


Hoje, em grande maioria, quando se fala em sistemas, se fale em desenvolvimento web. Com a
Web 2.0 o desenvolvimento de sistemas para Web se intensificou ao ponto de chegarmos a
detalhes de produção e qualidade muito próximos aos sistemas cliente-servidor. Dentre as
linguagens atuais, o Java se destaca pelo conjunto de Frameworks que oferecem um
desenvolvimento sustentável, com muitas facilidades de manutenção. O .Net (com o C#) também
é excelente para grandes projetos. O PHP também não pode ser esquecido, porém sua
manutenção não é tão favorecida. Enfim, Java também é livre e aberto, dando um ponto forte
para minha escolha.
Você poderá baixar o Java em: h p://www.sun.com/

Por que u lizar JPA?


O JPA, na versão 3 do EJB, é indiscu velmente o Framework mais poderoso da atualidade (em
minha singela opinião). Através das diversas possibilidades oferecidas pelo JPA, u lizaremos um
pequeno, mas fantás co escopo de persistência. Em essência, trabalha-se com anotações JPA,
integradas aos Beans. Essas caracterís cas serão melhores discu das nos exemplos apresentados.
Mais detalhes em: h p://java.sun.com/developer/technicalAr cles/J2EE/jpa/

Por que trabalhar com JSF?


O Java ServerFaces é uma das mais atuais alterna vas para se construir a camada view da
aplicação web. Ela permite ao desenvolvedor u lizar tags específicas, sem nenhuma codificação
na va em Java (scriptles) no arquivo jsp. As páginas dinâmicas ficam ligadas diretamente aos
Beans. A produ vidade é favorecida e a manutenção facilitada, como veremos.
Veja mais detalhes em: h p://java.sun.com/javaee/javaserverfaces/

Por que u lizar a arquitetura MVC?


A arquitetura MVC (também estendida para MVCP, sendo o P de persistence) é amplamente
u lizada como padrão de desenvolvimento. O model (M) define o comportamento do sistema,
implementando os Beans, também conhecidos como Pojo (Plain Old Java Object). O view (V)
define a camada de visualização (onde u lizaremos o JSF). O controller (C) define as regras de
negócio da aplicação – pode-se u lizar os Beans de Sessão fornecidos pelo EjB3. Não
trabalharemos com esses tópicos neste estudo. Vamos u lizar uma camada isolada do modelo e
da apresentação.
Referência: h p://pt.wikipedia.org/wiki/MVC

http://www.linu.com.br/papers/paper020.htm 1/35
14/02/2019 www.linu.com.br/papers/paper020.htm

Por que u lizar o Netbeans?


Deve-se atentar para a seguinte questão: Netbeans, Eclipse, JBuilder, JCompany, entre outras, são
excelentes IDEs de desenvolvimento para aplicações Java, mas a grande jogada não são as IDEs, e
sim o Java. O que quero dizer é o seguinte: cada desenvolvedor trabalha com a IDE que mais se
adaptar, ou o que for estabelecido em sua empresa. Todos são bons, porém, é possível chegar aos
mesmos resultados em todos eles. Uns fornecem algumas facilidades, mas podemos produzir os
mesmos resultados com qualquer um deles. Escolhi o Netbeans neste estudo por sua facilidade em
relação ao Java. Não precisaremos instalar plugins. Além do fato dele ser livre. Portanto, não tome
esse tutorial como um modelo de produção onipresente. Podemos produzir o mesmo resultado na
unha – configurando os diretórios no container, bibliotecas e arquivos Java nos comandos do
prompt, se a necessidade de ficarmos associados a nenhuma IDE.
Pode-se baixar o Netbeans em: h p://www.netbeans.org/

Por que u lizar o PostgreSQL?


Todos os bancos livres são bons. Cada um com suas qualidades próprias. Fique à vontade para
trabalhar com outros bancos. O fato de se trabalhar com o JPA facilita ainda mais a transição de
um banco para o outro. Precisamos apenas alterar a JAR e o arquivo de configuração
persistence.xml. O SQL apresentado poderá também ser facilmente adaptado, pois man ve uma
certa flexibilidade no código.
Baixe o PostgreSQL em: h p://www.postgresql.org/

Modelo a ser exemplificado


Abaixo temos o modelo que será abordado:

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.

Criação do banco de dados


Os recursos de persistência implementados pelo Toplink, oferecem um recurso de geração
automá ca, porém, prefiro manter a implementação do banco manual. Desta forma, no futuro,
quando mudarmos a linguagem, o paradigma, nosso banco estará íntegro. Em alguns casos, o
modelo referencial gerado automa camente não fica, digamos, totalmente relacional.
Abaixo temos o SQL de geração da tabela. O nome do banco é mycrud e a codificação é UTF8.

create table telefones (

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/).

Criação do Projeto no Netbeans


Detalhes: Estamos trabalhando com a versão 6.1 do Netbeans, o container Tomcat 6.0.16 e o JEE 5.
Em primeiro lugar, recomendo que todos os outros projetos que estejam abertos no Netbeans
sejam fechados – só por questão de organização. Abaixo temos os passos necessários para a
criação do projeto.

1. Clique em Arquivo, Novo Projeto...


2. Na janela Novo Projeto, dentro da aba Categorias, selecione a opção Web. Na aba Projetos,
selecione a opção Aplicação Web
3. Clique em Próximo >
4. Em Nome do projeto, defina o valor mycrud
5. Clique em Próximo >
6. Em Servidor, selecione a opção Apache Tomcat 6.0.16
7. Clique em Próximo >
8. Na aba Frameworks, marque apenas a opção JavaServer Faces
9. Clique em Finalizar

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

12. Em Selecione um esquema, selecione public


13. Clique em OK
14. Em Estratégia de geração de tabela, marque a opção Nenhum
15. Clique em Finalizar

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.

1. Na aba Projetos, clique com o botão direito em Bibliotecas


2. Selecione a opção Adicionar biblioteca...
3. Selecione a opção PostgreSQL JDBC Driver
4. Clique em Adicionar biblioteca

Vamos agora criar os pacotes Java.

1. Na aba Projetos, clique com o botão direito em Pacotes de códigos-fonte


2. Clique na opção Novo, e no submenu Outro...
3. Na aba Categorias, selecione a opção Java
4. Na aba Tipos de arquivos, selecione a opção Pacote Java
5. Clique em Próximo >
6. Em Nome do pacote, defina o valor model
7. Clique em Finalizar
8. Repita a sequência de 1 ao 5
9. Em Nome do pacote, defina o valor persistence
10. Clique em Finalizar
11. Repita a sequência de 1 ao 5
12. Em Nome do pacote, defina o valor controller
13. Clique em Finalizar
14. Repita a sequência de 1 ao 5
15. Em Nome do pacote, defina o valor view
16. Clique em Finalizar
17. Repita a sequência de 1 ao 5
18. Em Nome do pacote, defina o valor u l
19. Clique em Finalizar

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

Criação do Modelo (camada Model)


O primeiro passo é criar uma Inteface que será implementada em todos os Pojos. Essa interface,
além de garan r a correta u lização dos objetos nas próximas camadas, seria usado na geração
de componentes ComboBox. Neste projeto não criaremos nenhum, mas através dessa Interface
isso seria possível e facilitado (quem sabe em outros futuros ar gos veremos tais detalhes...).

1. Na aba Projetos, clique com o botão direito em Pacotes de códigos-fonte


2. Clique na opção Novo, e no submenu Outro...
3. Na aba Categorias, selecione a opção Java
4. Na aba Tipos de arquivos, selecione a opção Interface Java
5. Clique em Próximo >
6. Em Nome da classe, digite InterfacePojo
7. Em Pacote, selecione a opção model
http://www.linu.com.br/papers/paper020.htm 4/35
14/02/2019 www.linu.com.br/papers/paper020.htm

8. Clique em Finalizar

Subs tua todo o conteúdo do arquivo pelo código abaixo:

// InterfacePojo.java
package model;

public interface InterfacePojo {


public int getCode();
public void setCode(int code);
public String getDescribe();
public void setDescribe(String describe);
}

Lembre-se sempre de salvar as alterações (menu Arquivo, opção Salvar todos). Vamos agora criar
o Pojo (model) do objeto Telefone.

1. Na aba Projetos, clique com o botão direito em Pacotes de códigos-fonte


2. Clique na opção Novo, e no submenu Outro...
3. Na aba Categorias, selecione a opção Java
4. Na aba Tipos de arquivos, selecione a opção Classe Java
5. Clique em Próximo >
6. Em Nome da classe, digite Telefone
7. Em Pacote, selecione a opção model
8. Clique em Finalizar

Subs tua o conteúdo do arquivo pelo código abaixo:

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

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name = "id")
private int id;

@Column(name = "ddd", nullable = false, length = 2)


private String ddd;
http://www.linu.com.br/papers/paper020.htm 5/35
14/02/2019 www.linu.com.br/papers/paper020.htm

@Column(name = "numero", nullable = false, length = 8)


private String numero;

@Column(name = "nome", nullable = false, length = 40)


private String nome;

public void setId(int id) { this.id = id; }


public int getId() { return id; }
public String getDdd() { return ddd; }
public String getNome() { return nome; }
public String getNumero() { return numero; }
public void setDdd(String ddd) { this.ddd = ddd; }
public void setNome(String nome) { this.nome = nome; }
public void setNumero(String numero) { this.numero = numero; }

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

Neste código, devemos nos atentar nas anotações EJB 3:

@En ty – usado para definir a en dade


@Table – usado para definir o nome da tabela no banco de dados
@NamedQueries e @NamedQuery – são usadas para definir a linguagem JPQL (Java Persistence
Query Language) de acesso aos dados do banco. Observe que é muito similar à SQL, porém, aqui
se trabalha com Orientação a Objetos.
@Id – Usado para definir que o atributo em questão, será a chave primária na tabela
@GeneratedValue – Usado para definir automa camente o valor do campo em questão
@Column – Usado para definir o nome do campo da tabela no qual este atributo está relacionado.
Observe que existem as dire vas length e nullable que servem, respec vamente, para definir o
tamanho máximo do campo e se o mesmo pode ser nulo.
@Override – esta anotação é usada para mostrar ao compilador que este método deverá ser
u lizado ao invés do método da Interface. Neste caso, é obvio que estes métodos serão usados
(pois somos obrigados a implementá-los por conta da InterfacePojo), mas mesmo assim, é boa
prá ca de programação colocar o @Override nos casos em que um método é sobrescrito
(polimorfismo).

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.

1. Na aba Projetos, no item Arquivos de configuração


2. Dê um duplo clique em persistence.xml
3. Insira o código <class>model.Telefone</class> entre as tags </provider> e <proper es>

O código do arquivo ficará igual ao mostrado abaixo:

<?xml version="1.0" encoding="UTF-8"?>


<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>model.Telefone</class>
<properties>
<property name="toplink.jdbc.user" value="pgadmin"/>
<property name="toplink.jdbc.password" value="pgadmin"/>
<property name="toplink.jdbc.url" value="jdbc:postgresql://localhost:5432/mycrud"/>
<property name="toplink.jdbc.driver" value="org.postgresql.Driver"/>
</properties>
</persistence-unit>
</persistence>

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.

Criação da Persistência (camada Persistence)


A camada de persistência consiste em um Data Access Object (DAO) geral que implementa os
procedimentos do CRUD (inserção, alteração, exclusão e seleção). Ele será responsável pela
captura das Excep ons de persistência que, quando encontradas, serão jogadas para a camada
acima através de uma PersistenceExcep on. Em geral, iremos passar um objeto para os métodos
dessa camada e ele executará (através dos recursos do EJB 3) todos os procedimentos sozinho.
Deve-se também atentar para a necessidade de criar um Singleton do DAO.

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.

1. Na aba Projetos, clique com o botão direito em Pacotes de códigos-fonte


2. Clique na opção Novo, e no submenu Outro...
3. Na aba Categorias, selecione a opção Java
4. Na aba Tipos de arquivos, selecione a opção Classe Java
5. Clique em Próximo >
6. Em Nome da classe, digite Dao
7. Em Pacote, selecione a opção persistence
8. Clique em Finalizar

Subs tua o conteúdo do arquivo pelo código abaixo.

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

private static EntityManagerFactory emf =


Persistence.createEntityManagerFactory("default");
private static EntityManager em = emf.createEntityManager();
private static Dao dao;

public Dao() {}

public static Dao getDataAccessObject() {


if ( dao == null ) dao = new Dao();
return dao;
}

public void create(Object object) throws PersistenceException {


try {
em.getTransaction().begin();
em.persist( object );
em.getTransaction().commit();
em.clear();
} catch (Exception e) {
throw new PersistenceException( "Não foi possível criar o objeto!" );
}
}

public List<?> read(String namedQuery) throws PersistenceException {


try {
Query query = em.createNamedQuery( namedQuery );
List<?> collection = query.getResultList();
em.clear();
return collection;
} catch (Exception e) {
throw new PersistenceException( "Não foi possível realizar a consulta!" );
}
}

public List<?> executeQuery(String ejbQL, String parameter[])


throws PersistenceException {
try {
Query query = em.createQuery( ejbQL );
if ( parameter != null ) {
for (int i = 0; i < parameter.length; i++)
query.setParameter( (i+1) , parameter[ i ] );
}
List<?> collection = query.getResultList();
em.clear();
return collection;
} catch (Exception e) {
throw new PersistenceException( "Não foi possível realizar a consulta!" );
}
}

public void update(Object object) throws PersistenceException {


try {
http://www.linu.com.br/papers/paper020.htm 8/35
14/02/2019 www.linu.com.br/papers/paper020.htm
em.getTransaction().begin();
em.merge( object );
em.getTransaction().commit();
em.clear();
} catch (Exception e) {
throw new PersistenceException( "Não foi possível alterar o objeto!" );
}
}

public void destroy(Object object) throws PersistenceException {


try {
em.getTransaction().begin();
em.remove( em.merge( object ) );
em.getTransaction().commit();
em.clear();
} catch (Exception e) {
throw new PersistenceException( "Não foi possível excluir o objeto!" );
}
}

@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!" );
}
}

A funcionalidade Singleton foi introduzida através do método getDataAccessObject(). O objeto Dao


será criado nas outras camadas através deste método, que retorna uma nova referência ou a
referência já u lizada por outra sessão. Observe que os Excep ons gerados pelo banco não serão
detalhadamente filtrados, devido à simplicidade mostrada neste exemplo. Em todos os casos,
somente uma mensagem será liberada. Observe também que foi criado um método chamado
executeQuery(), u lizado para executar namedQuery com parâmetros. Esse recurso será muito
ú l para validações e regras realizadas no Bo.

Criação das classes de apoio (pacote u l)


Algumas classes serão criadas para apoiar o funcionamento geral do sistema. A primeira delas
será a MyCrudExcep on u lizada como exceção para as regras de negócio.

1. Na aba Projetos, clique com o botão direito em Pacotes de códigos-fonte


2. Clique na opção Novo, e no submenu Outro...
3. Na aba Categorias, selecione a opção Java
4. Na aba Tipos de arquivos, selecione a opção Classe Java
5. Clique em Próximo >
6. Em Nome da classe, digite MyCrudExcep on
7. Em Pacote, selecione a opção u l
8. Clique em Finalizar

O código desta classe, muito simples, aliás, é mostrado abaixo.

// MyCrudException.java
package util;
http://www.linu.com.br/papers/paper020.htm 9/35
14/02/2019 www.linu.com.br/papers/paper020.htm

public class MyCrudException extends Exception {


public MyCrudException() { super(); }
public MyCrudException(String message) { super( message ); }
}

O próximo objeto é responsável pela criação de um componente de validação de números. Você


pôde observar que nosso Pojo telefone possui campos ddd e número do po String. Mas na
realidade estes valores são apenas numéricos. Neste objeto faremos tal verificação. Optei em não
criar um método está co que seria usado. Isso depende da preferência do desenvolvedor. Para a
criação deste novo arquivo, realize os procedimentos abaixo:

1. Na aba Projetos, clique com o botão direito em Pacotes de códigos-fonte


2. Clique na opção Novo, e no submenu Outro...
3. Na aba Categorias, selecione a opção Java
4. Na aba Tipos de arquivos, selecione a opção Classe Java
5. Clique em Próximo >
6. Em Nome da classe, digite Number
7. Em Pacote, selecione a opção u l
8. Clique em Finalizar

Abaixo temos o código desta classe:

// Number.java
package util;

public class Number {

private int length;


private String value;

public Number() { this( 1 ); }


public Number(int length) { this( length , "0" ); }
public Number(int length, String value) {
this.setLength(length);
this.setValue(value);
}

public void setLength( int length ) {


this.length = ( length > 0 ) ? length : 1;
}
public void setValue(String value) {
this.value = value;
}
public int getLength() { return this.length; }
public String getValue() { return this.value; }

public boolean validate() {


if ( this.value == null ) return false;
if ( this.value.length() != this.length ) return false;
for ( int i = 0; i < this.length; i++ ) {
if ( "0123456789".indexOf( this.value.charAt( i ) ) == -1 )
return false;
}
return true;
}
}

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

Criação das Regras de Negócio (camada Controller)


A filosofia será similar ao da camada de persistência. Haverá uma classe geral chamada Bo. Aqui,
porém, precisaremos de uma classe de BO específica para o Telefone – onde serão criadas as
regras de negócio. Haverá também uma Interface que definirá os procedimentos padrões de
camada de Business Object. Abaixo temos o procedimento para a criação das classes e interfaces.

1. Na aba Projetos, clique com o botão direito em Pacotes de códigos-fonte


2. Clique na opção Novo, e no submenu Outro...
3. Na aba Categorias, selecione a opção Java
4. Na aba Tipos de arquivos, selecione a opção Interface Java
5. Clique em Próximo >
6. Em Nome da classe, digite InterfaceBo
7. Em Pacote, selecione a opção controller
8. Clique em Finalizar

Subs tua o arquivo pelo código abaixo:

// InterfaceBo.java
package controller;

import java.util.List;
import model.InterfacePojo;
import util.MyCrudException;

public interface InterfaceBo {


public void create(InterfacePojo pojo) throws MyCrudException;
public List<?> read() throws MyCrudException;
public List<?> executeQuery(String ejbQL, String parameter[])
throws MyCrudException;
public void update(InterfacePojo pojo) throws MyCrudException;
public void destroy(InterfacePojo pojo) throws MyCrudException;
public Object searchObjectByCode(Class objectClass, Object id)
throws MyCrudException;
public void validate(InterfacePojo pojo) throws MyCrudException;
}

Agora será implementada a classe BO geral. Execute o procedimento abaixo:

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

Subs tua o conteúdo do arquivo Bo pelo código abaixo:

// Bo.java
package controller;

import java.util.List;
import javax.persistence.PersistenceException;
import model.InterfacePojo;
import persistence.Dao;
import util.MyCrudException;

public class Bo implements InterfaceBo {

http://www.linu.com.br/papers/paper020.htm 11/35
14/02/2019 www.linu.com.br/papers/paper020.htm
private String namedQuery;

public Bo(String namedQuery) {


this.namedQuery = 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 class TelefoneBo extends Bo {

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.

Criação da interface com Usuário (camada View)


A camada View terá alguns detalhes a serem descritos. Durante a apresentação das classes e dos
JSP's, falaremos mais sobre o desenvolvimento.
O primeiro passo será implementar o objeto ViewManager, responsável pelo gerenciamento da
tela. Ele simplesmente controlará o desenvolvimento dos processos realizados pelo usuário.

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

Subs tua o código pelo fragmento abaixo:

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

public abstract class ViewManager {

private boolean formView;


private boolean formCreate;
private boolean formRead;
private boolean formUpdate;
private boolean formDestroy;
private String titleForm;

public ViewManager(String titleForm) {


this.titleForm = ( titleForm == null ) ? "CRUD" : titleForm;
this.clearForm();
this.formRead = true;
}

public String getTitleForm() {


if ( this.formView ) return titleForm + " - Visualizar";
if ( this.formCreate ) return titleForm + " - Inserir";
if ( this.formRead ) return titleForm + " - Consultar";
if ( this.formUpdate ) return titleForm + " - Atualizar";
if ( this.formDestroy ) return titleForm + " - Excluir";
return titleForm;
}

public boolean isFormView() { return this.formView; }


public boolean isFormCreate() { return this.formCreate; }
public boolean isFormRead() { return this.formRead; }
public boolean isFormUpdate() { return this.formUpdate; }
public boolean isFormDestroy() { return this.formDestroy; }

private void clearForm() {

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

public void setFormView(ActionEvent event) {


this.clearForm();
this.formView = true;
setPojo( getObjectBySession() );
}

public void setFormCreate(ActionEvent event) {


this.clearForm();
this.formCreate = true;
createNewPojo();
}

public void setFormRead(ActionEvent event) {


this.clearForm();
this.formRead = true;
}

public void setFormUpdate(ActionEvent event) {


this.clearForm();
this.formUpdate = true;
setPojo( getObjectBySession() );
}

public void setFormDestroy(ActionEvent event) {


this.clearForm();
this.formDestroy = true;
setPojo( getObjectBySession() );
}

protected void showMessage(Severity severity, String resume, String detail) {


FacesContext.getCurrentInstance().addMessage
( null , new FacesMessage( severity , resume , detail ) );
}

public void createNewPojo() {}


public InterfacePojo getObjectBySession() { return null; }
public void setPojo(InterfacePojo pojo) {}

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

Subs tua o código pelo fragmento abaixo:

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

public abstract class PojoManager extends ViewManager {

private Bo bo;
private InterfacePojo pojo;

public PojoManager(String titleForm, Bo bo, InterfacePojo pojo) {


super(titleForm);
this.bo = bo;
this.pojo = pojo;
}

@Override
public void setPojo(InterfacePojo pojo) {
this.pojo = pojo;
}

public InterfacePojo getPojo() {


return this.pojo;
}

public void setBo(Bo bo) {


this.bo = bo;
}

public Bo getBo() {
return this.bo;
}

public void create(ActionEvent event) {


try {
this.bo.create(this.pojo);
super.setFormCreate(event);
super.showMessage(FacesMessage.SEVERITY_INFO,
null, "Objeto inserido com sucesso!");
} catch (MyCrudException e) {
super.showMessage(FacesMessage.SEVERITY_WARN,
null, e.getMessage());
}
}

public void destroy(ActionEvent event) {


try {
this.bo.destroy(this.pojo);
super.setFormRead(event);
super.showMessage(FacesMessage.SEVERITY_INFO,
null, "Objeto excluído com sucesso!");
} catch (MyCrudException e) {
super.showMessage(FacesMessage.SEVERITY_WARN,
null, e.getMessage());
}
}

public void update(ActionEvent event) {


try {
this.bo.update(this.pojo);
super.setFormRead(event);
super.showMessage(FacesMessage.SEVERITY_INFO,
null, "Objeto alterado com sucesso!");
} catch (MyCrudException e) {

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());
}
}

public List<?> getList() {


List list = null;
try {
list = this.bo.read();
} catch (MyCrudException e) {
super.showMessage(FacesMessage.SEVERITY_WARN,
null, e.getMessage());
} finally {
return list;
}
}

@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;
}
}

public Object searchObjectByCode() {


Object value = null;
try {
value = this.bo.searchObjectByCode(
this.pojo.getClass(),
new Integer(this.pojo.getCode()));
if (value == null) {
super.showMessage(FacesMessage.SEVERITY_WARN,
null, "Objeto não encontrado!");
}
} catch (MyCrudException e) {
super.showMessage(FacesMessage.SEVERITY_WARN,
null, e.getMessage());
} finally {
return value;
}
}
}

Esta é, provavelmente, a classe mais complexa do projeto. Porém, depois de implementada, o


ganho de produção para outros CRUDs é fantás co. Antes de tudo, vamos observar os principais
comportamentos: através dos ge ers e se ers de Pojo e Bo, poderemos gerenciar as respec vas
classes. Outro comportamento importante é realizado pelos métodos comuns do CRUD (create,
destroy, update e read), pois eles realizam o procedimento (através do Bo) e, caso ocorra,
capturam as exceções geradas nas camadas inferiores. Através do showMessage (implementado
no ViewManager.java) as mensagens serão enviadas para a tela (navegador). Outro método
importante é definido em getObjectBySession(), que retorna o objeto selecionado na JSP. Quando
isso ocorre? Na listagem de telefones, haverão campos de opções (links para visualizar, alterar e
excluir) no qual o usuário poderá clicar. Neste momento, o objeto da linha selecionada (onde o link
foi clicado), será enviado para o servidor. O código de getObjectBySession() obtém esse objeto
(que, inclusive, possui o nome de pojo). Por padrão, não vamos implementar em PojoManager
uma chamada ao método executeQuery() de Bo, pois caso haja necessidade de executar uma
Query que não esteja especificada no Model, somente o Bo teria essa permissão (ou melhor, a

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

Subs tua o contexto abaixo pelo código da classe criada:

// TelefoneManager.java
package view;

import controller.TelefoneBo;
import model.Telefone;

public class TelefoneManager extends PojoManager {

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

O código da classe é mostrado abaixo:

// SessionBean.java
package view;

public class SessionBean {

private TelefoneManager telefoneBean;

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();
}

public TelefoneManager getTelefoneBean() {


return this.telefoneBean;
}

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:

<?xml version='1.0' encoding='UTF-8'?>


<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-
facesconfig_1_2.xsd">
<managed-bean>
<managed-bean-name>SessionBean</managed-bean-name>
<managed-bean-class>view.SessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>

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.

Criação das telas JSP


Nesta etapa, finalmente criaremos a interface com usuário. Primeiramente, vamos criar dois
templates através do recurso de tags (isso poderia ser feito, com algumas vantagens, com
facelets). Vamos criar a pasta para guardar nossas tags. Por padrão, o diretório tags fica localizado
dentro de WEB-INF. Execute o procedimento abaixo para criá-lo:

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

Subs tua o conteúdo do arquivo pelo código abaixo:

<%@tag description="put the tag description here" pageEncoding="UTF-8"%>

<table>
<tr>
<td width="20%" bgcolor="#898989"> &nbsp; </td>
<td align="center" bgcolor="#aeaeae">
<font class="title"> MyCRUD </font>
</td>
<td width="20%" bgcolor="#898989"> &nbsp; </td>
</tr>
</table>

http://www.linu.com.br/papers/paper020.htm 20/35
14/02/2019 www.linu.com.br/papers/paper020.htm

Agora vamos criar a tag footer.

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

Subs tua o conteúdo do arquivo pelo código abaixo:

<%@tag description="put the tag description here" pageEncoding="UTF-8"%>

<table>
<tr>
<td bgcolor="#898989" height="3"></td>
</tr>
</table>

Agora, vamos criar nosso es lo CSS.

1. Na aba Projetos, clique com o botão direito no item Páginas web


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 css
7. Clique em Finalizar

Nossa folha de es lo ficará aqui. Vamos criá-la:

1. Na aba Projetos, abra o item Páginas web


2. Clique com o botão direito no diretório css, selecione a opção Novo, item Outro...
3. Na caixa Categorias, selecione Web
4. Na caixa Tipos de Arquivos, selecione Folha de es lo em cascata
5. Clique em Próximo >
6. Em Nome do arquivo CSS, defina o valor style
7. Clique em Finalizar

Subs tua o conteúdo do arquivo pelo código abaixo:

/* 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;
}

Por fim, vamos definir as imagens que u lizaremos no sistema.

1. Na aba Projetos, clique com o botão direito no item Páginas web


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 img
7. Clique em Finalizar

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

As imagens deverão ser salvas em:

/home/guilherme/desenvolvimento/java/netbeans/mycrud/web/img

Ou seja, exatamente no diretório que você criou. As imagens estão dispostas abaixo:

delete.gif floppy.gif lupa.gif

Após salva-las no diretório img, você poderá observá-las pelo Netbeans.

Vamos agora para a criação do nosso arquivo JSP. Primeiramente, vamos excluir o arquivo
welcomeJSF.jsp. Para isso, execute:

1. Abra o item Páginas web na aba Projetos


2. Clique com o botão direito em welcomeJSF.jsp e selecione Excluir
3. Na confirmação, clique em Sim

Vamos criar nosso JSP:

1. Na aba Projetos, clique com o botão direito no item Páginas web


2. Selecione a opção Novo, item Outro...
3. Na caixa Categorias, selecione Web
4. Na caixa Tipos de arquivos, selecione JSP
5. Clique em Próximo >
6. Em Nome do arquivo JSP, entre com crudTelefone
7. Clique em Finalizar

Subs tua o código gerado pelo conteúdo abaixo (que é grande, alias):

<%@page contentType="text/html" pageEncoding="UTF-8"%>

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> &nbsp;
<h:commandLink actionListener="#{SessionBean.telefoneBean.setFormUpdate}">
<h:graphicImage styleClass="link" value="img/floppy.gif" />
</h:commandLink> &nbsp;
<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" />
&nbsp;
<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:messages showSummary="false" showDetail="true"


infoClass="severityInformation"
warnClass="severityWarning"
errorClass="severityError" />

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

Para configurar nossa JSP como página inicial, execute a sequência:

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:

<?xml version="1.0" encoding="UTF-8"?>


<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>com.sun.faces.verifyObjects</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/crudTelefone.jsp</welcome-file>
</welcome-file-list>
</web-app>

O que transforma nosso JSP em página principal é a dire va <welcome-file> localizada em


<welcome-file-list>.

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

acessar nossas tags header e footer


4. Na tag <my:header />, fazemos referência ao namespace my (definido na taglib anterior), o
conteúdo de header
5. Em <f:view> definimos o escopo onde trabalharemos com os recursos JSF
6. Em <h:form id="editForm"> é definido o formulário
7. Na criação de <h:dataTable..., definimos os es los CSS (styleClass, headerClass e
footerClass), a listagem SessionBean.telefoneBean.list de componentes que será exibida
(que obtém seu valor em getList() de telefoneBean), o nome do objeto (var="pojo") em cada
linha da tabela, e se a mesma é renderizada. Como telefoneBean foi criado agora, como
você pode observar no código do constructor de ViewManager (“avô” de
TelefoneMananger), definimos this.formRead = true;. Isso significa que, o código de
SessionBean.telefoneBean.formRead (que acessa o método isFormRead() de ViewManager)
u lizado em rendered, retorna true – e possibilita a exibição deste componente dataTable
8. O campo <h:outputText value="#{SessionBean.telefoneBean. tleForm}" /> obtém o valor do
método getTitleForm() que, por consequência de formRead ser verdadeiro, retorna a String
Telefone – Consultar
9. Os <h:outputText..., encontrados nas outras colunas, acessam diretamente o elemento pojo
da iteração, ou seja, um objeto Telefone (lembrando que getList() de telefoneBean, definido
no value de dataTable, retorna uma listagem de Telefone's. Em cada linha, um dos
Telefone's será exibido. Como se trata do pojo Telefone, podemos acessar seus métodos
getNome() e getNumeroFormatado(), respec vamente com pojo.nome e
pojo.numeroFormatado
10. Através dos <h:commandLink... (cada um associado com sua <h:graphicImage...), podemos
disparar as ações (com ac onListener) para setFormView(), setFormUpdate() e
setFormDestroy(). Cada uma delas buscará da sessão, o objeto em questão (pelo código de
getObjectBySession()), e tornará o respec vo booleano form a vo (desabilitando os demais
com clearForm()). Isso nos levaria para as respec vas ações do CRUD.
11. Através do <h:commandBu on..., podemos executar a ação setFormCreate, que criará um
novo pojo com createNewPojo() (que foi sobrescrito em TelefoneManager e, em run me,
será executado) e definirá formCreate como true

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:

Vejamos o que ocorreu:

1. Quando o botão Inserir da primeira tela (a de consulta) foi clicado, o método


setFormCreate() foi chamado, um novo Telefone foi criado e formCreate foi definido como
true. Neste caso, a dataTable da consulta não será mais exibida (pois formRead foi definida
como false) e o panelGrid passará a ser mostrado
2. Os códigos dos <h:inputText..., serão associados aos valores do pojo Telefone
3. Observe também que, através dos disabled's dos <h:inputText..., o JSP desabilitará os input's
para os casos onde isFormView() ou isFormDestroy() retornarem true
4. Com os <h:commandBu on..., poderemos executar as ações do CRUD definidas em
PojoManager
5. Observe que cada um deles possui (com exceção do Voltar) um rendered que fará com que
os mesmos só sejam exibidos em suas respec vas telas. Ou seja, como estamos na tela de
cadastro, getFormCreate() retornará true e fará com que seu botão seja exibido. Como
getFormUpdate() e getFormDestroy() retornam false, os respec vos botões não serão
mostrados para o usuário
6. Simulando um cadastro, entre com os valores 2, 22334455 e João, para os campos DDD,
Número e Nome, respec vamente
7. Quando clicarmos no botão Inserir, o método create() de PojoManager será chamado

http://www.linu.com.br/papers/paper020.htm 28/35
14/02/2019 www.linu.com.br/papers/paper020.htm

8. PojoManager automa camente já recebeu uma instância de Telefone através de setPojo(), e


por isso, quando create() executa this.bo.create(this.pojo);, this.pojo retorna esta instância
9. telefoneBean é uma instância de TelefoneManager, que por usa vez, define o Bo de
PojoManager como sendo um TelefoneBo. Isso significa que, no run me, this.bo de
PojoManager é um TelefoneBo
10. Ao verificarmos o método create() de Bo, vemos que o primeiro procedimento a ser
executado é validate( pojo );
11. Como Bo é um TelefoneBo, o validate() do run me também é o seu, ou seja, vejamos o que
ocorre no validate() de TelefoneBo
12. Como já comentado, esse método faz a validação do pojo Telefone. Em primeiro lugar, ele
valida o valor de telefone.getDdd() (através do objeto de u lidades u l.Number), que por
sua vez, retorna false em ddd.validate() e por consequência gera uma MyCrudExcep on com
a mensagem "Valor do DDD inválido!"
13. Essa exceção é disparada pelo throws do método validate() de TelefoneBo, capturada pelo
try do método create() de Bo, disparada pelo novo MyCrudExcep on de create() de Bo,
capturada pelo try de PojoManager, que por sua vez envia uma mensagem para a JSP
14. Como nada foi alterado em formCreate (de ViewManager) a mesma tela será exibida,
porém com a mensagem encaminha sendo mostrada na parte inferior (igual a imagem
anterior)
15. Se preenchermos os dados corretamente, após o validate() de TelefoneBo, o método
create() de Dao é executado, que por sua vez, armazena o objeto no banco
16. O run me retorna para o método create() de PojoManager, executa setFormCreate() - para
criar um novo Telefone e consequentemente limpar os campos do JSP – e posteriormente,
joga uma mensagem para a JSP

Observe o que ocorre quando o cadastro é realizado com sucesso:

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:

Se clicarmos na opção de alterar (ícone do disquete, na tela de consulta), e realizarmos algumas


alterações, o método update() de PojoManager realiza o procedimento setFormRead(), que levará

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.

Aplicando as Regras de Negócio


Como você pode observar, os procedimento de cadastro e atualização obrigam o usuário a passar
pelo método validate() de TelefoneBo. É exatamente nesta classe que nós vamos aplicar as
seguintes regras de negócio:

· O sistema não deve permi r cadastrar um DDD da área 22


· Luck é arquiinimigo de Dartvaider. O sistema não deve deixar que ambos existam no banco de
dados para evitar uma pane no sistema
· O sistema deve ter no mínimo 1 (um) registro no banco de dados

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;

public class TelefoneBo extends Bo {

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

private void invalidDdd(Telefone telefone) throws MyCrudException {


if ( telefone.getDdd().equals( "22" ) )
throw new MyCrudException( "O DDD 22 não pode ser utilizado!" );
}

private void luckVersusDartvaider(Telefone telefone)


throws MyCrudException {

String ejbQL = "select obj from Telefone obj where ";


ejbQL += "UPPER( obj.nome ) like ?1";
String parameter[] = new String[ 1 ];

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 {

String ejbQL = "select obj from Telefone obj";


List<Telefone> collection = (List<Telefone>)
super.executeQuery( ejbQL , null );
if ( collection.size() == 1 )
throw new MyCrudException( "Existe um único registro!" );

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:

1. Na tela de cadastro, entre com o telefone de Dartvaider. Ao inserir, o método create(), em


algum momento, encontra com validate(), que por sua vez chama luckVersusDartvaider()
2. Em luckVersusDartvaider(), criamos nossa EJB Query Language que vai verificar se existe
algum registro no banco com obj.nome igual (ou que contém – like) o parâmetro, ainda não
definido, ?1

http://www.linu.com.br/papers/paper020.htm 33/35
14/02/2019 www.linu.com.br/papers/paper020.htm

3. Se getNome() possui o valor LUCK, parameter[0] será DARTVAIDER


4. Caso contrário, paramter[0] será LUCK
5. Em nosso exemplo, o valor de parameter[0] é igual á DARTVAIDER
6. Através do método executeQuery() de Bo, passamos ejbQL e o vetor parameter para
executeQuery() de Dao, que por sua vez, monta uma Query que subs tui a dire va ?1 pelo
valor con do em parameter (isso é realizado em um looping, pois podemos ter vários
parâmetros dependendo da Query)
7. Por fim, essa consulta retorna uma List<?> com os resultados
8. O run me volta para o método luckVersusDartvaider() e verifica a quan dade de registros
con dos em collec on. Como Luck já estava cadastrado (em nosso exemplo, já estava),
collec on.isEmpty() retornará false, que com a oposição do resultado (!), fará com que uma
MyCrudExcep on seja disparada com a mensagem "May The Force Be With You!"
9. Observe que tanto o valor de getNome() (em Telefone) quanto o valor de obj.nome (na
ejbQL) são transformados em maiúsculo para uma melhor comparação

Após executar este teste, a tela abaixo será exibida:

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:

Bom, é isso ai!

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.

Bom pessoal! Espero ter contribuído com algo!


Caso vejam algum erro no sistema ou algum erro de português (ops!!!), peço que colaborem
enviando-me um e-mail para que o mesmo possa ser corrigido!

Você pode fazer o download completo da aplicação clicando aqui!

Abraços, Guilherme Pontes.

http://www.linu.com.br/papers/paper020.htm 35/35

Vous aimerez peut-être aussi