Curso de Engenharia de Computação DESENVOLVIMENTO DE...

49
i Curso de Engenharia de Computação DESENVOLVIMENTO DE SISTEMAS UTILIZANDO JAVA DESIGN PATTERNS: STRUTS, HIBERNATE, DAO E JSTL. William Patatas Soares Itatiba – São Paulo – Brasil Dezembro de 2006

Transcript of Curso de Engenharia de Computação DESENVOLVIMENTO DE...

i

Curso de Engenharia de Computação

DESENVOLVIMENTO DE SISTEMAS UTILIZANDO JAVA

DESIGN PATTERNS: STRUTS, HIBERNATE, DAO E JSTL.

William Patatas Soares

Itatiba – São Paulo – Brasil

Dezembro de 2006

ii

Curso de Engenharia de Computação

DESENVOLVIMENTO DE SISTEMAS UTILIZANDO JAVA

DESIGN PATTERNS: STRUTS, HIBERNATE, DAO E JSTL.

William Patatas Soares

Monografia apresentada à disciplina Trabalho de Conclusão de Curso, do Curso de Engenharia de Computação da Universidade São Francisco, sob a orientação do Prof. Dr. André Leon S. Gradvohl, como exigência parcial para conclusão do curso de graduação. Orientador: Prof. Dr. André Leon S. Gradvohl

Itatiba – São Paulo – Brasil

Dezembro de 2006

iii

Desenvolvimento de sistemas utilizando Java Design Patterns:

Struts, Hibernate, DAO e JSTL.

William Patatas Soares

Monografia defendida e aprovada em 12 de dezembro de 2006 pela Banca

Examinadora assim constituída:

Prof . André Leon S. Gradvohl

USF – Universidade São Francisco – Itatiba – SP.

Prof Beto Wenzel

USF – Universidade São Francisco – Itatiba – SP.

Prof Maurício Fabbri

USF – Universidade São Francisco – Itatiba – SP.

iv

A mente que se abre a uma nova idéia jamais

voltará ao seu tamanho original.

(Albert Einstein)

v

A meus pais Aguiar e Benilde, sem os quais não

chegaria até aqui.

A minha noiva Meire, que ensinou-me a fé e o

amor.

Sou eternamente grato a todos.

vi

Agradecimentos

Agradeço primeiramente ao Professor André, meu orientador, que acreditou em mim e

incentivou-me para a conclusão deste trabalho, face aos inúmeros percalços do trajeto.

Agradeço também ao Professor Alencar, um companheiro de percurso e de discussões

profícuas, dentro e fora do contexto deste trabalho, agraciando-me incontáveis vezes com sua

paciência, conhecimento e amizade.

Eu agradeço fraternalmente a todos.

vii

Sumário

Lista de Siglas...................................................................................................................... ix

Lista de Figuras.................................................................................................................... x

Resumo ................................................................................................................................ xi

Abstract ............................................................................................................................... xi

1 Introdução ..................................................................................................................... 1 1.1 Visão geral................................................................................................................ 1

2 Projeto............................................................................................................................ 4 2.1 Aplicações web multicamadas................................................................................... 4 2.2 Padrões de Projeto..................................................................................................... 5

3 Padrão de projeto Model-View-Controller................................................................... 7 3.1 Visão geral................................................................................................................ 7 3.2 Modelo da arquitetura ............................................................................................... 7 3.3 Seqüência de funcionamento ..................................................................................... 8 3.4 Framework Struts...................................................................................................... 9

3.4.1 Modelo da arquitetura......................................................................................... 9 3.4.2 Fluxo de uma aplicação Struts .......................................................................... 10

4 Padrão de projeto hibernate ....................................................................................... 12 4.1 Visão geral.............................................................................................................. 12 4.2 Recursos ................................................................................................................. 12 4.3 Modelo da arquitetura ............................................................................................. 14

5 Padrão de projeto DAO............................................................................................... 16 5.1 Visão geral.............................................................................................................. 16 5.2 Recursos ................................................................................................................. 16

6 Padrão de projeto jstl (jsp standard tag library) ....................................................... 17 6.1 Visão geral.............................................................................................................. 17 6.2 Recursos ................................................................................................................. 17

7 Desenvolvimento da aplicação .................................................................................... 18 7.1 Criar os módulos do sistema.................................................................................... 19

7.1.1 Camada de visão............................................................................................... 20 7.1.2 Camada de controle .......................................................................................... 20 7.1.3 Camada de modelo ........................................................................................... 21

8 Conclusão..................................................................................................................... 23 8.1 Contribuições.......................................................................................................... 23

viii

8.2 Extensões................................................................................................................ 23

Apêndice 1 – Arquivo index.jsp......................................................................................... 24

Apêndice 2 – Arquivo failure.jsp....................................................................................... 26

Apêndice 3 – Arquivo SearchForm.java ........................................................................... 27

Apêndice 4 – Arquivo SearchAction.java ......................................................................... 29

Apêndice 5 – Arquivo struts-config.xml............................................................................ 33

Apêndice 6 – Arquivo PhoneToolDAO.java ..................................................................... 34

Apêndice 7 – Arquivo PhoneToolDTO.java ..................................................................... 35

Apêndice 8 – Arquivo PhoneTool.hbm.xml ...................................................................... 37

Referências Bibliográficas ................................................................................................. 38

ix

Lista de Siglas

DAO Data Access Object

DTO Data Transfer Object

EIS Enterprise Information System

EJB Enterprise Java Bean

HQL Hibernate Query Language

J2EE Java 2 Enterprise Edition

JDBC Java Database Conectivity

JSP Java Server Pages

JSTL JSP Standard Tag Library

LGPL Lesser General Public License

MVC Model-View-Controller

RMI Remote Method Invocation

XML eXtensible Markup Language

x

Lista de Figuras

FIGURA 1-1: AMBIENTE J2EE TÍPICO ....................................................................................... 2

FIGURA 2-1: CENÁRIOS DE APLICAÇÕES J2EE.......................................................................... 5

FIGURA 3-1: MODELO DA ARQUITETURA MVC........................................................................ 8

FIGURA 3-2: SEQÜÊNCIA DE FUNCIONAMENTO DO MVC .......................................................... 8

FIGURA 3-3: MODELO STRUTS DA IMPLEMENTAÇÃO MVC..................................................... 10

FIGURA 4-1: APLICAÇÃO STANDALONE ................................................................................. 13

FIGURA 4-2: APLICAÇÃO WEB .............................................................................................. 13

FIGURA 4-3: COMPONENTES DO HIBERNATE .......................................................................... 14

FIGURA 7-1: CASO DE USO DA APLICAÇÃO ............................................................................. 18

FIGURA 7-2: DIAGRAMA DE SEQÜÊNCIA DA APLICAÇÃO ......................................................... 19

xi

Resumo

As aplicações Java para ambientes web estão sendo cada vez mais utilizadas em

ambientes corporativos. Desenvolvedores têm menos tempo e menos recursos do que

necessitam. Sendo assim, é comum equipes com vários desenvolvedores trabalhando em

equipe.

Esta monografia mostra quatro padrões de projeto que se tornaram ferramentas muito

úteis para os desenvolvedores considerando o cenário descrito acima.

PALAVRAS-CHAVE: padrões de projeto, aplicação web.

Abstract

The Java applications for web environment have been used frequently on corporate

environments. Developers have less time and resources than they need, so there is usually a

team with many developers working together.

This monograph shows four design patterns that became very useful for developers

considering the situation described above.

KEY WORDS: design patterns, web application.

1

1 INTRODUÇÃO

1.1 Visão geral

Aplicações empresariais são complexas, isto é um fato. Diariamente desenvolvedores,

arquitetos, gerentes de projeto e usuários são forçados a lidar com estruturas de dados

complexas, alterações em regras de negócio, mudanças de necessidades dos usuários e novas

tecnologias. Naturalmente, os desenvolvedores geralmente têm menos tempo e menos

recursos do que precisariam (ou gostariam) para enfrentar tudo isso.

A plataforma Java 2 Enterprise Edition (J2EE) surgiu com o objetivo de padronizar e

simplificar a criação de aplicações empresariais. Para isso, propõe um modelo onde

componentes J2EE (páginas JSP1, Servlets2, EJB's3, etc) escritos pelos usuários da plataforma,

podem fazer uso de serviços providos por esta, os quais simplificam sua implementação e

possibilitam maior foco no negócio.

Um diferencial significativo na arquitetura proposta para a plataforma J2EE foi a

iniciativa de enfatizar a utilização de design patterns (ou padrões de projeto, em português).

Tais padrões trazem inúmeras vantagens na modelagem e implementação de um software [9]:

• possibilidade de projetar soluções mais rapidamente e com qualidade já que os

padrões são soluções comprovadamente eficientes para problemas já conhecidos;

• visam principalmente flexibilidade, organização e reaproveitamento de código, o que

resulta em maior produtividade, qualidade e facilidade de manutenção das aplicações assim

desenvolvidas.

1 Java Server Pages (JSP) consiste em uma tecnologia baseada em java utilizada no desenvolvimento de

aplicações para web. 2 Objetos Java que recebem requisições http e geram respostas baseadas nessas requisições. 3 Enterprise Java Bean (EJB) é um componente de software que estende as funcionalidades de um servidor

permitindo encapsular lógica de negócio e dados específicos de uma aplicação.

2

Os principais serviços disponibilizados pela plataforma J2EE destinam-se a suprir as

necessidades de aplicações empresariais distribuídas, isto é, aquelas que necessitam da

flexibilidade de disponibilizar acesso à sua lógica de negócio e dados para diferentes tipos de

dispositivos clientes (navegadores, dispositivos móveis, aplicações desktop, entre outros) e

para outras aplicações residentes na mesma empresa ou fora desta. A Figura 1-1 ilustra um

ambiente J2EE típico [6].

Figura 1-1: Ambiente J2EE típico

A organização dos capítulos posteriores é a seguinte:

• O Capítulo 2 descreve uma introdução do projeto tema deste trabalho, de

aplicações multicamadas e de padrões de projeto;

• O Capítulo 3 explica sobre o padrão de projeto MVC (Model View Contoller)

e como ele ajuda no desenvolvimento modular de um sistema multicamadas,

focando principalmente no padrão Struts que implementa o MVC;

• O Capítulo 4 explica sobre o padrão de projeto Hibernate que permite um

mapeamento objeto-relacional do banco de dados para o sistema;

• O Capítulo 5 aborda o padrão DAO (Data Access Object), que junto com o

Hibernate auxilia na parte de persistência do desenvolvimento do sistema;

3

• O Capítulo 6 descreve o padrão JSTL, biblioteca de tags que auxiliam no

desenvolvimento de paginas web, poupando esforço e tempo do

desenvolvedor.

• O Capítulo 7 descreve o desenvolvimento de um sistema web integrando as

aplicações dos padrões descritos;

• O Capítulo 8 finaliza com conclusões após o desenvolvimento de um sistema

web utilizando as ferramentas abordadas e possíveis contribuições para futuros

trabalhos.

4

2 PROJETO

Neste projeto será implementada uma aplicação web na qual serão utilizados quatro

padrões de projeto para demonstrar sua eficiência no seu desenvolvimento e para mostrar um

sistema bem estruturado onde, apesar de ser uma aplicação relativamente pequena, sua

estrutura pode ser aplicada também em sistemas de grande porte.

2.1 Aplicações web multicamadas

Aplicações distribuídas são comumente compostas de uma camada cliente, que

implementa a interface com o usuário, uma ou mais camadas intermediárias, que processam a

lógica do negócio e provêem serviços à camada cliente, e outra, chamada de Enterprise

Information System (EIS), formada por sistemas legados e bancos de dados. A infra-estrutura

oferecida pela J2EE possibilita que estas camadas, possivelmente localizadas em máquinas

diferentes, possam se comunicar remotamente e juntas comporem uma aplicação.

Um componente criado numa aplicação J2EE deve ser instalado no container

apropriado. Um container é um ambiente de execução padronizado que provê serviços

específicos a um componente. Assim, um componente pode esperar que em qualquer

plataforma J2EE implementada por qualquer fornecedor estes serviços estejam disponíveis.

Um web container destina-se a processar componentes web como servlets, JSP's,

HTML's e Java Beans. Estes são suficientes para criar aplicações completas que não

necessitam ser acessadas por diferentes tipos de cliente nem tampouco tornar seus dados e

lógica distribuídos. Já um EJB container destina-se a prover a infra-estrutura necessária para a

execução de componentes de negócio distribuídos. Tal componente pode ser acessado de

maneiras diferentes, por exemplo, através de Remote Method Invocation (RMI), o que

possibilita que este seja utilizado por qualquer tecnologia que provê suporte a um dos padrões

de comunicação e que seja localizado virtualmente a partir de qualquer rede TCP/IP.

5

A plataforma J2EE permite uma arquitetura flexível sendo que tanto o web container

quanto o EJB container são opcionais. Alguns cenários possíveis podem ser observados na

Figura 2-1 [11].

Figura 2-1: Cenários de aplicações J2EE

2.2 Padrões de Projeto

A correta utilização de arquiteturas e padrões de projeto no desenvolvimento de

softwares representa um importante ideal a ser alcançado por qualquer equipe que pretende

produzir aplicações computacionais profissionais. Não basta aprender uma tecnologia, é

necessário também conseguir projetar soluções com esta tecnologia. A definição de uma

arquitetura, por exemplo, permite que tenhamos uma visão completa da aplicação, de quais

são seus principais componentes, o objetivo de cada um deles e a maneira como se relacionam

a fim de desempenharem suas funções. Quando utilizamos padrões, estamos levando em

conta experiências de outros projetos de desenvolvimento, aumentando assim as chances de

chegarmos a uma solução correta pois erros passados poderão ser evitados.

Em aplicações sob a plataforma J2EE não é diferente. Em geral estamos tão atolados no

processo de compreensão dos serviços da plataforma, de suas APIs (Application Program

Interface) e do negócio a ser resolvido que não dedicamos o tempo necessário para aprender a

projetar soluções com a tecnologia. Segundo Grady Booch [12], “existe um buraco semântico

entre as abstrações e serviços que a plataforma J2EE oferece e a aplicação final que será

6

produzida com esta e os padrões de projeto representam soluções que aparecem repetidamente

para preencher este buraco”.

Um padrão provê uma solução para um problema comum baseado em experiências

anteriores comprovadamente eficazes. Dispor de um bom conjunto de padrões é como ter um

time de especialistas sentado ao seu lado durante o desenvolvimento, aconselhando-lhe com o

melhor do seu conhecimento.

Boas práticas de projeto são descobertas pela experiência e levam tempo até se

tornarem maduras e confiáveis. Um padrão captura essa experiência e serve para comunicar,

de forma padronizada, o conhecimento que trazem. Dessa forma, os padrões, além de

ajudarem os desenvolvedores e arquitetos a reutilizarem soluções tanto de projeto quanto de

implementação, ajudam também a criar um vocabulário comum na equipe, diminuindo assim

o esforço de comunicação.

Os padrões que serão abordados neste texto ajudam a melhorar o desempenho de

sistemas em multicamadas e a torná-los mais fáceis de se manter ao reduzir a complexidade.

O padrão Model-View-Controller (MVC) reforça um projeto modular e de fácil manutenção e

força a separação de camadas, será abordado através da sua implementação Struts. O Data

Access Object (DAO) fornece uma interface flexível entre a lógica de negócio e as fontes de

dados reais. O Hibernate que é um serviço de consulta e persistência Objeto/Relacional para

Java, provê um mapeamento de uma classe para uma tabela do banco de dados, muito

poderoso e de alto desempenho. E o JSP Standard Tag Library (JSTL), que consiste numa

biblioteca de tags de JSP que auxiliam e agilizam a construção de páginas JSP.

7

3 PADRÃO DE PROJETO MODEL-VIEW-CONTROLLER

3.1 Visão geral

Depois de anos de evolução das tecnologias web e dos processos fabris de construções

de aplicações orientadas a objetos, o padrão MVC garante a separação da interface, do

controle de fluxo e da regra de negócio, em que cada tipo de componente executa um

determinado tipo de tarefa. Essa separação permite alteração em cada uma das camadas

isoladamente, diminuindo o trabalho da mudança constante das aplicações web.

Como o MVC facilita a divisão de trabalho por conjuntos de habilidades, este padrão é

bastante adequado para empresas de desenvolvimento que suportam desenvolvimento

modular e concorrente com muitos desenvolvedores.

3.2 Modelo da arquitetura

No modelo MVC, cada componente tem um tipo de responsabilidade [4, 5]:

• Servlets: atuam como controladores (controller), que vão atender e entender as

requisições dos usuários;

• JavaBeans: atuam como modelo (model), que representam e devem executar a

regra de negócio;

• JSP: atuam como visão (view), ou seja, irão disponibilizar as diversas formas de

visualização do modelo de dados.

8

Figura 3-1: Modelo da arquitetura MVC

3.3 Seqüência de funcionamento

O controlador irá receber a requisição, usar serviços do modelo e indicar uma

visualização para exibir o estado do modelo resultante da requisição executada.

Figura 3-2: Seqüência de funcionamento do MVC

9

Existem diversas implementações do modelo MVC, a mais famosa é o framework4

Struts [3].

3.4 Framework Struts

O Struts é um projeto de fonte aberta e foi originalmente criado por Craig McClanahan

em Maio de 2000, mas desde então ele é patrocinado pela Apache Software Foundation e tem

sido mantido pela comunidade do código aberto. O Struts implementa o padrão MVC, sendo

assim ele também tem como objetivo prover a divisão de uma aplicação em um modelo de

dados, um conjunto de visões e um conjunto de controladores [7].

3.4.1 Modelo da arquitetura

Seguindo o padrão do MVC, o modelo da arquitetura do Struts conta com seus

componentes próprios:

4 Estrutura de suporte definida na qual um outro projeto pode ser organizado e desenvolvido.

10

Figura 3-3: Modelo Struts da implementação MVC

3.4.2 Fluxo de uma aplicação Struts

Seguindo a numeração indicada na figura anterior, tem-se o seguinte fluxo:

1. Cada solicitação HTTP tem que ser respondida neste mesmo protocolo. Desta forma,

inicia-se uma aplicação que utiliza o Struts. Esta solicitação normalmente é definida

como requisicao.do, que é um nome lógico para a requisição do usuário.

2. A solicitação requisicao.do é mapeada no arquivo struts-config.xml. Neste

arquivo estão todas as definições do controlador do framework. O arquivo é então lido

por um ActionServlet (que fará efetivamente o papel do controlador da aplicação) na

inicialização da aplicação criando então um banco de objetos com o arquivo de

configuração. No arquivo de configuração são definidos os Actions (requisições dos

usuários) para cada solicitação.

3. O ActionServlet (que faz o papel do controlador da aplicação), define o Action

correspondente para a solicitação. Uma Action pode validar a entrada de dados e acessar

a camada de negócios para recuperar as informações nos bancos de dados e outros

serviços de dados.

4. A requisição HTTP pode ser feita também através de um formulário HTML. Em vez

de fazer com que cada Action retire os valores do campo da solicitação, o ActionServlet

11

coloca a entrada em um JavaBean. Estes JavaBeans são definidos como FormBeans no

Struts e estendem a classe org.apache.struts.action.ActionForm.

5. O Action pode acessar o FormBean, efetuar qualquer operação e armazenar o

resultado em um ResultBean.

6. O Action interage com a camada de negócio onde uma base de dados poderá ser

atualizada.

Em geral, o Struts não apresenta a resposta em si, mas envia a solicitação para outro

recurso, como uma página JSP. O Struts fornece a classe ActionForward que pode ser usada

para armazenar o caminho para uma página sob um nome lógico. Desta forma, o endereço

ficará oculto para o usuário. Este visualizará apenas o nome definido para o caminho (por

exemplo, resposta.do). Este recurso evita que o usuário possa estar visualizando uma

versão desatualizada da aplicação, já que as requisições serão feitas apenas para nomes

lógicos.

Ao completar a lógica de negócio, o Action selecionará e retornará um ActionForward

para o servlet. Então, o servlet usará o caminho armazenado no objeto ActionForward para

chamar a página e completar a resposta.

Esses detalhes logísticos da aplicação são definidos no objeto ActionMapping. Cada

ActionMapping está relacionado a um caminho específico. Quando este caminho for

selecionado, como requisicao.do, o servlet irá recuperar o objeto ActionMapping. O

mapeamento informará ao servlet quais Actions, ActionForms e ActionForwards usar.

12

4 PADRÃO DE PROJETO HIBERNATE

4.1 Visão geral

A grande maioria dos desenvolvedores de sistemas ainda opta por utilizar bancos de

dados relacionais pela confiabilidade e robustez, embora o paradigma utilizado seja o

Orientado a Objetos. Dessa forma, os registros do banco de dados devem ser transformados

em objetos e as informações contidas nos objetos devem ser persistidas em forma de linhas e

colunas. Chama-se isso de “Mapeamento Objeto-Relacional” [10].

Muitas vezes, os desenvolvedores acabam consumindo muito tempo de

desenvolvimento para fazer este mapeamento. A proposta do Hibernate é exatamente prover

aos desenvolvedores uma maneira de realizar este mapeamento de forma transparente, isto é,

criando classes como se não houvesse persistência relacional. Sendo assim o Hibernate

consiste em um serviço de consulta e persistência Objeto/Relacional para Java, muito

poderoso e de alto desempenho.

4.2 Recursos

No entanto, o Hibernate não provê apenas simples mapeamento de uma classe para uma

tabela. Relacionamentos, Herança, Polimorfismo, Composições e Coleções são algumas dos

conceitos orientados a objetos contemplados pelo Hibernate. Ele também possui o Hibernate

Query Language (HQL), uma linguagem de consultas orientada a objetos.

Hibernate suporta uma considerável quantidade de bancos de dados, incluindo DB2,

PostgreSQL, MySQL, Oracle, Sybase, SQL Server, dentre outros. Além de tudo isso,

Hibernate é um software livre. Qualquer pessoa pode utilizá-lo em aplicações domésticas e

comerciais de acordo com a Lesser General Public License (LGPL).

13

Mas o framework não é uma boa opção para todos os tipos de aplicação. Sistemas que

fazem uso extensivo de stored procedures, triggers ou que implementam a maior parte da

lógica da aplicação no banco de dados, contando com um modelo de objetos simples não vai

se beneficiar com o uso do Hibernate. Ele é mais indicado para sistemas que contam com um

modelo rico, onde a maior parte da lógica de negócios fica na própria aplicação Java,

dependendo pouco de funções específicas do banco de dados.

Conforme figuras mostradas abaixo, o Hibernate pode ser aplicado em dois cenários

diferentes:

• Aplicações Standalone (aplicação desktop)

• Aplicações Web

Figura 4-1: Aplicação Standalone

Figura 4-2: Aplicação Web

14

4.3 Modelo da arquitetura

Dependendo da complexidade do projeto, um maior número de APIs e componentes são

utilizados pelo Hibernate. A figura a seguir exibe aqueles que são necessários em um sistema

mais simples possível [1]:

Figura 4-3: Componentes do Hibernate

De acordo com a especificação do Hibernate, os componentes descritos na figura acima

são definidos da seguinte forma:

• Session Factory

Armazena o mapeamento e configurações compilados. É uma fábrica de objetos

Session e também provê conexões. Este objeto é imutável e threadsafe (pode ser

acessado por múltiplas threads sem perigo de inconsistência.

• Session

Um objeto que representa o diálogo entre a aplicação e a persistência (banco de

dados), encapsulando uma conexão JDBC (Java DataBase Connectivity). Este

objeto não deve ser manipulado por múltiplas threads. Ele controla um cache

dos objetos persistentes. Os Sessions não devem durar toda a execução da

aplicação, ou seja, são objetos chamados de vida curta.

• Peristent Object (Objetos Persistentes)

15

Objetos manipulados por informações persistentes e lógica de negócio. Devem

ser JavaBeans (possui um construtor sem parâmetros e métodos get/set para os

atributos persistidos). Eles só podem estar associados à exatamente uma Session.

• Transient Objects (Objetos Transientes)

Instâncias das classes persistentes que não estão atualmente associadas a uma

Session. Podem ter sido instanciados pela aplicação, mas não persistidos ainda,

ou recuperados por uma Session que foi fechada.

• Transaction

Objeto usado pela aplicação para especificar unidades atômicas de acesso ao

banco. Não deve ser manipulado por múltiplas threads. Abstrai a aplicação de

transações do tipo JDBC. Uma Session pode manipular várias Transaction.

16

5 PADRÃO DE PROJETO DAO

5.1 Visão geral

O padrão DAO é uma solução com a qual desenvolvedores implementam um objeto que

é unicamente responsável por receber informação de um armazenamento persistente, onde

quer que ele esteja [9]. Isto abstrai a visão do dado usado por uma aplicação do layout da

tabela, esquema eXtensible Markup Language (XML) ou arquivo em disco. Uma equipe

poderia produzir três objetos DAO para um projeto particular: um para ler o banco de dados,

um para ler dos arquivos XML recebidos da web e um para fornecer dados de teste para serem

usados por desenvolvedores trabalhando em outros aspectos do sistema. Se todos os três

objetos são descendentes de uma única classe abstrata Java que define os vários métodos de

acesso, os objetos podem ser substituídos na aplicação final dependendo das necessidades

atuais. Os objetos podem também ser usados em outros projetos baseados no mesmo modelo.

5.2 Recursos

Em conjunto com o MVC, o DAO pode ser usado para aumentar a velocidade da

camada de apresentação (ou visão) em uma aplicação maior pulando uma camada EJB. Ler

diretamente do banco de dados é sempre mais rápido do que ir através da camada EJB, que

tem que ler o banco de qualquer forma. Fazer isto diretamente com a interface JDBC é uma

prática perigosa, já que ela liga o modelo de dados à camada de apresentação de tal forma que

qualquer alteração na implementação do modelo de dados requer reescrever grandes partes da

camada de apresentação, o que geralmente não é muito prático. Ao se utilizar um DAO

obtém-se o máximo de velocidade com muito menos esforço de manutenção.

Como o DAO provê uma separação do código relacionado ao acesso dos dados, do

código de negócio, em conjunto com o Hibernate, DAO torna-se muito útil deixando

transparente o uso do Hibernate para o código de negócio.

17

6 PADRÃO DE PROJETO JSTL (JSP STANDARD TAG LIBRARY)

6.1 Visão geral

Durante o desenvolvimento web surgiam as seguintes dificuldades:

• Dificuldade de construir páginas JSPs bem organizadas internamente;

• Páginas JSPs com muito código Java;

• Web designers não sabem programar em Java;

• Problemas na interação entre desenvolvedores e web designers.

Diante dessas dificuldades era necessário criar páginas dinâmicas bastante complexas

sem escrever código Java dentro delas, para tornar isso possível eram necessárias tags que

tornassem fáceis tarefas que exigiriam várias linhas de código Java, como formatação de

números e datas seguindo configurações regionais do usuário. Isso facilitaria a interação entre

desenvolvedores e web designers. Surgiu então o JSTL que é uma biblioteca que contempla

essas tags sugeridas anteriormente [2, 8].

6.2 Recursos

JSTL consiste então em uma biblioteca de tags JSP que facilitam muito o

desenvolvimento de uma página JSP. Tal biblioteca abriga muitas funções e funcionalidades

que não necessitam de implementação, apenas chamá-las através de tags, aumentando assim a

legibilidade do código.

18

7 DESENVOLVIMENTO DA APLICAÇÃO

A aplicação para exemplificar a integração entre os padrões de projetos abordado neste

trabalho consiste em um simples sistema de consulta de cadastro, onde um usuário irá

consultar as informações de telefones, email de uma pessoa através do nome dela. O sistema é

simples, mas possui as funcionalidades necessárias para o emprego dos padrões de projeto:

separação em camadas com o Struts, utilização das tags do JSTL e interação com banco de

dados para consultas utilizando DAO e Hibernate.

O sistema será simples, porém dotado de uma arquitetura bem robusta o que permite o

desenvolvimento de novas funcionalidades para ele no futuro. O fluxo de funcionamento do

ponto de vista do usuário é apresentado na Figura 7-1.

Figura 7-1: Caso de uso da aplicação

19

A seqüência de operações do sistema desde a requisição até a resposta é descrita no

seguinte diagrama de seqüência ilustrado na Figura 7-2.

Figura 7-2: Diagrama de seqüência da aplicação

O primeiro passo no desenvolvimento desta aplicação será criar os módulos do sistema

que será organizado em camadas, utilizando assim o Struts que implementa a arquitetura do

padrão MVC. Esta é a parte mais importante, pois trata de toda a estrutura do sistema

podendo assim, caracterizá-lo com os seguintes adjetivos: robustez, escalabilidade,

portabilidade e operabilidade.

7.1 Criar os módulos do sistema

Como o sistema está modelado seguindo a arquitetura Struts do modelo MVC, primeiro

será criada a camada de visão, responsável pela interação com o usuário.

20

7.1.1 Camada de visão

A camada de visão será composta por arquivos JSP que consistem em arquivos com

uma mistura de tags html, tags jsp e tags do Struts. Para padronizar e simplificar o código

(deixando a página JSP sem nenhum código, apenas tags), serão utilizadas as tags da

biblioteca do padrão JSTL.

A aplicação possui os seguintes arquivos JSP: index.jsp (página principal) e

failure.jsp (página onde é retornado o erro). Os códigos destas páginas localizam-se nos

apêndices 1 e 2 respectivamente.

Completando a camada de visão há o ActionForm, que consiste em um objeto JavaBean

que o Struts utiliza para representar os dados do formulário e transferi-los entre as camadas de

visão e as camadas de controle. O sistema possui então o arquivo SearchForm.java,

localizado no Apêndice 3.

No arquivo de configuração struts-config.xml é adicionado a declaração deste

ActionForm como um form-bean pois como foi dito anteriormente o mesmo consiste em um

objeto JavaBean para tratar os dados de um formulário. Para que indicar ao Struts que os

dados do formulário da página index.jsp serão mapeados no objeto SearchForm, é

necessário adicionar as tags para fazer esse mapeamento no arquivo de configuração do Struts

struts-config.xml, este arquivo contém todas as configurações utilizadas pelo Struts,

sendo então o “mapa” da estrutura da aplicação, está no Apêndice 5.

7.1.2 Camada de controle

A camada de controle compreende a funcionalidade envolvida quando o usuário clicar

no botão Search da página JSP principal gerando um evento para que se gere uma interface

de resposta. Esta camada chamará os objetos de persistência da camada de modelo para que

efetuem as operações necessárias no banco de dados e retornem um resultado que servirá de

base para a camada de controle direcionar para a página JSP que deverá gerar a interface

resultante.

21

Será criada então a classe SearchAction.java que recebe o evento search da

página principal index.jsp resgatando os dados através da SearchForm.java e

invocando a camada de modelo para fazer as operações necessárias de consulta no banco.

Retornado algum dado essa classe redireciona o resultado de sucesso para a página inicial

index.jsp mapeando novamente os dados de retorno no SearchForm.java, não

retornando dado a classe redireciona o resultado de erro para a página failure.jsp .

O mapeamento indicando esse fluxo: index.jsp preenche com os valores do

formulário o SearchForm.java do qual a SearchAction.java resgatará para invocar

a camada de modelo redirecionando o resultado para Index.jsp caso sucesso ou

failure.jsp caso falha, é feito no arquivo struts-config.xml.

7.1.3 Camada de modelo

A classe SearchAction preencherá um java bean responsável pela transferência de

dados entre a camada de controle e modelo chamado de Data Transfer Object (DTO) , este

DTO recebe o nome de PhoneToolDTO.java, e está descrito no Apêndice 7.

Após preencher esse java bean, a classe SearchAction chamará a classe DAO

PhoneToolDAO.java, apresentado no Apêndice 6, passando o DTO. A classe DAO por

sua vez acessará o banco de dados através do Hibernate efetuando a abertura de conexão,

consulta, mapeamento dos dados retornados e encerramento da conexão de forma

transparente.

Isso porque o a aplicação possui um arquivo de configuração chamado

PhoneTool.hbm.xml, detalhado no Apêndice 8. Esse arquivo mapeia a tabela onde é feita

a consulta com nossa classe DTO, mapeia também cada campo da tabela com seu respectivo

atributo no DTO, fazendo assim o mapeamento objeto-relacional. Assim o DAO retorna para

22

a SearchAction um objeto DTO preenchido com os atributos resultantes da consulta feita

pelo Hibernate.

23

8 CONCLUSÃO

A pesquisa desenvolvida ao longo deste trabalho buscou mostrar como aperfeiçoar o

desenvolvimento de uma aplicação web multicamadas, mostrando quatro padrões de projeto

muito úteis de confiabilidade reconhecida.

O desenvolvimento de uma aplicação web sem a utilização desses quatro padrões de

projeto, necessitaria de muito mais tempo e não proporcionaria uma arquitetura tão robusta

para a aplicação. São ferramentas poderosas que tornam mais simples a maneira de lidar com

funcionalidades mais complexas como acesso a banco, modulação e desenvolvimento de um

sistema web.

8.1 Contribuições

As principais contribuições gerais deste estudo são dar uma introdução de como

desenvolver uma aplicação web dotada de uma arquitetura robusta e mostrar que o uso de

padrões de projeto torna o desenvolvimento mais rápido e simples.

8.2 Extensões

Este trabalho pode ser continuado agregando-se mais padrões de projeto e tornando o

sistema mais complexo, contemplando novas funcionalidades.

24

Apêndice 1 – Arquivo index.jsp

<%@ page language="java" import="java.lang.*,java.util.*" %>

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<%@ taglib uri="http://displaytag.sf.net" prefix="display" %>

<html>

<head>

<title>Phone Tool</title>

</head>

<html:form action="/search">

<table>

<tr>

<td align="left">

Name:

<html:text property="name" size="50"/>

</td>

</tr>

<tr>

<td align="left">

Email:

<html:text property="email" size="50"/>

</td>

</tr>

<tr>

<td align="left">

Department:

<html:text property="department" size="50"/>

</td>

</tr>

<tr>

<td align="left">

Nextel:

<html:text property="nextel" size="50"/>

</td>

</tr>

<tr>

<td align="left">

Mobile Phone:

<html:text property="mobile" size="50"/>

25

</td>

</tr>

<tr>

<td align="left">

Ramal:

<html:text property="ramal" size="50"/>

</td>

</tr>

<tr>

<td align="left">

Id:

<html:text property="id" size="50"/>

</td>

</tr>

</table>

<br>

<html:submit property="method" value="search"/>

<html:submit property="method" value="newSearch"/>

</html:form>

</---------------------------------------------------------------------------------------/>

<br>

<display:table name="RESULT">

<display:column property="name" href="search.do?method=select" paramId="index" paramProperty="ramal"/>

<display:column property="ramal"/>

</display:table>

</html>

26

Apêndice 2 – Arquivo failure.jsp

<%@ page language="java" import="java.lang.*,java.util.*" %>

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html>

<head>

<title>Phone Tool</title>

</head>

<html:form action="/search">

<%= request.getAttribute("RESULT")%>

<br>

<html:submit property="method" value="back"/>

</html:form>

</html>

27

Apêndice 3 – Arquivo SearchForm.java

package com.sanminasci.phonetool;

import org.apache.struts.action.ActionForm;

public class SearchForm extends ActionForm {

private static final long serialVersionUID = 3256719572219409968L;

protected String name;

protected String email;

protected String department;

protected String nextel;

protected String mobile;

protected String ramal;

public void setName(String name) {

this.name = name;

}

public String getName() {

return (name);

}

public void setEmail(String email) {

this.email = email;

}

public String getEmail() {

return (email);

}

public void setDepartment(String department) {

this.department = department;

}

public String getDepartment() {

return (department);

}

public void setMobile(String Mobile) {

this.mobile = (mobile);

}

public String getMobile() {

return (mobile);

}

public void setNextel(String nextel) {

28

this.nextel = (nextel);

}

public String getNextel() {

return (nextel);

}

public void setRamal(String ramal) {

this.ramal = (ramal);

}

public String getRamal() {

return (ramal);

}

public void reset(){

this.name=null;

this.email=null;

this.department=null;

this.nextel=null;

this.ramal=null;

}

}

29

Apêndice 4 – Arquivo SearchAction.java

package com.sanminasci.phonetool;

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

import org.apache.struts.actions.DispatchAction;

import com.sanminasci.phonetool.util.PhoneToolDAO;

import com.sanminasci.phonetool.util.PhoneToolDTO;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import javax.servlet.ServletContext;

import javax.servlet.ServletRequest;

import javax.sql.DataSource;

import java.sql.Connection;

import java.sql.Statement;

import java.sql.ResultSet;

// ---- Search -----------------------------------------------------------------------------------------

public class SearchAction extends DispatchAction

{

Connection con = null;

Statement stmt = null;

ResultSet rs = null;

public ActionForward search(ActionMapping mapping, ActionForm search,

HttpServletRequest request, HttpServletResponse response)

throws Exception {

String target;

HttpSession session = request.getSession(true);

ServletContext context = servlet.getServletContext();

DataSource dataSource = (DataSource) context

.getAttribute(Action.DATA_SOURCE_KEY);

PhoneToolDAO dao = new PhoneToolDAO(dataSource);

SearchForm form = (SearchForm) search;

PhoneToolDTO dto = new PhoneToolDTO();

if(form.getName() != "")

{

dto.setName(form.getName());

}

else

{

dto.setName(null);

30

}

if(form.getEmail() != "")

{

dto.setEmail(form.getEmail());

}

else

{

dto.setEmail(null);

}

if(form.getDepartment() != "")

{

dto.setDepartment(form.getDepartment());

}

else

{

dto.setDepartment(null);

}

if(form.getNextel() != "")

{

dto.setNextel(form.getNextel());

}

else

{

dto.setNextel(null);

}

if(form.getMobile() != "")

{

dto.setMobile(form.getMobile());

}

else

{

dto.setMobile(null);

}

if(form.getRamal() != "")

{

Integer ramal = new Integer(Integer.parseInt(form.getRamal()));

dto.setRamal(ramal);

}

else

{

dto.setRamal(null);

}

ArrayList resultlist = dao.findByParameters(dto);

if (resultlist.isEmpty())

{

target = "failure";

31

String error = "Contact not found";

request.setAttribute("RESULT",error);

}

else

{

request.setAttribute("RESULT",resultlist);

session.setAttribute("RESULT",resultlist);

target = "success";

}

return (mapping.findForward(target));

}

// ---- Select -----------------------------------------------------------------------------------------

public ActionForward select(ActionMapping mapping, ActionForm search,

HttpServletRequest request, HttpServletResponse response)

throws Exception {

SearchForm form = (SearchForm) search;

HttpSession session = request.getSession(true);

PhoneToolDTO dto = new PhoneToolDTO();

ArrayList resultlist = (ArrayList)session.getAttribute("RESULT");

for(int i=0; i<resultlist.size(); i++)

{

If(request.getParameter("index").equals(((PhoneToolDTO)

resultlist.get(i)).getRamal().toString()))

{

form.setName(((PhoneToolDTO) resultlist.get(i)).getName());

form.setEmail(((PhoneToolDTO) resultlist.get(i)).getEmail());

form.setDepartment(((PhoneToolDTO) resultlist.get(i)).getDepartment());

form.setNextel(((PhoneToolDTO) resultlist.get(i)).getNextel());

form.setRamal((((PhoneToolDTO) resultlist.get(i)).getRamal()).toString());

request.setAttribute("RESULT1",form);

request.setAttribute("RESULT",resultlist);

break;

}

}

String target = "success";

return (mapping.findForward(target));

}

// ---- newSearch -----------------------------------------------------------------------------------------

public ActionForward newSearch(ActionMapping mapping, ActionForm search,

HttpServletRequest request, HttpServletResponse response)

throws Exception {

SearchForm form = (SearchForm) search;

HttpSession session = request.getSession(true);

session.removeAttribute("RESULT");

session.removeAttribute("SEQ");

request.removeAttribute("RESULT");

request.removeAttribute("RESULT1");

32

form.setName(null);

form.setEmail(null);

form.setDepartment(null);

form.setNextel(null);

form.setRamal(null);

String target = "success";

return (mapping.findForward(target));

}

// ---- Back ------------------------------------------------------------------------------------------

public ActionForward back(ActionMapping mapping, ActionForm search,

HttpServletRequest request, HttpServletResponse response)

throws Exception {

SearchForm form = (SearchForm) search;

HttpSession session = request.getSession(true);

session.removeAttribute("RESULT");

session.removeAttribute("SEQ");

request.removeAttribute("RESULT");

request.removeAttribute("RESULT1");

form.setName(null);

form.setEmail(null);

form.setDepartment(null);

form.setNextel(null);

form.setRamal(null);

String target = "success";

return (mapping.findForward(target));

}

}

33

Apêndice 5 – Arquivo struts-config.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"

"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>

<data-sources>

<data-source>

<set-property property="driverClass"

value="org.postgresql.Driver" />

<set-property property="url"

value="jdbc:postgresql://localhost:5432/public" />

<set-property property="user"

value="postgres" />

<set-property property="password"

value="postgres" />

</data-source>

</data-sources>

<form-beans>

<form-bean name="SearchForm"

type="com.sanminasci.phonetool.SearchForm"/>

<form-bean name="AdminForm"

type="com.sanminasci.phonetool.AdminForm"/>

<form-bean name="ModuloForm"

type="com.sanminasci.phonetool.ModuloForm"/>

</form-beans>

<action-mappings>

<action path="/search"

type="com.sanminasci.phonetool.SearchAction"

name="SearchForm"

input = "/index.jsp"

scope="request"

parameter="method">

<forward name="success" path="/index.jsp" />

<forward name="failure" path="/failure.jsp" />

</action>

</action-mappings>

<message-resources parameter="" />

<message-resources key="" parameter="" />

</struts-config>

34

Apêndice 6 – Arquivo PhoneToolDAO.java

package com.sanminasci.phonetool.util;

import cirrus.hibernate.*;

public class PhoneToolDAO

{

private SessionFactory factory;

public PhoneToolDAO() {

Datastore datastore = Hibernate.createDatastore();

datastore.storeClass(Amigo.class);

factory = datastore.buildSessionFactory();

}

//--------- Find By Parameters ---------------------------------------------------------------------

public java.util.List getInfo(String condicao) throws Exception{

Session session = factory.openSession();

PhoneToolDTO phoneTool = session.find(condicao);

session.flush();

session.close();

return amigos;

}

}

35

Apêndice 7 – Arquivo PhoneToolDTO.java

package com.sanminasci.phonetool.util;

public class PhoneToolDTO {

protected String name;

protected String email;

protected String department;

protected String nextel;

protected Integer ramal;

protected String mobile;

public PhoneToolDTO() {

super();

}

public void setName(String name) {

this.name = name;

}

public String getName() {

return (name);

}

public void setEmail(String email) {

this.email = email;

}

public String getEmail() {

return (email);

}

public void setDepartment(String department) {

this.department = department;

}

public String getDepartment() {

return (department);

}

public void setNextel(String nextel) {

this.nextel = (nextel);

36

}

public String getNextel() {

return (nextel);

}

public void setMobile(String mobile) {

this.mobile = (mobile);

}

public String getMobile() {

return (mobile);

}

public void setRamal(Integer ramal) {

this.ramal = (ramal);

}

public Integer getRamal() {

return (ramal);

}

}

37

Apêndice 8 – Arquivo PhoneTool.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD//EN"

"http://hibernate.sourceforge.net/hibernate-mapping.dtd">

<hibernate-mapping>

<class name="Amigo" table="amigos">

<id name="name" column="nome" type="name">

<generator class="assigned"/>

</id>

<property name="email" type="string"/>

<property name="department" type="string"/>

<property name="nextel" type="string"/>

<property name="ramal" type="integer"/>

<property name="mobile" type="string"/>

</class>

</hibernate-mapping>

38

Referências Bibliográficas

[1] Elliott, James. Hibernate: A Developer’s Notebook. O’Reilly, 2004.

[2] Geary, David M. Core JSTL Mastering the JSP Standard Tag Library. Prentice Hall PTR, 2002.

[3] Goodwill, James. Mastering Jakarta Struts. Wiley, 2002.

[4] Hall, Marty; Brown, Larry. Core Servlets and JavaServer Pages, Volume 1: Core Technologies. Sun Microsystems, 2004.

[5] Bloch, Cynthia; Bodoff , Stephanie. Servlets Tutorial. Disponível em um CD que acompanha o livro: “Entendendo e dominando o Java” de Oziel Moreira Neto.

[6] Neto, Oziel Moreira. Entendendo e dominando o Java para Internet. Digerati Books, 2006.

[7] Hightower, Rick. Jakarta Struts Live. Source Beat, 2004.

[8] Sun Microsystems. JavaServer Pages Standard Tag Library. Disponível on-line em http://java.sun.com/products/jsp/jstl, 2005.

[9] Sun Microsystems. Design Patterns. Disponível on-line em http://www.java.sun. com

[10] Faé, Bruno; Souza, Vitor. Engenho - Tutorial Hibernate - Parte 01. Disponível em http://www.javablogs.com.br/blogs/page/engenho

[11] Neto, Oziel Moreira. Entendendo e dominando o Java. Digerati Books, 2004.

[12] Alur, Deepak; Crupi, John; Malks, Dan. Core J2EE Patterns: Best Practices and Design Strategies, Second Edition. Pearson, 2003.