Você está na página 1de 209

Caelum

Mata o tempo e matas a tua carreira


BryanForbes

Sobre a empresa
ACaelumatuanomercadodesde2002,desenvolvendosistemaseprestandoconsultoria
em diversas reas, luz sempre da plataforma Java. Foi fundada por profissionais que se
encontraramnoBrasildepoisdeumaexperincianaAlemanhaeItlia,desenvolvendosistemasde
grandeportecomintegraoaosmaisvariadosERPs.Seusprofissionaispublicaramjdiversos
artigos nas revistas brasileiras de Java, assim como artigos em eventos acadmicos, e so
presenaconstantenoseventosdatecnologia.
Em 2004 a Caelum criou uma gama de cursos que rapidamente ganharam grande
reconhecimentonomercado.OscursosforamelaboradosporexinstrutoresdaSunquequeriam
trazer mais dinamismoeaplicaras ferramentas e bibliotecasutilizadasno mercado, taiscomo
Eclipse,Hibernate,Struts,eoutrastecnlogiasopensourcequenosoabordadaspelaSun.O
materialutilizadofoiinicialmentedesenvolvidoenquantoeramministradososcursosdeverode
javadaUniversidadedeSoPauloemjaneirode2004pelosinstrutoresdaCaelum.
Em2006aempresafocaseusprojetosemtrsgrandesreas:sistemasdegerenciamento
decontedoparaportais,desenvolvimentodesoluesdeintegraofinanceiraetreinamentocom
intuitodeformao.

Sobre a apostila
EstaaapostiladaCaelumquetemcomointuitoensinarJavadeumamaneiraelegante,
mostrandoapenasoquenecessrionomomentocorretoepoupandooleitordeassuntosque
nocostumamserdeseuinteresseemdeterminadasfasesdoaprendizado.
ACaelumesperaquevocaproveiteessematerial,equeelepossaserdegrandevaliapara
autodidataseestudantes.Todososcomentrios,crticasesugestesseromuitobemvindos.
Omaterialaquicontidopodeserpublicamentedistribudodesdequenosejaalteradoe
seuscrditossejammantidos.Elenopodeserusadoparaministrarqualquercurso,pormpode
serrefernciaematerialdeapoio.Casovocestejainteressadoemuslofinscomerciais,entre
emcontatocomaempresa.
Ateno: Voc pode verificar a data de ltima atualizao da apostila no fim do ndice.
Nuncaimprimaaapostilaquevocreceberdeumamigooupegarporemail,poisatualizamos
constantementeessematerial,quasequemensalmente.Vatonossositeefaaodownloadda
ltimaverso!

www.caelum.com.br

CaelumJava para desenvolvimento Web

ndice
Captulo 1: Como aprender Java.........................................................................1
1.1 - O que realmente importante?..............................................................1
1.2 - Sobre os exerccios.................................................................................1
1.3 - Tirando dvidas.......................................................................................2
1.4 - Sobre o curso..........................................................................................2
1.5 - Sobre os autores.....................................................................................2
Captulo 2: JDBC java.sql.................................................................................4
2.1 - Executando o eclipse pela primeira vez..................................................4
2.2 - Criando nosso projeto no eclipse............................................................5
2.3 - O banco...................................................................................................6
2.4 - Sockets: uma idia inocente...................................................................7
2.5 - A conexo em Java..................................................................................7
2.6 - Fbrica de Conexes...............................................................................9
2.7 - Fbrica de Conexes facilitando o acesso ao banco.............................9
2.8 - Exerccios..............................................................................................10
2.9 - A tabela de exemplo..............................................................................11
2.10 - Javabeans............................................................................................11
2.11 - Exerccios............................................................................................12
2.12 - Inserindo dados...................................................................................13
2.13 - Solues para viagem Design Patterns............................................15
2.14 - DAO Data Access Object..................................................................15
2.15 - Exerccios............................................................................................17
2.16 - Exerccios adicionais...........................................................................18
2.17 - Pesquisando........................................................................................18
2.18 - Exerccios............................................................................................20
2.19 - Um pouco mais....................................................................................20
2.20 - Exerccios adicionais...........................................................................21
2.21 - Desafios...............................................................................................21
2.22 - Exerccios adicionais...........................................................................21
2.23 - Exerccios adicionais...........................................................................22
Captulo 3: O que o JEE?................................................................................24
3.1 - As especificaes..................................................................................24
3.2 - APIs.......................................................................................................24
3.3 - Referncia de Implementao..............................................................25
3.4 - Implementaes compatveis com a especificao...............................25
3.5 - Apache?.................................................................................................26
Captulo 4: Servlet Continer...........................................................................28
4.1 - Introduo.............................................................................................28
4.2 - Servlet Continer..................................................................................28
4.3 - Tipos de continer.................................................................................28
4.4 - Instalando o tomcat...............................................................................29
4.5 - Em casa: iniciando o tomcat.................................................................31
4.6 - Em casa: parando o tomcat...................................................................31
4.7 - O tomcat no windows............................................................................31
Captulo 5: O eclipse e seus plugins.................................................................33
5.1 - Os plugins Sysdeo e Amateras..............................................................33
5.2 - Configurando o plugin do amateras no eclipse.....................................33
5.3 - Configurando o plugin do tomcat no eclipse........................................34
Datadestaedio:26deJunhode2006

ii

CaelumJava para desenvolvimento Web

5.4 - Em casa: Instalando o eclipse...............................................................36


5.5 - Em casa: Instalando o plugin para o tomcat.........................................36
5.6 - Em casa: Instalando o plugin para arquivos jsp, html e xml................36
5.7 - Plugins do eclipse no windows..............................................................37
Captulo 6: Novo projeto web...........................................................................38
6.1 - Novo projeto..........................................................................................38
6.2 - Configurando no tomcat........................................................................40
6.3 - Erros comuns........................................................................................42
6.4 - Anlise do resultado final......................................................................42
6.5 - O driver do oracle em um servidor tomcat..........................................43
6.6 - web.xml.................................................................................................43
6.7 - Configurando o Amateras.....................................................................43
6.8 - Em casa: configurando o tomcat sem o plugin.....................................44
Captulo 7: JSP Java Server Pages..................................................................46
7.1 - O que uma pgina JSP........................................................................46
7.2 - Exerccios..............................................................................................47
7.3 - Listando os contatos..............................................................................48
7.4 - Exerccios..............................................................................................48
7.5 - Erros comuns........................................................................................50
7.6 - HTML e Java: eu no quero cdigo Java no meu jsp!...........................51
7.7 - EL: Expression language.......................................................................51
7.8 - Exerccios..............................................................................................52
7.9 - Exerccios adicionais.............................................................................52
7.10 - Erros comuns......................................................................................53
7.11 - Exerccios Adicionais..........................................................................53
7.12 - Instanciando POJOs.............................................................................54
7.13 - Compilando os arquivos JSP...............................................................55
Captulo 8: JSTL JavaServer Pages Tag Library............................................56
8.1 - JSTL.......................................................................................................56
8.2 - As empresas hoje em dia.......................................................................56
8.3 - Instalao..............................................................................................57
8.4 - Cabealho para a JSTL core..................................................................57
8.5 - For.........................................................................................................57
8.6 - Exerccios..............................................................................................59
8.7 - c:out e c:set...........................................................................................60
8.8 - Mas quais so as tags da taglib core?...................................................60
8.9 - Import: trabalhando com cabealhos e rodaps...................................60
8.10 - Exerccios............................................................................................61
8.11 - Erros Comuns......................................................................................61
8.12 - Incluso esttica de arquivos..............................................................62
8.13 - Exerccios............................................................................................62
8.14 - Trabalhando com links........................................................................63
8.15 - Exerccios adicionais...........................................................................64
8.16 - Tag <c:if>...........................................................................................64
8.17 - Exerccios............................................................................................64
Captulo 9: Controle de erro.............................................................................66
9.1 - Exceptions.............................................................................................66
9.2 - JSTL a soluo?..................................................................................67
9.3 - Exerccios adicionais.............................................................................67
Datadestaedio:26deJunhode2006

iii

CaelumJava para desenvolvimento Web

9.4 - Tratamento padro de erros modo declarativo..................................68


9.5 - Pgina de erro.......................................................................................68
9.6 - Configurando a pgina de erro.............................................................68
9.7 - Quando acontece um erro em uma pgina jsp......................................69
9.8 - Exerccios..............................................................................................69
9.9 - Tratamento de outros erros..................................................................70
9.10 - Erros comuns......................................................................................71
9.11 - Exerccios............................................................................................71
9.12 - Erros Comuns......................................................................................73
Captulo 10: Servlets.........................................................................................74
10.1 - Servlet............................................................................................. ....74
10.2 - A estrutura de diretrios.....................................................................76
10.3 - Mapeando uma servlet no web.xml....................................................76
10.4 - Exerccios............................................................................................76
10.5 - Erros comuns......................................................................................78
10.6 - Init e Destroy.......................................................................................80
10.7 - Curiosidades do mapeamento de uma servlet....................................81
10.8 - OutputStream x PrintWriter................................................................81
10.9 - Parmetros..........................................................................................82
10.10 - Exerccios..........................................................................................83
10.11 - Exerccios adicionais.........................................................................86
10.12 - doGet, doPost e outros......................................................................86
10.13 - Converso de parmetros.................................................................87
10.14 - Exerccios..........................................................................................87
10.15 - Exerccios adicionais.........................................................................89
10.16 - Variveis membro..............................................................................89
10.17 - Exerccios..........................................................................................90
10.18 - HTML e Java: eu no quero cdigo Html na minha servlet!.............93
10.19 - Como funciona uma pgina JSP........................................................93
10.20 - Web archive (.war)............................................................................94
10.21 - Exerccios..........................................................................................94
10.22 - Quando acontece um erro em uma servlet.......................................97
10.23 - O try e catch......................................................................................98
10.24 - Exerccios..........................................................................................99
10.25 - Servlet para adicionar contatos no banco......................................100
10.26 - Exerccio.........................................................................................100
Captulo 11: Servlet e JSP API........................................................................104
11.1 - Incio e trmino da sua aplicao.....................................................104
11.2 - Exerccios..........................................................................................105
11.3 - getServletContext()...........................................................................105
11.4 - Exerccios..........................................................................................106
11.5 - Acessando a aplicao no jsp............................................................107
11.6 - Exerccios..........................................................................................107
11.7 - Propriedades de pginas jsp.............................................................108
Captulo 12: Model View Controller...............................................................109
12.1 - Servlet ou JSP?..................................................................................109
12.2 - Request dispatchers.........................................................................110
12.3 - Exerccio...........................................................................................111
12.4 - Resultado..........................................................................................111
Datadestaedio:26deJunhode2006

iv

CaelumJava para desenvolvimento Web

12.5 - Melhorando o processo.....................................................................111


Captulo 13: Construindo um Framework MVC.............................................116
13.1 - Nossa interface de execuo............................................................116
13.2 - Exerccios..........................................................................................116
13.3 - Criando um controlador e um pouco mais de reflection...................117
13.4 - Configurando o web.xml...................................................................119
13.5 - Exerccios..........................................................................................119
13.6 - Exerccios..........................................................................................120
13.7 - Exerccios Adicionais........................................................................122
13.8 - Model View Controller......................................................................122
13.9 - Lista de tecnologias: camada de controle.........................................123
13.10 - Lista de tecnologias: camada de visualizao................................124
13.11 - MVC 2.............................................................................................124
Captulo 14: Jakarta Struts.............................................................................125
14.1 - Struts.................................................................................................125
14.2 - Configurando o Struts.......................................................................125
14.3 - Exerccios..........................................................................................125
14.4 - Arquivo de mensagens......................................................................131
14.5 - Exerccios..........................................................................................132
14.6 - Erros comuns....................................................................................133
14.7 - Uma ao Struts................................................................................135
14.8 - Configurando a ao no struts-config.xml........................................136
14.9 - Exerccios..........................................................................................137
14.10 - Erros comuns..................................................................................139
14.11 - Pesquisando um banco de dados....................................................141
14.12 - Criando a ao................................................................................141
14.13 - O arquivo web/lista.jsp....................................................................142
14.14 - struts-config.xml.............................................................................142
14.15 - Exerccio.........................................................................................143
14.16 - Resultado condicional com o Struts................................................145
14.17 - Exerccios........................................................................................145
14.18 - Resultado do struts-config.xml.......................................................146
14.19 - Novos contatos................................................................................146
14.20 - Formulrio.......................................................................................147
14.21 - Mapeando o formulrio no arquivo struts-config.xml.....................147
14.22 - Exerccio.........................................................................................148
14.23 - Lgica de Negcios.........................................................................148
14.24 - Exerccio.........................................................................................149
14.25 - Erros comuns..................................................................................150
14.26 - Validando os campos.......................................................................150
14.27 - Exerccio.........................................................................................151
14.28 - Erros comuns..................................................................................152
14.29 - Limpando o formulrio....................................................................152
14.30 - Exerccios........................................................................................153
14.31 - Exerccios........................................................................................153
14.32 - Dois formulrios para a mesma ao..............................................153
14.33 - Exerccios adicionais.......................................................................154
14.34 - Struts-logic taglib: um exemplo antigo de for................................157
14.35 - Um pouco mais................................................................................157
Datadestaedio:26deJunhode2006

CaelumJava para desenvolvimento Web

Captulo 15: Jakarta Struts.............................................................................158


15.1 - Preparando um sistema de login......................................................158
15.2 - Passo 1: Formbean............................................................................158
15.3 - Passo 2: A pgina de login: login.jsp.................................................159
15.4 - Exerccio...........................................................................................159
15.5 - A ao................................................................................................160
15.6 - A ao no struts-config.xml...............................................................161
15.7 - ok.jsp e erro.jsp.................................................................................161
15.8 - Exerccios..........................................................................................161
15.9 - Testando............................................................................................162
15.10 - Erros comuns..................................................................................163
15.11 - Exerccios........................................................................................163
15.12 - Cookies............................................................................................163
15.13 - Sesso.............................................................................................164
15.14 - Configurando o tempo limite..........................................................164
15.15 - Registrando o usurio logado na sesso.........................................164
15.16 - Exerccios........................................................................................165
15.17 - Mas e o login acessando o banco de dados?...................................166
Captulo 16: Hibernate 3.2.............................................................................167
16.1 - Vantagens..........................................................................................167
16.2 - Criando seu projeto...........................................................................167
16.3 - Modelo..............................................................................................168
16.4 - Configurando a classe/tabela Produto .............................................168
16.5 - Exerccios..........................................................................................169
16.6 - Propriedades do banco......................................................................169
16.7 - Exerccios..........................................................................................169
16.8 - Configurando....................................................................................170
16.9 - Criando as tabelas.............................................................................170
16.10 - Exerccios........................................................................................170
16.11 - Sesses............................................................................................171
16.12 - Hibernate Session Factory..............................................................171
16.13 - Exerccios........................................................................................172
16.14 - Salvando novos objetos...................................................................172
16.15 - Exerccios........................................................................................172
16.16 - Buscando pelo id.............................................................................173
16.17 - Criando o ProdutoDAO ...................................................................173
16.18 - Exerccios........................................................................................173
16.19 - Buscando com uma clusula where................................................174
16.20 - ProdutoDAO: Listar tudo e fazer paginao...................................174
16.21 - Exerccios para o preguioso..........................................................174
16.22 - Exerccios adicionais.......................................................................175
Captulo 17: E agora?.....................................................................................177
17.1 - Certificao.......................................................................................177
17.2 - Frameworks......................................................................................177
17.3 - Revistas.............................................................................................177
17.4 - Falando em Java................................................................................177
Captulo 18: Apndice A - VRaptor.................................................................179
18.1 - Eu no quero o que eu no conheo.................................................179
18.2 - Vantagens..........................................................................................180
Datadestaedio:26deJunhode2006

vi

CaelumJava para desenvolvimento Web

18.3 - Vraptor 2...........................................................................................180


18.4 - Instalando e configurando o VRaptor...............................................180
18.5 - Minha primeira lgica de negcios...................................................180
18.6 - E o jsp com o formulrio? web/vraptor-formulario.jsp.....................181
18.7 - E a pgina final? web/contato/adiciona.ok.jsp..................................182
18.8 - Como configurar esse redirecionamento?........................................182
18.9 - Exerccios..........................................................................................182
18.10 - Log..................................................................................................183
18.11 - Um pouco mais................................................................................184
Captulo 19: Apndice B - Jakarta Velocity.....................................................185
19.1 - Velocity..............................................................................................185
19.2 - Vantagens..........................................................................................186
19.3 - Templates Velocity............................................................................186
19.4 - Instalando e configurando o Velocity e Velocity Tools......................186
19.5 - Exerccios..........................................................................................187
19.6 - Seu primeiro template......................................................................187
19.7 - Exerccios..........................................................................................188
19.8 - Mesclando velocity e o struts............................................................188
19.9 - Exerccios..........................................................................................188
19.10 - Objetos mais complexos..................................................................188
19.11 - Diretivas..........................................................................................189
19.12 - IF................................................................................................. ....189
19.13 - FOREACH.......................................................................................190
19.14 - PARSE.............................................................................................190
19.15 - Comentrios....................................................................................191
19.16 - Outras ferramentas.........................................................................191
19.17 - ImportTool.......................................................................................191
19.18 - CookieTool.......................................................................................191
19.19 - Um pouco mais................................................................................192
Captulo 20: Apndice C - Design Patterns.....................................................194
20.1 - Factory exemplo de cache de objetos.............................................194
Captulo 21: Apndice D - Servlets................................................................198
21.1 - Configurao de uma servlet............................................................198
21.2 - Exerccios..........................................................................................199
21.3 - Aplicao...........................................................................................199
21.4 - Descobrindo todos os parmetros do request..................................200
Captulo 22: Apndice E - Design Patterns.....................................................202
22.1 - Singleton...........................................................................................202
22.2 - Exerccios..........................................................................................203
22.3 - Um pouco mais..................................................................................204

Datadestaedio:26deJunhode2006

vii

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

Como aprender Java


Homens sbios fazem provrbios, tolos os repetem
SamuelPalmer

Comoomaterialestorganizadoedicasdecomoestudaremcasa.

1.1 - O que realmente importante?


Muitos livros, ao passar os captulos, mencionam todos os detalhes da linguagem
juntamentecomosprincpiosbsicosdela.Issoacabacriandomuitaconfuso,emespecialpois
oestudantenoconseguedistinguirexatamenteoqueimportanteaprenderereternaquele
momentodaquiloquesernecessriomaistempoeprincipalmente,experinciaparadominar.
Seumaclasseabstratadeveounoteraomenosummtodoabstrato,seoifsaceitar
argumentos booleanos e todos os detalhes de classes internas realmente no devem ser
preocupaes para aquele que possui como objetivo primrio aprender Java. Esse tipo de
informaoseradquiridacomotempoenonecessriaatumsegundomomento.

Nestecursoseparamosessasinformaesemquadrosespeciais,jquesoinformaes
extras.Ouentoapenascitamosnumexerccioedeixamosparaoleitorprocurarinformaesse
fordeseuinteresse.
Algumasinformaesnosomostradasepodemseradquiridasemtutoriaisouguiasde
referncia, normalmente so detalhes que para um programador experiente em Java algo
importante.
Por fim falta mencionar sobre a prtica, que deve ser tratada seriamente: todos os
exercciossomuitoimportanteseosdesafiospodemserfeitosquandoocursoacabar.De
qualquer maneira recomendamos aos alunos estudar em casa, principalmente aqueles que
fazemoscursosintensivos.

Ocurso
ParaaquelesqueestofazendoocursoJavaparadesenvolvimentoWeb,recomendadoestudar
emcasaaquiloquefoivistoduranteaaula,tentandoresolverosexercciosquenoforamfeitose
osdesafiosqueestolparaenvolvermaisoleitornomundodeJava.

ConvenesdeCdigo
ParamaisinformaessobreasconvenesdecdigofonteJava,acesse:
http://java.sun.com/docs/codeconv/

1.2 - Sobre os exerccios


Os exerccios do curso variam entre prticos at pesquisas na Internet, ou mesmo

Captulo1ComoaprenderJavaPgina1

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

consultas sobre assuntos avanados em determinados tpicos para incitar a curiosidade do


aprendiznatecnologia.
Existemtambm,emdeterminadoscaptulos,umasriededesafios.Elesfocammaisno
problemacomputacionalquenalinguagem,pormsoumaexcelenteformadetreinarasintaxe
e principalmente familiarizar o aluno com a biblioteca padro Java, alm de o aluno ganhar
velocidadederaciocnio.

1.3 - Tirando dvidas


Paratirardvidasdosexerccios,oudeJavaemgeral,recomendamosofrumdositedo
GUJ(www.guj.com.br),ondesuadvidaserrespondidaprontamente.
Sevocjparticipadeumgrupodeusuriosjavaoualgumalistadediscusso,podetirar
suasdvidasnosdoislugares.
Fora isso, sintase a vontade de entrar em contato conosco para tirar todas as suas
dvidasduranteocurso.

1.4 - Sobre o curso


ACaelum(http://www.caelum.com.br)ofereceoscursoseaapostila"FalandoemJava",
queabordaoensinodessalinguagemetecnologiadeformamaissimpleseprticadoqueem
outroscursos,poupandooalunodeassuntosquenosodeseuinteresseemdeterminadas
fasesdoseuaprendizado.
As apostilas "Falando em Java" esto parcialmente disponveis no site
http://www.caelum.com.br/fj.jsp.
Se voc possui alguma colaborao, como correo de erros, sugestes, novos
exerccioseoutros,entreemcontatoconosco!

1.5 - Sobre os autores


GuilhermeSilveira (guilherme.silveira@caelum.com.br)programadorewebdeveloper
certificadopelaSun,trabalhandocomJavadesde2000comoespecialistaeinstrutor.Programou
earquiteturouprojetosnaAlemanhadurante2anos.CofundadordoGUJ,escreveparaarevista
MundoJava,estudaMatemticaAplicadanaUSPeinstrutoreconsultornaCaelum.Umdos
comittersdoCodehausXStream.
PauloSilveira(paulo.silveira@caelum.com.br)programadoredesenvolvedorcertificado
Java. Possui grande experincia em desenvolvimento web, trabalhando em projetos na
AlemanhaeemdiversasconsultoriasnoBrasil.FoiinstrutorJavapelaSun,cofundadordo
GUJeformadoemcinciadacomputaopelaUSP,onderealizaseumestrado.umdos
editorestcnicosdarevistaMundoJava.
SrgioLopes (sergio.lopes@caelum.com.br)BacharelandoemCinciadaComputao
naUSPedesenvolvedorJavadesde2002.programadorcertificadoJavapelaSun,moderador
do GUJ e colaborador da revista Mundo Java. Trabalha com Java para Web e dispositivos
mveis,almdeministrartreinamentosnaCaelum.
Inmerasmodificaesesugestesforamrealizadasporoutrosconsultoreseinstrutores
daCaelum,emespecialAlexandredaSilva,FbioKungeThadeuRusso.

Captulo1ComoaprenderJavaPgina2

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Diversos screenshots, remodelamentos e melhorias nos textos foram realizados por


GuilhermeMoreiraeJacquelineRodrigues.
Agrecimentosatodasaspessoasquecostumamenviarerros,bugsesugestesparaa
equipe.

Captulo1ComoaprenderJavaPgina3

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

JDBC java.sql

O medo o pai da moralidade


FriedrichWilhelmNietzsche

Aotrminodessecaptulo,vocsercapazde:
conectarseaumbancodedadosqualqueratravsdaapijava.sql;
criarumafbricadeconexesusandoodesignpatternFactory;
pesquisardadosatravsdequeries;
executarcomandosnobancodedados;
DAODataAccessObject.

2.1 - Executando o eclipse pela primeira vez


1)Abraoterminaledigite:eclipseweb.
2)EscolhaWorkbench.

Captulo2JDBCjava.sqlPgina4

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

2.2 - Criando nosso projeto no eclipse


1)Crieumprojetonoeclipsechamadojdbceselecioneobotoparaseparardiretriosde
entradaesada.

Captulo2JDBCjava.sqlPgina5

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

2)CliqueemFinish.

2.3 - O banco
BANCO DE
DADOS

O banco de dados onde guardamos os dados que pertencem ao nosso sistema. A


maioriadosbancodedadoscomerciaishojeemdiasorelacionaisederivamdeumaestrutura
diferentedaquelaorientadaaobjetos.
O MYSQL o banco de dados que usamos para nossos exemplos, portanto iremos
utilizaroseguintecomandonoseuterminalparaacessaromesmo:

mysqluroot

Bancodedados
Paraaquelesquenoconhecemumbancodedados,recomendadolermaissobreomesmoe
SQLparacomearausaraapiJDBC.
O processo de armazenagem e captura de dados em um banco chamado de
Captulo2JDBCjava.sqlPgina6

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


PERSISTNCI
A

persistncia.AbibliotecapadrodepersistnciaembancodedadosemJavaaJDBCmas
jexistemdiversosprojetosdotipo ORM (ObjectRelationalMapping)quesolucionammuitos
problemasqueaestruturadaapidoJDBC(eODBC)gerou.

2.4 - Sockets: uma idia inocente


Para se conectar a umbancode dados, aprimeira idia, simples em sua formamas
complexa em sua implementao, a de abrir sockets diretamente com o banco de dados
desejado, por exemplo um Oracle, e se comunicar com o mesmo atravs de seu protocolo
proprietrioenosSQL.
Masvocconheceoprotocoloproprietriodealgumbancodedados?
Devido a natureza complexa desses protocolos, seria muito mais simples se existisse
algumemJavacomquemnossoprogramafossecapazdesecomunicaremJavaeelese
comunicassecomobancoemumprotocoloqualquer,alheioaonossoprograma.

2.5 - A conexo em Java


OsistemadesenvolvidoemJavaabstraiomtodoatravsdoqualpossvelfazeruma
conexopoisasconexessofeitasatravsdeuma
Cliente
ponte queimplementa todas as funcionalidades que
umbancodedadospadrodevenosfornecer.
InterfaceJDBC

Por exemplo, toda conexo deve permitir


executarcdigodeatualizao,pesquisa,etc.

ImplementaoJDBC.Qual?

Essa implementao precisa ser escolhida.


Essa escolha no feita programaticamente e sim
bastausarumaponte.
BD

Veja no esquema ao lado a ponte


(implementao)entreoprograma(cliente)eobanco
dedados.

O servio de encontrar uma ponte, ou seja, um driver certo delegado para um


controlador de drivers. Um gerente de drivers. Nada mais normal que ele se chame
DriverManager.

DRIVERMANAG
ER

Atravsdele,possvelchamarummtodo getConnection comumaurlqueindica


qualobancoquedesejoabrir.
O padro da url para o driver do
mysqlqueiremosutilizar:

DriverManager.getConnection("jdbc:mysql://localhost/teste");
Cliente

jdbc:mysql://ip/banco
Devemos substituir ip pelo ip da
mquinae banco pelonomedobancoa
serutilizado.
Seguindooexemplodalinhaacima
e tudo que foi dito at agora, possvel
rodar o exemplo abaixo e receber uma

InterfaceJDBC
ImplementaoJDBC.MySQL

DriverManagerprocura
poralgumdeseus
Driversqueaceiteessa
URLcomoparmetro.

MySQL

Captulo2JDBCjava.sqlPgina7

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

conexoparaumbancomysqlnaprpriamquina....
packagebr.com.caelum.jdbc;

//importsaqui(ctrl+shift+o)
publicclassJDBCExemplo{
publicstaticvoidmain(String[]args){
try{
Connectioncon=

DriverManager.getConnection("jdbc:mysql://localhost/teste");
System.out.println("Conectado!");
con.close();
}catch(SQLExceptione){
e.printStackTrace();
}
}
}

Masaotestarocdigoacima,nadafunciona.Aconexonopodeseraberta.Porque?
O sistema ainda no consegue
descobrir qual implementao do JDBC
deveserusadoparaaURLmencionada.
O primeiro passo adicionar a
implementao ao classpath: o arquivo
jarcontendoaimplementaodomysql
(mysql
connector) precisa ser
colocado em um lugar visvel ou
adicionado varivel de ambiente
classpath.

AvisandooDriverManagersobre
aexistnciadeumDriverparaoMySQL

Driversconhecidos

SQLServer

DriverManager

Oracle

MySQL

Class.forName("com.mysql.jdbc.Driver");

Aindafaltaregistrarodriverdomysqlnosistema.Paraissobastacarregareleatravsdo
mtodo Class.forName(). Esse mtodo abre uma classe que se registra com o
DriverManager.getConnection().
packagebr.com.caelum.jdbc;

//importsaqui(ctrl+shift+o)
publicclassJDBCExemplo{
publicstaticvoidmain(String[]args){
try{
Class.forName("com.mysql.jdbc.Driver");
Connectioncon=

DriverManager.getConnection("jdbc:mysql://localhost/teste",root,);
System.out.println("Conectado!");
con.close();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}catch(SQLExceptione){
e.printStackTrace();
}
}
}

Alterandoobancodedados
Captulo2JDBCjava.sqlPgina8

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

TeoricamentebastaalterarasduasStringsqueescrevemosparamudardeumbancoparaoutro.
Pormnotudotosimplesassim,ocdigosqlqueveremosaseguirpodefuncionaremum
bancomasnoemoutro.Dependedequalpadrosqlobancosuporta.
Issoscausadordecabeaeexistemcertosarcabouosqueresolvemissofacilmente,comoo
casodoHibernate(www.hibernate.org)edoPrevayler.

Listadedrivers
Osdriverspodemserbaixadosnormalmentenositedovendedordobancodedados.
Alguns casos, como no MSSQL, existem outros grupos que desenvolvem o driver em
jtds.sourceforge.net
Enquanto isso, voc pode achar o driver do MYSQL (chamado de mysql connector) no site
www.mysql.org.

2.6 - Fbrica de Conexes


Em determinado momento de nossa aplicao, gostaramos de ter o controle sobre a
construodosobjetosdanossaclasse.Muitacoisapodeserfeitaatravsdoconstrutor,como
saberquantosobjetosforaminstanciadosoufazerologsobreessasinstanciaes.
Asvezestambmqueremoscontrolarumprocessomuitorepetitivoetrabalhoso,como
abrirumaconexocomobancodedados.

2.7 - Fbrica de Conexes facilitando o acesso ao banco


Tomemoscomoexemploaclasseaseguirqueseriaresponsvelporabrirumaconexo
comobanco:
packagebr.com.caelum.jdbc;

//importsaqui(ctrl+shift+o)
publicclassConnectionFactory{
publicstaticConnectiongetConnection()throwsSQLException{
try{
Class.forName("jdbc:mysql://localhost/teste");
returnDriverManager.getConnection("com.mysql.jdbc.Driver",
"root","");
}catch(ClassNotFoundExceptione){
thrownewSQLException(e.getMessage());
}
}
}

Poderamoscolocarumavisonanossaaplicao,notificandotodososprogramadoresa
adquirirumaconexo:
Connectioncon=ConnectionFactory.getConnection();

PodemosperceberqueomtodoabreConexaoumafbricadeconexes,isto,ele
fabricaconexesparans,noimportandodeondeelasvieram.Portanto,nadamaisnaturaldo
quechamaraclassedeConnectionFactoryeomtododegetConnection.

2.8 - Exerccios

Captulo2JDBCjava.sqlPgina9

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

1)Copieodriverdomysqlparaoseuprojeto.
a)entrenoFileBrowser;
b)procureodiretriocaelum;
c)cliquedadireitanodriverdomysql,escolhaCopy;
d)volteparaodiretrioanterior;
e)entrenodiretrioworkspace,jdbc;
f)cliquedadireitaeescolhaPaste:vocacabadecolocaroarquivo.jarnoseuprojeto.
2)CrieumaclassechamadaConnectionFactoryquefabricaconexes.
a)crieanopacotebr.com.caelum.jdbc
b)crieomtodoestticogetConnectionqueretornaumanovaconexo:
publicstaticConnectiongetConnection()throwsSQLException{
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println(Conectandoaobanco);
returnDriverManager.getConnection("jdbc:mysql://localhost/teste",
"root","");
}catch(ClassNotFoundExceptione){
thrownewSQLException(e.getMessage());
}
}

3)CrieumaclassechamadaTestaConexaonopacotebr.com.caelum.jdbc.teste
a)coloqueomtodomain
publicstaticvoidmain(String[]args){...

b)fabriqueumaconexo:
Connectioncon=ConnectionFactory.getConnection();

c)fecheaconexo
con.close();

d)Trateoserroscomthrows.(Use:Ctrl+1eescolhaaddthrowsdeclaration).
4)RodeasuaclasseTestaConexao
a)CliquedadireitanasuaclasseTestaConexao
b)EscolhaRunas,JavaApplication
5)Parecequesuaaplicaonofuncionapoisodrivernofoiencontrado?Esquecemos
decolocarojarnoclasspath!(buildpathnoeclipse)
a)Cliquenoseuprojeto,pressioneF5paraexecutarumRefresh.
b)Selecioneoseudriverdomysql,cliquedadireitaeescolhaBuildPath,AddtoBuild
Captulo2JDBCjava.sqlPgina10

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Path.
c) Rode novamente sua aplicao TestaConexao agora que colocamos o driver no
classpath.

2.9 - A tabela de exemplo


Paracriarumatabelanova,devemosrodarocomandomysqlparaentrarnomesmo.
mysqluroot

Agoranospreparamosparausarobancodedadosteste:
useteste;

Aseguintetabelaserusadanosexemplosdessecaptulo:
createtablecontatos(
idBIGINTNOTNULLAUTO_INCREMENT,
nomeVARCHAR(255),
emailVARCHAR(255),
enderecoVARCHAR(255),
primarykey(id)
);

Nobancodedadosrelacional,comumrepresentarumcontato(entidade)emumatabela
decontatos.

2.10 - Javabeans
O que so Javabeans?A pergunta que noquer secalar podeser respondida muito
facilmenteumavezqueamaiorconfusofeitaaforaentre JavabeanseEnterpriseJava
Beans(EJB).
JAVABEANS

Javabeans so classes que possuem o construtor sem argumentos e mtodos de


acessodotipogeteset!Maisnada!Simplesno?
JosEJBssojavabeanscomcaractersticasmaisavanadasesooassuntoprincipal
docursoFJ31daCaelum.
Podemosusarbeanspordiversosmotivos,normalmenteasclassesdemodelodanossa
aplicaocostumamserjavabeans.
Agorairemosutilizar:

umaclassecommtodosdotipogetesetparacadaumdeseusparmetros,querepresenta
algumobjeto
umaclassecomconstrutorsemargumentosquerepresentaumacoleodeobjetos

Aseguir,vocvumexemplodeumaclassejavabeanqueseriaequivalenteaonosso
modelodeentidadedobancodedados:
packagebr.com.caelum.jdbc.modelo;
publicclassContato{

Captulo2JDBCjava.sqlPgina11

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


privateLongid;
privateStringnome;
privateStringemail;
privateStringendereco;

//mtodosgetesetparaid,nome,emaileendereo
publicStringgetNome(){
returnthis.nome;
}
publicvoidsetNome(Stringnovo){
this.nome=novo;
}
publicStringgetEmail(){
returnthis.email;
}
publicvoidsetEmail(Stringnovo){
this.email=novo;
}
publicStringgetEndereco(){
returnthis.endereco;
}
publicvoidsetEndereco(Stringnovo){
this.endereco=novo;
}
publicLonggetId(){
returnthis.id;
}
publicvoidsetId(Longnovo){
this.id=novo;
}
}

Atecnologiajavabeansmuitograndeemaisinformaessobreessavastareaquea
basedoscomponentesescritosemjavapodeserencontradaem:
http://java.sun.com/products/javabeans
SevocquersabermaissobreEnterpriseJavaBeans(EJB),aCaelumofereceocurso
FJ31,noosconfundacomJavaBeans!

2.11 - Exerccios
1)CrieaclassedeContato.
a)Nopacotebr.com.caelum.jdbc.modelo,crieumaclassechamadaContato.
packagebr.com.caelum.jdbc.modelo;
publicclassContato{
privateLongid;
privateStringnome;
privateStringemail;
privateStringendereco;
}

b)VnomenuSource,Generategettersesetterseselecionetodososgettersesetters.

Captulo2JDBCjava.sqlPgina12

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

2.12 - Inserindo dados


Parainserirdadosemumatabeladeumbancodedadosentidaderelacionalbastausara
clusula INSERT. Precisamos especificar quais os campos que desejamos atualizar e os
valores.
PrimeiroocdigoSQL:
1.

Stringsql="insertintocontatos(nome,email,endereco)values('"+nome+
"','"+email+"','"+endereco+"')";

Oexemploacimapossuidoispontosnegativosquesoimportantssimos.Oprimeiro
queoprogramadorquenoescreveuocdigooriginalnoconseguebateroolhoeentendero
queestescrito.Oqueocdigoacimafaz?Lendorapidamenteficadifcil.Maisdifcilainda
sabersefaltouumavrgula,umfechaparntesestalvez?
OutroproblemaoclssicopreconceitocontraJoanad'arc,formalmentechamadode
SQLInjection.Oqueacontecequandoocontatoaseradicionadopossuinonomeumaaspas
simples?Ocdigosqlsequebratodoepradefuncionarou,piorainda,ousuriofinalcapaz
dealterarseucdigosqlparaexecutaraquiloqueeledeseja(sqlinjection)...tudoissoporque
escolhemosaquelalinhadecdigoenofizemosoescapedecaracteresespeciais.
Poressesdoismotivosnoiremosusarcdigosqlcomomostradoanteriormente...vamos
imaginaralgomaisgenricoeumpoucomaisinteressante:
Stringsql="insertintocontatos(nome,email,endereco)values(?,?,?)";

ExisteumamaneiraemJavadeescreverocdigosqlcomonoprimeiroexemplodessa
seo(comcocatenaesdestrings).Essamaneiranoserensinadaduranteocursopois
umapssimaprticaquedificultaamanutenodoseuprojeto.
Perceba que no colocamos os pontos de interrogao de brincadeira, e sim porque
realmente no sabemos oque desejamos inserir. Estamos interessados emexecutar aquele
cdigomasnosabemosaindaquaissoosparmetrosqueiremosutilizarnessecdigosql
queserexecutado,chamadodestatement.
PREPARED
STATEMENT

As clusulas so executadas em um banco de dados atravs da interface


PreparedStatement.ParareceberumPreparedStatementrelativoconexo,bastachamaro
mtodoprepareStatement,passandocomoargumentoocomandoSQLcomosvaloresvindos
devariveispreenchidoscomumainterrogao.

PreparedStatementstmt=con.prepareStatement("insertintocontatos
(nome,email,endereco)values(?,?,?)");

Logoemseguida,chamamosomtodosetStringdoPreparedStatementparapreencher
osvalores,passandoaposio(comeandoem1)dainterrogaonoSQLeovalorquedeve
sercolocado.
//preencheosvalores
stmt.setString(1,Caelum);
stmt.setString(2,contato@caelum.com.br);
stmt.setString(3,R.Vergueiro3185cj57);

Porfim,umachamadaexecuteexecutaocomandoSQL.
stmt.execute();

Agora imaginetodo esse processo sendo escrito todavezque desejar inserir algono
Captulo2JDBCjava.sqlPgina13

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

banco?Aindanoconseguevisualizaroquodestrutivoissopodeser?
Vejaoexemploabaixo,queabreumaconexoeinsereumcontatonobanco:
packagebr.com.caelum.jdbc;

//importsaqui
publicclassJDBCInsere{
publicstaticvoidmain(String[]args){
try{
//conectando
Connectioncon=ConnectionFactory.getConnection();
//criaumpreparedStatement
PreparedStatementstmt=con.prepareStatement("insertintocontatos
(nome,email,endereco)values(?,?,?)");

//preencheosvalores
stmt.setString(1,Caelum);
stmt.setString(2,contato@caelum.com.br);
stmt.setString(3,R.Vergueiro3185cj57);

//executa
stmt.execute();
stmt.close();
System.out.println("Gravado!");
con.close();
}catch(SQLExceptione){
e.printStackTrace();
}
}
}

Fechandoaconexo
Nocomumutilizarjdbchojeemdia.OmaispraticadoousodealgumaapideORMcomoo
HibernateouEJB,pormaquelesqueaindainsistemnousodeJDBCdevemprestaratenono
momentodefecharaconexo.
Oexemplodadoacimanofechaamesmacasoalgumerroocorranomomentodeinseriralgum
dadonobancodedados.
Ocomumfecharaconexoemumblocofinally.

Mprtica:Statement
Ao invs de usar o PreparedStatement, voc pode usar uma interface mais simples chamada
Statement,quesimplesmenteexecutaumaclusulaSQLnomtodoexecute:
Statementstmt=con.createStatement();
stmt.execute(insert into contatos (nome,email,endereco) values
('Nome','Email','Endereco'));
stmt.close();
MasprefiraaclassePreparedStatementquemaisrpidaqueStatementedeixaseucdigomuito
maislimpo.
Captulo2JDBCjava.sqlPgina14

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Geralmente,seuscomandosSQLconterovaloresvindosdevariveisdoprogramaJava;usando
Statements,vocterquefazermuitasconcatenaes,masusandoPreparedStatements,issofica
maislimpoefcil.

2.13 - Solues para viagem Design Patterns


Orientaoobjetosresolveasgrandesdoresdecabeasquetnhamosnaprogramao
procedural,restringindoecentralizandoresponsabilidades.
Masalgumascoisasnopodemossimplesmenteresolvercomorientaoobjetospois
noexistepalavrachaveparaumafuncionalidadetoespecfica.

DESIGN
PATTERNS

Algunsdessespequenosproblemasaparecemcomtamanhafreqnciaqueaspessoas
desenvolvem uma soluo padro para o mesmo. Com isso, ao nos defrontarmos com um
desses problemas clssicos, podemos rapidamente implementar essa soluo genrica com
umaououtramodificao.Essasoluopadrotemonomede Design Pattern (padro
de projeto).
A melhor maneira para aprender o que um Design Pattern vendo como surgiu a
necessidadedomesmo.

Abblia
OlivromaisconhecidodeDesignPatternsfoiescritoem1995etemtrechosdecdigoemC++e
Smalltalk.Masoquerealmenteimportasoosconceitoseosdiagramasquefazemdesselivro
independentedequalquerlinguagem.Almdetudo,olivrodeleituraagradvel.
DesignPatterns,ErichGammaetal.

2.14 - DAO Data Access Object


JfoipossvelsentirquecolocarcdigoSQLdentrodesuasclassesdelgicaalgonem
umpoucoeleganteemuitomenosvivelquandovocprecisamanteroseucdigo.
Quantasvezesvocnoficoubravocomoprogramadorresponsvelporaquelecdigo
ilegvel?
Aidiaa seguirremoverocdigodeacessoaobancodedadosdesuasclassesde
lgicaecolocloemumaclasseresponsvelpeloacessoaomesmo.Assimocdigodeacesso
aobancodedadosficaemumlugars,ficandomaisfcildarmanutenoaomesmo.
QuetalseriasepudssemoschamarummtodoadicionaqueadicionaumContatoao
banco?
Emoutraspalavrasqueroqueocdigoaseguirfuncione:
//adicionaoosdadosnobanco
Misteriobd=newMisterio();
bd.adiciona(meunome,meuemail,meuendereo);

Mas...JavaorientadoaStrings?Vamostentarnovamente:emoutraspalavrasquero
queocdigoaseguirfuncione:
//adicionaumcontatonobanco
Misteriobd=newMisterio();

Captulo2JDBCjava.sqlPgina15

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

//mtodomuitomaiselegante
bd.adiciona(contato);

Tentaremoschegaraocdigoanterior:seriamuitomelhoremaiselegantepoderchamar
umnicomtodoresponsvelpelaincluso,certo?
packagebr.com.caelum.jdbc;

//importsaqui
publicclassTestaInsere{
publicstaticvoidmain(String[]args){
try{

//prontoparagravar
Contatocontato=newContato();
contato.setNome(Caelum);
contato.setEmail(contato@caelum.com.br);
contato.setEndereco(R.Vergueiro3185cj57);
//gravenessaconexo!!!
Misteriobd=newMisterio();
//mtodoelegante
bd.adiciona(contato);
System.out.println("Gravado!");
}catch(SQLExceptione){
e.printStackTrace();
}
}
}

Ocdigoanteriorjmostraopoderqueiremosalcanar:atravsdeumanicaclasse
seremoscapazesdeacessarobancodedadose,maisainda,somenteatravsdessaclasse
serpossvelacessarosdados.
Estaidia,inocenteaprimeiravista,capazdeisolartodooacessoabancoemclasses
bem simples, cuja instncia um objeto responsvel por acessar os dados. Da
responsabilidadedesteobjetosurgiuonomedeDataAccessObjectousimplesmenteDAO,um
dosmaisfamosospadresdedesenvolvimento.

DAO

OquefaltaparaocdigoacimafuncionarumaclassechamadaContatoDAOcomum
mtodochamadoadiciona.Vamoscriarumaqueseconectaaobancoaoserconstrudauma
instnciadamesma:
publicclassContatoDAO{

//aconexocomobancodedados
privateConnectionconnection;
publicContatoDAO()throwsSQLException{
this.connection=ConnectionFactory.getConnection();
}
}

AgoraquetodoContatoDAOpossuiumaconexocomobancopodemosfocarnomtodo
adiciona, que recebe um Contato como argumento e responsvel por adicionar o mesmo
atravsdecdigosql.

Captulo2JDBCjava.sqlPgina16

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


publicvoidadiciona(Contatocontato)throwsSQLException{

//preparedstatementparainsero
PreparedStatementstmt=this.connection.prepareStatement("insertinto
contatos(nome,email,endereco)values(?,?,?)");
//setaosvalores
stmt.setString(1,contato.getNome());
stmt.setString(2,contato.getEmail());
stmt.setString(3,contato.getEndereco());
//executa
stmt.execute();
stmt.close();
}

2.15 - Exerccios
1)Crieaclassebr.com.caelum.jdbc.dao.ContatoDAO
packagebr.com.caelum.jdbc.dao;

//importsaqui(CTRL+SHIFT+O)
publicclassContatoDAO{

//aconexocomobancodedados
privateConnectionconnection;
publicContatoDAO()throwsSQLException{
this.connection=ConnectionFactory.getConnection();
}
publicvoidadiciona(Contatocontato)throwsSQLException{

//preparedstatementparainsero
PreparedStatementstmt=this.connection.prepareStatement("insertinto
contatos(nome,email,endereco)values(?,?,?)");
//setaosvalores
stmt.setString(1,contato.getNome());
stmt.setString(2,contato.getEmail());
stmt.setString(3,contato.getEndereco());
//executa
stmt.execute();
stmt.close();
}
}

2)CrieumaclassechamadaTestaInserecomummtodomain:
packagebr.com.caelum.jdbc;

//importsaqui(CTRL+SHIFT+O)
publicclassTestaInsere{
publicstaticvoidmain(String[]args)throwsSQLEXception{

//prontoparagravar
Contatocontato=newContato();
contato.setNome(Caelum);
contato.setEmail(contato@caelum.com.br);
contato.setEndereco(R.Vergueiro3185cj57);
//gravenessaconexo!!!
ContatoDAOdao=newContatoDAO();
Captulo2JDBCjava.sqlPgina17

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

//mtodoelegante
dao.adiciona(contato);
System.out.println("Gravado!");
}
}

3)Testeseuprograma.
4)Verifiqueseocontatofoiadicionado.
mysqlhlocalhosturoot
useteste;
select*fromcontatos;

2.16 - Exerccios opcionais


1)Altereseuprogramaeuseaclassejava.util.ScannerdoJava5paraleros
dadosatravsdoteclado:
//criaoScanner
Scannerteclado=newScanner(System.in);
//prontoparagravar
Contatocontato=newContato();
contato.setNome(teclado.next());
contato.setEmail(teclado.next());
contato.setEndereco(teclado.next());

2.17 - Pesquisando
Para pesquisar tambm utilizamos a interface PreparedStatement, de forma que o
mtodoexecuteQueryretornatodososcontatosnoexemploaseguir.
RESULTSET

OobjetoretornadodotipoResultSetquepermitenavegarporseusregistrosatravs
domtodonext.Essemtodoirretornarfalsequandochegaraofimdapesquisa,portantoele
normalmenteutilizadoparafazerumloopnosregistroscomonoexemploaseguir:

//pegaaconexoeoStatement
Connectioncon=ConnectionFactory.getConnection();
PreparedStatementstmt=con.prepareStatement("select*fromcontatos");
//executaumselect
ResultSetrs=stmt.executeQuery();
//iteranoResultSet
while(rs.next()){
}
rs.close();
stmt.close();
con.close();

Pararetornarovalordeumacolunanobancodedadosbastachamarumdosmtodos
getdoResultSet,dentreosquais,omaiscomum:getString.
//pegaaconexoeoStatement
Connectioncon=ConnectionFactory.getConnection();
PreparedStatementstmt=con.prepareStatement("select*fromcontatos");
Captulo2JDBCjava.sqlPgina18

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

//executaumselect
ResultSetrs=stmt.executeQuery();
//iteranoResultSet
while(rs.next()){
System.out.println(
rs.getString("nome")+"::"+rs.getString("email")
);
}
stmt.close();
con.close();

RecursoAvanado:Ocursor
Assim como o cursor do banco de dados, s possvel mover para o prximo registro. Para
permitirumprocessodeleituraparatrsnecessrioespecificarnaaberturadoResultSetquetal
cursordeveserutilizado.
Mas,novamente,podemosaplicarasidiasdeDAOecriarummtodogetLista()no
nossoContatoDAO:
PreparedStatementstmt=
this.connection.prepareStatement("select*fromcontatos");
ResultSetrs=stmt.executeQuery();
List<Contato>contatos=newArrayList<Contato>();
while(rs.next()){

//criandooobjetoContato
Contatocontato=newContato();
contato.setNome(rs.getString(nome));
contato.setEmail(rs.getString(email));
contato.setEndereco(rs.getString(endereco));
//adicionandooobjetolista
contatos.add(contato);
}

rs.close();
stmt.close();
returncontatos;

2.18 - Exerccios
1)CrieomtodogetListanaclasseContatoDAO.
publicList<Contato>getLista()throwsSQLException{
PreparedStatementstmt=
this.connection.prepareStatement("select*fromcontatos");
ResultSetrs=stmt.executeQuery();
List<Contato>contatos=newArrayList<Contato>();
while(rs.next()){
//criandooobjetoContato
Contatocontato=newContato();
contato.setNome(rs.getString(nome));
contato.setEmail(rs.getString(email));
contato.setEndereco(rs.getString(endereco));

Captulo2JDBCjava.sqlPgina19

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

//adicionandooobjetolista
contatos.add(contato);
}

rs.close();
stmt.close();
returncontatos;
}

2)VamosusaromtodogetListaagoraparalistartodososcontatosdonossobancode
dados.
3)CrieumaclassechamadaTestaListaDAOcomummtodomain:
a)CrieumContatoDAO:
ContatoDAOdao=newContatoDAO();

b)ListeoscontatoscomoDAO:
List<Contato>contatos=dao.getLista();

c)Iterenessalistaeimprimaasinformaesdoscontatos:
for(Contatocontato:contatos){
System.out.println(Nome:+contato.getNome());
System.out.println(Email:+contato.getEmail());
System.out.println(Endereo:+contato.getEndereco()+\n);
}

4)Rodeoprogramaanteriorclicandodadireitanomesmo,Run,RunasJavaApplication.

2.19 - Um pouco mais...


1)AssimcomooMYSQLexistemoutrosbancosdedadosgratuitoseopensourcena
internet. O HSQLDB um banco desenvolvido em Java que pode ser acoplado a qualquer
aplicao e libera o cliente da necessidade de baixar qualquer banco de dados antes da
instalaodeumprodutoJava!
2)OHibernatetomoucontadomercadoeviroufebremundialpoisnosefaznecessrio
escreverumalinhadecdigoSQL!
3)OutrosprojetoscomooHibernatesobastantefamososcomooOJBeoTorque,cada
umcomsuasprpriascaractersticasimplementandoafuncionalidadedeORM.
4)OPrevayler,iniciativabrasileira,funcionacomoumacamadadeprevalnciadeseus
objetos,deumamaneiramuitodiferentedeumaferramentadeORMconvencional.
5)SeumprojetonousanenhumadastecnologiasdeORMdisponveis,omnimoaser
feitoseguiroDAO.

2.20 - Exerccios opcionais


1) Use clusulas where para refinar sua pesquisa no banco de dados. Por exemplo:
wherenomelike'C%'
2)Crieomtodopesquisarquerecebeumid(int)eretornaumobjetodotipoContato.

Captulo2JDBCjava.sqlPgina20

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)UseaclassedeDAOparaprocurareremovercontatosdobancodedados.

2.21 - Desafios
1)Faaconexesparaoutrostiposdebancodedadosdisponveis.

2.22 - Exerccios opcionais


AgoraquevocjsabeusaroPreparedStatementparaexecutarqualquertipodecdigo
sqleResultSetparareceberosdadosretornadosdasuapesquisaficasimples,pormmaante,
escreverocdigodediferentesmtodosdeumaclassetpicadeDao.
Vejaprimeiroomtodoaltera,querecebeumcontatocujosvaloresdevemseralterados:
1.
2.
3.
4.
5.
6.
7.
8.
9.

publicvoidaltera(Contatocontato)throwsSQLException{
PreparedStatementstmt=connection.prepareStatement("updatecontatosset
nome=?,email=?,endereco=?whereid=?");
stmt.setString(1,contato.getNome());
stmt.setString(2,contato.getEmail());
stmt.setString(3,contato.getEndereco());
stmt.setLong(4,contato.getId());
stmt.execute();
stmt.close();
}

Noexistenadadenovonaslinhasacima.Umaexecuodequery!Simples,no?
Agoraocdigopararemoo:comeacomumaquerybaseadaemumcontato,masusa
somenteoiddeleparaexecutaraquerydotipodelete:
1. publicvoidremove(Contatocontato)throwsSQLException{
2.
PreparedStatementstmt=connection.prepareStatement("deletefrom
contatoswhereid=?");
3.
stmt.setLong(1,contato.getId());
4.
stmt.execute();
5.
stmt.close();

6. }

2.23 - Exerccios opcionais


1)AdicioneomtodoparaalterarcontatonoseuContatoDAO.
publicvoidaltera(Contatocontato)throwsSQLException{
PreparedStatementstmt=connection.prepareStatement("updatecontatosset
nome=?,email=?,endereco=?whereid=?");
stmt.setString(1,contato.getNome());
stmt.setString(2,contato.getEmail());
stmt.setString(3,contato.getEndereco());
stmt.setLong(4,contato.getId());
stmt.execute();
stmt.close();
}

2)AdicioneomtodopararemovercontatonoseuContatoDAO.
publicvoidremove(Contatocontato)throwsSQLException{
PreparedStatementstmt=connection.prepareStatement("deletefromcontatos
whereid=?");
stmt.setLong(1,contato.getId());
stmt.execute();
stmt.close();

}
Captulo2JDBCjava.sqlPgina21

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)Useosmtodoscriadosanteriormenteparafazertestescomoseubancodedados:
atualizeeremovaumcontato.
4)CrieumaclassechamadaFuncionariocomoscamposid(Long), nome,usuarioe
senha(String).
5)Crieumatabelanobancodedados.
6)CrieumaclassedotipoDAO.
7)Useaparainstanciarnovosfuncionriosecoloclosnoseubanco.

Captulo2JDBCjava.sqlPgina22

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

O que o JEE?

Ensinar aprender duas vezes.


JosephJoubert

OqueoJavaEnterpriseEdition?
Servidordeaplicao
ServletContiner
Implementaodereferncia

3.1 - As especificaes
OJEE(JavaEnterpriseEditionouJavaEE)nopassadeumasriedeespecificaes
bemdetalhadas,dandoumareceitadecomodeveserimplementadoumsoftwarequefazum
determinadoservio.
Veremosnocursoosvriosserviosqueumsoftwaredeveimplementarparaseguiras
especificaes do JEE. Veremos tambm conceitos muito importantes, para depois firmar
jargescomoservidor de aplicaoecontiners.
Essesserviosvariamdesdeenviodeemails,atcomplexosserviosdetransao.
PorqueaSunfazisso?Aidiaquevocpossacriarumaaplicaoqueutilizeesses
servios.Comoessesserviossobemcomplicados,vocnoperdertempoimplementando
essapartedosistema,pormterdecomprardealgum(existemimplementaesgratuitasde
excelentequalidade).
Algum dia, voc poder querer trocar essa implementao atual por uma que mais
rpidaemdeterminadospontos(econseqentementemaiscara).Pormcontinuarutilizandoa
mesmainterface,isto,comovocchamaaquelasfuncionalidadesdoJavaEE.Oquemudaa
implementao da especificao,voctemessaliberdade,no est preso a umcdigo ea
especificaogarantequesuaaplicaofuncionarcomaimplementaodeoutraempresa.

Ondeencontrarasespecificaes.
OgruporesponsvelporgerirasespecificaesusaositedoJavaCommunityProcess:
http://www.jcp.org/
Lvocpodeencontrartudosobreas JavaSpecificationRequests,isto,osnovospedidosde
bibliotecaseespecificaesparaoJava,tantoparaJSE,quantoEEeoutros.
SobreoJEE,vocpodeencontrarem:
http://java.sun.com/javaee/

3.2 - APIs
Captulo3OqueoJEE?Pgina23

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

AsAPIsaseguirsoasprincipaisdentreasdisponibilizadaspeloJavaEnterpriseEdition
atravsdesuaespecificaoemsuaverso5:

JavaAPIforXMLBasedRPC(JAXRPC),JavaAPIforXMLRegistries(JAXR)
(trabalharcomarquivosxml)

JavaServerPages(JSP),JavaServlets,JavaServerFaces(JSF)
(trabalharparaaweb)

EnterpriseJavabeansComponents(EJB)eJavaPersistenceApi
(objetosdistribudos,clusters,acessoremotoaobjetosetc)

JavaManagementExtensions(JMX)
(administraodasuaaplicaoeestatsticassobreamesma)

JavaTransactionAPI(JTA)
(controledetransaonocontiner)

JavaMessageService(JMS)
(trocademensagenssncronasouno)

JavaNamingandDirectoryInterface(JNDI)
(espaodenomeseobjetos)
EntreoutrasparatrabalharcomWebserviceseoutrostiposdeacessoremotoouinvocao
remotademtodos(RMI).

3.3 - Referncia de Implementao


Existe um grande download do Java EE na pgina da Sun. Se o Java EE uma
especificao,oqueprecisopegar?
Nessedownloadvocteradocumentao,ummontedejarsondeficamasinterfaces
quesoimplementadaspelasempresas(vendors),ferramentaseoutros.Reparequeaquino
vemaVirtualMachine,compiladoreocontedodoJavaStandardEdition.JavaEEprecisado
JavaStandardEditionsevocquiserdesenvolver.
REFERNCIA
O que realmente ocupa muito espao a RI - Reference Implementation
DE
(Refernciadeimplementao,ouJavaEERI).ComoasespecificaesdoJavaEEnoso
IMPLEMENTA
muitosimples,eaSunprecisatestlasparaversetudodenecessrioseencontraporl,a
O

prpriaSundesenvolveumaimplementaoquevemjuntocomoJavaEE,apenasparatestes
dosusurios.
VocpodeusaraRInoseuambientedetrabalho,masvaleapenalembrarqueelano
rpida,enemtemfacilidadesdeusonahoradainstalao,criaodeumanovaaplicaoe
outros.
OutrautilidadedaRIparaqueasempresasquedesejamvenderseuprprioproduto,
possamtirardvidasdecasosemqueaespecificaonotenhasidomuitoclara,testandoesse
casonaRI.

BaixandoaJavaEE
http://java.sun.com/javaee
Altimaversoa5.Cuidadoaofazerodownloadpoisexisteumaversoquetambmvemtodo
Captulo3OqueoJEE?Pgina24

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

oJavaStandardEdition.

3.4 - Implementaes compatveis com a especificao


Existemdiversosservidoresdeaplicaofamososcompatveiscomaespecificaodo
Java EE 1.4, abaixo listamos alguns dos mais famosos. Lembrese que a verso 5 muito
recente e as empresas demoram para criar servidores que do suporte a nova verso da
tecnologia.
Do grupo a seguir, o Jboss se destaca como o primeiro a implementar essas novas
especificaes.
2.

Apache,ApacheGeronimo,gratuito

3.

BEA,BEAWeblogicServer

4.

IBM,IBMWebsphereApplicationServer

5.

Jboss,JbossApplicationServer,gratuito

6.

Objectweb,ObjectwebJonas,gratuito

7.

Oracle,OracleApplicationServer

8.

Sun,SunJavaSystemApplicationServerPlatform

3.5 - Apache?
OgrupoApachepossuiumservidorweb,umservletcontinereumservidordeaplicao,
cuidadoparanochamartudodeApacheenosaberdequalestfalando.
OservidorwebsechamaApacheHttpd,oservletcontinersechamaApacheTomcateo
servidordeaplicaoApacheGeronimo.

Captulo3OqueoJEE?Pgina25

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

Servlet Continer

Que ningum se engane: s se consegue a simplicidade atravs


de muito trabalho.
ClariceLispector

Oqueecomofuncionaumservletcontiner.

4.1 - Introduo
Nocomeo,aInterneteraumadziadepginasestticascontendositesdepesquisade
diversasacademias.
Danecessidadedegerarcontedodinmicocomoosprimeiroscontadores,umaidia
bem simples hoje em dia, surgiram os primeiros programas de CGI (Common Gateway
Interface).
AtravsdelinguagenscomoC,C++,Perl,ASP,PHP, Cobol,Delphi,Shelletc,foi
possvelgerarcontedoquepermiteaousurioacessodiversasfuncionalidadesatravsde
pginasHTML,comoquandovocdesejacomprarprodutosemumalojavirtual.
Paramelhorarodesempenhodoltimo,inventaramoqueviriaaserumaservlet,uma
nova forma de trabalhar com requisies de clientes via web que economiza o tempo de
processamentodeumachamadaeamemriaqueseriagastaparatalprocesso,almdeserem
Javaepossuirtodasasvantagensefacilidadesdeorientaoaobjeto.
Almdomais,servletssoportveistantoquantoqualquerprogramaescritoemJava,e
aqueles que programam servlets no precisam mais se preocupar com a funcionalidade do
servidor,quejfoiescritaparansenoprecisaseralterada.

HTML
EstecursotemcomoprrequisitooconhecimentodeHTML:saberutilizarastagsprincipaispara
aconstruodepginasdinmicas(html,body,form,input,textareaeselect).
CasonoestejaacostumadocompginasHTML,recomendasequetenteleralgumtutorialpara
quenoapareamdificuldadesduranteocurso.
Embreveestudaremosasservlets,masantesveremosoJSP(JavaServerPages),que
comoescrevemosamaiorpartedenossaspginasdinmicasemJava.

4.2 - Servlet Continer


CONTINER

Ocontinerocomponenteresponsvelpordarsuporteparaasapisdeservletejsp.

4.3 - Tipos de continer


Captulo4ServletContinerPgina26

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Os3tiposmaiscomumdeinstalaodeservletcontinersewebserverssomostrados
nogrfico.
Clientes

Webserver+
Servlet
Continerjuntos
Tipo1

Webserver
ServletContiner
Tipo2

Webserver
ServletContiner
Tipo3

Noprimeiro,todasasrequisiesvodiretoparaowebserver,quetambmocontiner.
No tipo dois, o webserver usa o continer como um plugin e envia as requisies
pertinentes ao mesmo, enquanto, no tipo trs, as requisies so feitas diretamente ao
webserverouaocontiner.
OJEE5compostopelasseguintesespecificaesligadasaumaaplicaoweb:
JSP
Servlets
JSTL
JSF

Tomcat
Baixeotomcatemhttp://tomcat.apache.orgnolinkdedownloadbinaries.
OTomcatvirouimplementaopadroerefernciadenovasapisdeservlets,isto,quandouma
novaespecificaosurge,otomcatcostumaseroprimeiroservletcontineraimplementaranova
api.

4.4 - Instalando o tomcat


ParainstalaroTomcatnaCaelum,sigaosseguintespassos:
1)AbraoFileBrowser.
2)Entrenoatalhocaelum.
3)Selecioneoarquivodoapachetomcat.
4)CliquedadireitaescolhaExtractto.

Captulo4ServletContinerPgina27

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

5)Escolhaasuapastaprincipal:HomeeselecioneExtract.

6)Oresultadoumapastachamadaapachetomcat:otomcatjestinstalado.

Captulo4ServletContinerPgina28

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

4.5 - Em casa: iniciando o tomcat


Entrenodiretriodeinstalaoerodeoprogramastartup.sh:
cdapachetomcat<TAB>/bin
./startup.sh

4.6 - Em casa: parando o tomcat


Entrenodiretriodeinstalaodotomcaterodeoprogramashutdown.sh:
cdapachetomcat<TAB>/bin
./shutdown.sh

4.7 - O tomcat no windows


Parainstalarotomcatnowindowsbastaexecutaroarquivo.exequepodeserbaixadono
sitedotomcat.Depoisdissovocpodeusarosscriptsstartup.bateshutdown.bat,analogamente
aosscriptsdolinux.
Tudooquevamosdesenvolvernestecursofuncionaemqualquerambientecompatvel
comoJavaEnterpriseEdition.

Captulo4ServletContinerPgina29

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

O eclipse e seus plugins


O repouso uma boa coisa mas o tdio seu irmo.
Voltaire(FranoisMarieArouet)

Nestecaptulovociraprendera:
instalaropluginparajspdogrupoAmateras
instalaropluginparaotomcatdaSysdeo
configurarosdoispluginsparasuainstalao

5.1 - Os plugins Sysdeo e Amateras


IremosutilizaroplugindoAmaterasparavisualizarcdigohtmldeumamaneiramais
elegante(colorida).
JoplugindaSysdeoparaoTomcatoresponsvelporligaredesligaromesmo.

5.2 - Configurando o plugin do amateras no eclipse


Iremos configurar o Amateras para no utilizar o preview, uma vez que essa
funcionalidadenofuncionanoLinuxcomdeterminadasversesdoFirefox.
VnomenuWindow,Preferences,Amateras:

Captulo5OeclipseeseuspluginsPgina30

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

EscolhaaopoDisablePreview.
InfelizmenteaversodoFirefoxnoLinuxqueusamosnocompatvelcomoplugindo
grupoAmateraseportantonopermitequevisualizemososjsp'samedidaqueescrevemosele.
Sendo assim, tanto no windows quanto em verses anteriores do Firefox no Linux, o
plugincapazdemostrarumpreviewdojsp.

5.3 - Configurando o plugin do tomcat no eclipse


VnomenuWindow,Preferences,Tomcat:
1)Selecioneaverso5.xdotomcat.
2)Selecionetomcathomeecoloqueodiretrioondeinstalouotomcat.

Captulo5OeclipseeseuspluginsPgina31

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)Apliqueasalteraes.

4)Cliquenobotodotomcatqueestnabarradeferramentas.

5)Abraoseubrowseretenteacessar:http://localhost:8080

Captulo5OeclipseeseuspluginsPgina32

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

5.4 - Em casa: Instalando o eclipse


1)Baixeoeclipsenapginawww.eclipse.org.
2)Descompacteoarquivoepronto.

5.5 - Em casa: Instalando o plugin para o tomcat


Um dos plugins mais simples e famosos o plugin para tomcat desenvolvido pela
empresafrancesaSysdeo.Ositeoficial:
1)http://www.sysdeo.com/eclipse/tomcatplugin
2)BaixeoarquivotomcatPluginV31beta.zip.
3)Descompacteocontedodessezipnodentrododiretriopluginsondevocinstalouo
eclipse. Por exemplo, se voc instalou o eclipse em c:\eclipse, descompacte o arquivo em
c:\eclipse\plugins.

5.6 - Em casa: Instalando o plugin para arquivos jsp, html e xml


Iremosutilizaroplugindaamaterasparadarsuporteaosarquivosdotipojsp,htmlexml.
O siteoficialdoplugino http://amateras.sourceforge.jp/ eiremos utilizaropluginchamado
EclipseHtmlEditor.
UmprrequisitoparaoEclipseHtmlEditoroGEFdoprprioprojetoEclipse.Olinko
prpriositedoEclipse,DownloadseentoGEF.Baixeaversorelativaaoseueclipse(por
exemplo3.1.1).
Captulo5OeclipseeseuspluginsPgina33

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Para instalar o EclipseHtmlEditor basta descompactar o arquivo dentro do diretrio


c:\eclipse\pluginsjoGEFnodiretrioc:\eclipse.

5.7 - Plugins do eclipse no windows


Nowindowsexisteumanicadiferena:inicieoeclipsecomaopocleantodavezque
vocinstalarumnovoplugin.

Captulo5OeclipseeseuspluginsPgina34

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

Novo projeto web

So muitos os que usam a rgua, mas poucos os inspirados.


Plato

Nessecaptulo,vocaprender:
acriarumnovoprojetowebnoeclipse;
quaissoosdiretriosimportantesdeumaaplicaoweb;
quaissoosarquivosimportantesdeumaaplicaoweb;
ondecolocarsuaspginasearquivosestticos;
iniciarotomcatatravsdoplugindoeclipse;
configurarseuprojetoparausaroplugindehtml,jspexml;
configurarseuprojetoparausaroplugindoAmateras.

6.1 - Novo projeto


Primeirovamoscriarumnovoprojetowebnoeclipseusandooplugindasysdeo.
1)VnomenuNeweescolhaProject,JavaProject:

Captulo6NovoprojetowebPgina35

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

2)Onomedoprojetoserjspteste.
3) Selecione a opo que separa o diretrio de arquivos .java dos arquivos .class
(separatesourceandoutputfolders).
4)EscolhaNext.

5)Mudeodiretriodesadaparajspteste/web/WEBINF/classes

Captulo6NovoprojetowebPgina36

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Nossoprojetopossuiaseguinteestrutura:

Lembresequeoeclipsenomostraodiretriodesadadassuasclassesportantoo
diretrioclasses,apesardeexistir,noaparecenoPackageExplorer.

6.2 - Configurando no tomcat


1)Crieumaarquivochamadoteste.jsp,comoseguintecontedo
<html>
Teste
</html>
2)VnomenuProject,Properties.
3)Escolhaaabadotomcat.
Aprximatelapededuasinformaesimportantes:

Captulo6NovoprojetowebPgina37

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

contextname:qualonomedanossaaplicaoquedeveserutilizadoparaocliente
acessal. Isto , se escolhermos o nome de /jspteste para o context name, o usurio ir
acessaraseguinteurl:

http://localhost:8080
/jspteste

Portantoreparequenosefaznecessrioseromesmonomedoprojeto!!!
subdirectorytosetasroot:diretriodoprojetoaserutilizadocomobase.Istose
escolhermos o nome /web como subdiretrio raiz teremos que ao acessar a url

http://localhost:8080
/jspteste

/bemvindo.html

, a pgina do diretrio /web/bemvindo.html ser


chamada.Isto,odiretrio/webabasedoseuprojeto.
4)Selecione/jsptestecomoseucontextname
5)Digite/webcomoseudiretriobase.
6)MarqueseuprojetocomoumprojetodoTomcat(checkbox).

SfaltacriarmosumdiretriolibemWEBINF:
7)CliquedadireitanodiretrioWEBINFecrieumnovochamadolib.

Captulo6NovoprojetowebPgina38

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Caso seu resultado final no mostre os arquivos jar do tomcat siga as seguintes
instrues:
8)Cliquedadireitanoprojeto
9)EscolhaTomcat,addTomcatlibtoprojectbuildpath

6.3 - Erros comuns


1) Se mesmo assim os arquivos .jar no estiverem no seu classpath, confira a
configuraodoplugindotomcat.Odiretrioescolhidofoiodiretriocerto?

6.4 - Anlise do resultado final


Oresultadofinalalgoqueprecisamosanalisarcommuitacalma.Vamospassoapasso.
PrimeirotemosabibliotecadoJava5nonossoclasspath.
Depoistemostrsjarsquenoconhecemos.Essesjarsestonodiretriodotomcat(veja
ocaminhocompletodele)evmjuntocomtodososservletcontinerouservidordeaplicao.
Essesjarspermitemquevocutilizeaapideservletsejsp.Sevocnoutilizasseoplugindo
tomcatdeveriacolocaressesjarsnoclasspathatravsdomenuProject,Properties,JavaBuild
Path,Libraries.
Agoraosdiretriosprincipais,quesoindependentesdequalservletcontinerouservidor
deaplicaovocestutilizando:
src:diretrioondeseencontramsuasclasses.
web: diretriodasuaaplicaowebdeverdade.Tudoquesuaaplicaowebprecisa
estaquidentro.Coloquenessediretrioosarquivosdeextensohtml,jpg,gif,swf,jspetc.
web/WEBINF/:todososarquivosediretriosdentrododiretrioWEBINF(maisculo)
invisvel para o cliente final, portanto jamais coloque pginas html aqui, pois no sero
acessveis.Eexatamenteporessemotivocolocamososarquivosdeconfiguraodobancode
dados,desuasservletsetcnessediretrio.
web/WEBINF/classes: todasasclassessogeradasdentrodestediretrio.Verifique
Captulo6NovoprojetowebPgina39

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

emProject,Properties,JavaBuildPathquetodososarquivosquesocompiladosvoparar
nessediretrio!Essesarquivosestonoclasspathdesuaaplicaowebautomaticamente.
web/WEBINF/lib: aquiestoasbibliotecas(arquivos.jar)queseronecessriaspara
nossaaplicaoweb.Essasbibliotecasestonoclasspathdesuaaplicaoautomaticamente.

WEBINF/lib
OdiretriolibdentrodoWEBINFpodecontertodasasbibliotecasnecessriasparaaaplicao
web,evitandoassimqueoclasspathdamquinaquerodaaaplicaopreciseseralterado.
Alm do mais, cada aplicao web poder usar suas prprias bibliotecas com suas verses
especficas!Vocvaiencontrarprojetosopensourcequesomentefornecemsuporteerespondem
perguntas aqueles usurios que utilizam tal diretrio para suas bibliotecas, portanto evite ao
mximoousodoclasspathglobal.

6.5 - O driver do oracle em um servidor tomcat


Existe um problema clssico que aparece quando colocamos arquivos .zip dentro do
diretriolib.Essearquivo ignorado,conformedeterminadopelaespecificaodasservlets,
sendoassim,aoutilizaralgumaapiqueestdentrodeumarquivo.zip,renomeieprimeiroesse
arquivopara.jaresomenteentocoloqueodentrododiretriolib.
Oexemplomaisfamosodetalproblemaodriverdooracleque,emalgumasverses,
umarquivo.zip.

6.6 - web.xml
Precisamosagoracriarumarquivoimportanteparatodaaplicaoweb:
web/WEBINF/web.xml:essearquivorepresentaaestruturadanossaaplicaoweb,o
bsicoparatodaaplicaoweb:
<?xmlversion="1.0"encoding="ISO88591"?>
<webappxmlns="http://java.sun.com/xml/ns/j2ee"version="2.4">
<displayname>Aplicacaowebsimples</displayname>
</webapp>

AgoraquejinstalamosoTomcat,podemosnospreocuparnacriaodenossaprimeira
aplicaoweb,queserbaseadanatecnologiachamadaJSP,Java Server Pages,pginas
dinmicasquenormalmentegeramcontedohtmlparaservidoresweb.
Apesardoarquivoweb.xmlseropcionaleleserextremamenteimportantemaisparaa
frenteemnossaaplicao.

6.7 - Configurando o Amateras


VamosagoraconfiguraroplugindoAmateras.Essepluginprecisasabertambmqualo
diretriobasedanossaaplicao,assimeleconsegueencontrarodiretrioWEBINFeosjars
dodiretriolibparacolorirnossosjspsefacilitarotrabalhoquetemosaoescreverosmesmos.
1)VnomenuProject,Properties.
2)EscolhaaopoAmateras.

Captulo6NovoprojetowebPgina40

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)AssimcomonaconfiguraodoplugindoTomcat,escolhaodiretrio/webcomobase
doseuprojetoweb.

6.8 - Em casa: configurando o tomcat sem o plugin


Sefosseocasodecriarumaaplicaowebsemutilizaroplugindotomcatdeveramos
criar um arquivo de extenso xml com o nome de sua aplicao no diretrio
tomcat/conf/Catalina/localhost.
Para isso teramos que configurar a url /jspteste para o diretrio
/home/usuario/workspace/jspteste/web/. Queremos tambm permitir que o tomcat
faaorestartdesuaaplicaosemprequejulgarnecessrio.
1)abraosseusdiretrios
2)vparaodiretriotomcat
3-) escolha o diretrio conf/Catalina/localhost
4)crieumarquivochamado jspteste.xml
5)escrevaocdigoaseguirnoseuarquivo:

<Contextpath="/jspteste"docBase="/home/usuario/workspace/jspteste/web/"
reloadable="true"/>

Captulo6NovoprojetowebPgina41

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


Noesqueadetrocarapalavrausuriopelonomedoseuusurio.

Oarquivoxmldeconfiguraodotomcat
Emprocessosdebuildmaisdesenvolvidos,noexisteconfiguraoaserfeitanemmesmona
mquinadedesenvolvimento,sendotudoautomatizadoporprocessosdebuildedeploy.

Captulo6NovoprojetowebPgina42

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

JSP Java Server Pages


O maior prazer esperar pelo prazer.
GottholdLessing

Nessecaptulo:
vocaprenderoqueJSP;
suasvantagensedesvantagens.

7.1 - O que uma pgina JSP


JSP

O primeiro arquivo jsp que vamos criar chamado bemvindo.jsp. Esse arquivo
poderiacontersimplesmentecdigohtml,comoocdigoaseguir:

<html>Bemvindo</html>

AfinalJSP uma pgina html comum que contem tambm cdigo Java
epossuiextensojsp,claro.
Assim fica claro que uma pgina jsp nada mais que um arquivo baseado em html.
Sejamos elegantes aoponto deescrever umcdigo java na nossaprimeirapgina. Que tal
declararumavariveldotipoString:
<%
Stringmensagem=Bemvindo!;
%>
SCRIPTLET

Simples!Paraescrevercdigojavanasuapginabastaescrevloentreastags<%e%>.
Essecdigochamadodescriptlet.
Essaidiadecolocarcdigodeumalinguagemdeprogramaojuntocomhtmlnoto
nova.ANetscapepossuiaoSSJS(ServerSideJavascript)porexemplo,usandocdigobaseado
emjavascript.

scriptlet
scriptletocdigoescritoentre<%e%>,essenomecompostodapalavrascript(linguagemde
script)comosufixolet,queindicaalgopequeno.
ASunpossuiessamaniadecolocarosufixoletemmuitascoisascomoosscriptlets,servlets,
portletsetc.
Podemosavanarmaisumpoucocomjspeutilizarumadasvariveisjimplicitasnojsp:
todoarquivojspjpossuiumavarivelchamadaout(dotipoJspWriter)quepermiteimprimir
objetosatravsdomtodoprintln:
<%out.println(nome);%>

Avariveloutumobjetomplicitonanossapginajspeexistemoutrasdeacordocoma
Captulo7JSPJavaServerPagesPgina43

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

especificaodomesmo.
Existemaindaoutraspossibilidadesparaimprimirocontedodanossavarivel:podemos
utilizarumatalho(muitoparecido,ouigual,aoutraslinguagensdescriptparaaweb):
<%=nome%><br>

Agorajestamosaptosaescreveronossoprimeirojsp.

Comentrios
Oscomentriosemumapginajspdevemserfeitoscomooexemploaseguir:
<%comentrioemjsp%>

7.2 - Exerccios
1)Crieoarquivoweb/bemvindo.jsp.
<html>
<%comentrioemjspaqui:nossaprimeirapginajsp%>
<%
Stringmensagem="Bemvindo!";
%>
Duasversesdiferentesnahoradeimprimiralgo:<br>
<%out.println(mensagem);%><br>
<%=mensagem%><br>
<%
System.out.println("Tudofoiexecutado!");
%>
</html>

2)Testeaurlhttp://localhost:8080/jspteste/bemvindo.jsp

3)OndeapareceuamensagemTudofoiexecutado!?
Lembresequeocdigojavainterpretadonoservidor,portantoapareceunoconsoledo
seuTomcat.

Captulo7JSPJavaServerPagesPgina44

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

4)Sevocpossusseumarquivochamado database.properties, emquediretrio


vococolocaria?
5)Emqualdiretriovocdevecompilarsuasclasses?Porqueessediretrioestdentro
dodiretrioWEBINF?

7.3 - Listando os contatos


UmavezquepodemosescreverqualquercdigoJavacomoscriptlet,noficadifcilcriar
umalistagemdetodososcontatos(usandoasintaxedojava1.4).
Temos todas as ferramentas necessrias para fazer tal listagem uma vez que j
executamostaltarefanaauladeJDBC.
BasicamenteocdigoutilizaroContatoDAOquecriamosanteriormenteparaimprimira
listadeContatos:
<%
ContatoDAOdao=newContatoDAO();
Listcontatos=dao.getLista();
for(inti=0;i<contatos.size();i++){
Contatocontato=(Contato)contatos.get(i);
%>
<li><%=contato.getNome()%>,<%=contato.getEmail()%>:
<%=contato.getEndereco()%></li>
<%
}
%>

Aindafaltaimportarasclassesdospacotescorretos.
Nojspusamosatag<%@pageimport=%>paraimportaraquiloqueserusadono
nosso cdigo scriptlet. O atributo import permite que seja especificado qual o pacote a ser
importado.Esseatributoonicoquepodeaparecervriasvezes.Nessecasoiremosimportar
diversospacotesseparandoosmesmoscomvrgula.

7.4 - Exerccios
1)Importeosarquivosdonossoprojetoanteriorparaesse.Vnoterminaledigite:
cdworkspace
unzip/caelum/zips/21/jspteste.zip

Captulo7JSPJavaServerPagesPgina45

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

2)EscolhaonomedoprojetoeaperteateclaF5
3)Crieoarquivoweb/listascriptlet.jsp.
a)Importeospacotesnecessrios.
<%@ page
import="java.util.*,br.com.caelum.jdbc.*,br.com.caelum.jdbc.dao.*,br.com.caelum.jdbc.mode
lo.*" %>
b)Coloqueocdigoparafazeralistagem.
<html><ul>
<%
ContatoDAOdao=newContatoDAO();
Listcontatos=dao.getLista();
for(inti=0;i<contatos.size();i++){
Contatocontato=(Contato)contatos.get(i);
%>
<li><%=contato.getNome()%>,<%=contato.getEmail()%>:
<%=contato.getEndereco()%></li>
<%
}
%>

</ul></html>
c)Testeaurlhttp://localhost:8080/jspteste/listascriptlet.jsp

Captulo7JSPJavaServerPagesPgina46

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

7.5 - Erros comuns


1)Casovoctenhaobtidoaseguintetelanoseunavegador:

ConfiraoseuContatoDao,seelepossuiosseguintesproblemasdecompilao:

Captulo7JSPJavaServerPagesPgina47

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

IssoocorreupoisseuprojetoestconfiguradoparaoJava1.4,entodevemosalterartal
configuraoparaJava5.0:
a)Vnopacotebr.caelum.jdbc.dao,naclasseContatoDao
Useoquickfixdoeclipseparasolucionarseuproblema:
b)Cliquenalmpadacomumxnabarraesquerdadoeclipse
c)EscolhachangeworkspacecomplianceandJREto5.0

7.6 - HTML e Java: eu no quero cdigo Java no meu jsp!


complicadoficarescrevendoJavaemseuarquivojspno?
Primeiroficatudomalescritoedifcildeler.OJavapassaaatrapalharocdigohtmlem
vezdeajudar.
Depois,quandooresponsvelpelodesigngrficodapginaquiseralteraralgoterque
conhecerJavaparaentenderoqueestescritoldentro...hmm...nopareceumaboasoluo.
UmaidiaboaoMVC,queservistomaisadiantenestecurso.

7.7 - EL: Expression language


EL

PararemoverumpoucodocdigojavaqueficanapginajspaSundesenvolveuuma
linguagemchamadaExpressionLanguagequeinterpretadapeloservletcontiner.
Nossoprimeiroexemplocomessalinguagemutilizlaparamostrarparmetrosqueo
clienteenviaatravsdesuarequisio.
Por exemplo, se o cliente chama a pgina testaparam.jsp?idade=24 o programa deve
Captulo7JSPJavaServerPagesPgina48

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

mostraramensagemqueoclientetem24anos.
Como fazer isso? Simples, existe uma varivel chamada param que, na expression
language,reponsvelpelosparmetrosenviadospelocliente.Paraleroparmetrochamado
idade basta usar ${param.idade}. Para ler o parmetro chamado dia devemos usar
${param.dia}.

7.8 - Exerccios
1)Crieumapginachamadaweb/testaidade.jsp:
<html>
Digitesuaidadeepressioneoboto:<br/>
<formaction="testaparametro.jsp">
Idade:<inputname="idade"/><inputtype="submit"/>
</form>
</html>

2) Crie um arquivo chamado testaparametro.jsp e coloque o cdigo de expression


languagequemostraaidadequefoienviadacomoparmetroparaessapgina.
<html>
Testandoseusparametros:<br/>
Aidade${param.idade}
</html>

3)Testeosistemaacessandoapginahttp://localhost:8080/jspteste/testaidade.jsp.

7.9 - Exerccios opcionais


1)Tenteutilizaroquadroaseguirparadefinirapginapadrodeseusite.

welcomefilelist
Oarquivoweb.xmlabaixodizqueosarquivoschamadosbemvindo.jspdevemserchamados
quandoumclientetentaacessarumdiretriowebqualquer.
Ovalordessecampocostumaserindex.htmlemoutraslinguagensdeprogramao.
Vocpodeindicarmaisdeumarquivoparaseroseuwelcomefile!

Captulo7JSPJavaServerPagesPgina49

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

<welcomefilelist>
<welcomefile>bemvindo.jsp</welcomefile>
</welcomefilelist>
EacesseaURL:
http://localhost:8080/jspteste/

7.10 - Erros comuns


1)Depoisquevocdigitouaidadenoformulariovocobteveapginaabaixo?

Verifiquenoseuarquivotestaidade.jspnoactiondentrodoformulrioseonomedapgina
paraaqualdeveriaserredirecionadaestdigitadocorretamente.
2)Aidadenoapareceuesuatelaficouassim?

Verifique se no seu arquivo testaparametro.jsp o parmetro idade est digitado


corretamente.

7.11 - Exerccios opcionais


1)Crieoutroexemplocomdoiscamposemvezdeums.Mostreosdoisparmetrosna
segundapgina.
a)Exemplocomdoiscampos:
<html>
Digitesuaidadeepressioneoboto:<br/>
<formaction="testaparametro.jsp">
Captulo7JSPJavaServerPagesPgina50

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


Nome:<inputname="nome"/><br/>
Idade:<inputname="idade"/><inputtype="submit"/>
</form>
</html>

b)Mostrandoosdoisparmetros:
<html>
Testandoseusparametros:<br/>
Onome${param.nome}<br/>
Aidade${param.idade}
</html>

c)Exemplodeumresultadofinal:

7.12 - Instanciando POJOs


POJO

Comojfoicomentadoanteriormente,osJavabeansdevempossuiroconstrutorpblico
semargumentos(umtpicoPlainOldJavaObject:POJO),gettersesetters.
Sedesejarmosinstanciarumobjetodessetipoemnossapginajsppodemosfazeruso
dissoatravsdeumatagsimples.
Isso mesmo! Umatag. A Sunpercebeu queosprogramadores estavam abusandodo
cdigoJavanojspetentoucriaralgomaisnatural(umpontoumtantoquantoquestionvelda
maneira que foi apresentada no incio), sugerindo o uso de tags para substituir trechos de
cdigo.
Oresultadofinalumconjuntodetags(umataglibrary,outaglib)padro,quepossui,
entreoutrastags,afuncionalidadedeinstanciarobjetosatravsdoconstrutorsemargumentos.

JSP:USEBEAN

Issonotodifcil.Dumaolhadanatagaseguir:

<jsp:useBean id="contato" class="br.com.caelum.jdbc.modelo.Contato"/>


Agorapodemosimprimironomedocontato(queestembranco,claro...):
${contato.nome}
Mas onde est o getNome()? A expression language capaz de perceber sozinha a
necessidadedechamarummtododotipogetter,porissoopadrogetter/setterdopojoto
importantehojeemdia.
Destamaneira,classescomoContatosoferramentaspoderosasporseguiressepadro
Captulo7JSPJavaServerPagesPgina51

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

poisdiversasbibliotecasimportantesestobaseadasnele:Hibernate,Struts,JXPath,EJBetc.

Ateno
NaExpressionLanguage${contado.nome}chamarafunogetNomeporpadro.Paraqueisso
semprefuncionedevemoscolocaroparmetroemletraminsculaouseja${contato.Nome}no
funciona.

7.13 - Compilando os arquivos JSP


OsarquivosJSPsnosocompiladosdentrodoeclipse,poressemotivonahoraque
estamosescrevendooJSPnoeclipsenoprecisamosdasclassesdodriver.
OsJSPssotransformadosemumaservlet,queveremosadiante,porumcompilador
JSP(oTomcatcontmumcompiladorembutido).EssecompiladorJSPpodegerarumacdigo
javaqueentocompiladoparagerarbytecodediretamenteparaaservlet.
Ento,somenteduranteaexecuodeumapginajsp,quandoeletransformadoem
umaservlet,queseucdigojavacompiladoenecessitamosdasclassesdodriverqueso
procuradasnodiretriolib.

Captulo7JSPJavaServerPagesPgina52

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

JSTL JavaServer Pages Tag Library

Saber compreendermos as coisas que mais nos convm.


FriedrichNietzsche

Nessecaptulo,vocaprender:
oqueJSTL;
taglibcore;
tagc:forEach
tagc:import
diretivainclude
tagc:if
tagc:url

8.1 - JSTL
Seguindoaidiademelhorarocdigojavaqueprecisadeumamaneiraououtraser
escritonapginajsp,aSunsugeriuousodaJavaServerPagesStandardTagLibrary....aJSTL.
Observao: Antes de 2005 JSTL significava JavaServer Pages Standard Template
Library.
JSTL

A JSTL a api que encapsulou em tags simples toda a funcionalidade que diversas
pginas web precisam, como controle de laos (fors), controle de fluxo do tipo if else,
manipulaodedadosxmleainternacionalizaodesuaaplicao.
Antigamente diversas bibliotecas foram criadas por vrios grupos com funcionalidades
similares ao JSTL (principalmente ao Core), culminando com a apario da mesma, numa
tentativadaSundepadronizaralgoqueomercadovcomotil.
ExistemaindaoutraspartesdaJSTL,porexemploaquelaqueacessabancodedadose
permiteescrevercdigossqlnanossapgina,masseodesignernocompreendejavaoque
diremos de SQL??? O uso de tal parte da JSTL desencorajado exceto em casos muito
especiais.
A JSTL foi a forma encontrada de padronizar o trabalho de milhares de
programadores de pginas JSP.
Antes disso muita gente programava como nos exemplos que vimos
anteriormente, somente com JSPs e Javabeans, o chamado Modelo 1, que na poca
fazia parte dos Blueprints de J2EE da Sun (boas prticas).

8.2 - As empresas hoje em dia


MuitaspginasjspnoBrasilaindapossuemgrandespedaosdescriptletsespalhados
dentrodelamesma.

Captulo8JSTLJavaServerPagesTagLibraryPgina53

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Recomendamos a todos os nossos alunos, que optarem pelo jsp como camada de
visualizao, que utilizem a JSTL e outras bibliotecas de tag para evitar o cdigo
incompreensvelquepodesergeradocomscriptlets.
O cdigo das scriptlets mais confundem do que ajudam, tornando a manuteno da
pginajspcadavezmaiscustosaparaoprogramadoreparaaempresa.

8.3 - Instalao
Para instalar a implementao mais famosa da JSTL basta baixar a mesma no site
jakarta.apache.org.
Aodescompactaroarquivo,vocencontrarosarquivos.jarqueestonodiretriolibdo
seuprojeto.ElessoaimplementaopadrodaJSTLfeitapelogrupojakarta.
AousaroJSTLemalgumapginaprecisamosprimeirodefinirocabealhoparautilizla.
Existemquatroapisbsicaseiremosaprenderprimeiroautilizarabibliotecachamadadecore.

8.4 - Cabealho para a JSTL core


Semprequevamosutilizarumataglibdevemosprimeiroescreverumcabealhoatravs
deumatagjspquedefinequaltaglibiremosutilizaredefinimosumnomeparaomesmo,o
chamadoprefixo.
EsseprefixopodeterqualquervalormasnocasodataglibcoredajstlopadrodaSun
aletra c.Jauri(quenodeveserdecorada)mostradaaseguirenoimplicaemuma
requisiopeloprotocolohttpesimumabuscaentreosarquivos.jarnodiretriolib.
Aodescompactarmosoarquivojspteste.zipnocaptuloanteriorcolocamostambmtais
arquivos.jar,detalmodoquepodemosincluirataglibcorecomonoexemploaseguir:
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>

8.5 - For
UsandoaJSTLcore,vamosreescreveroarquivoquelistatodoscontatos.
Ocabealhojconhecidodaseoanterior:
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<html>

Depoisprecisamosinstanciaredeclararnossodao.Aorevisaroexemplodalistaatravs
descriptlets,desejamosexecutaroseguinte:
classe:br.com.caelum.jdbc.dao.ContatoDAO
construtor:semargumentos
varivel:dao
J vimos a tag jsp:useBean, capaz de instanciar determinada classe atravs do
construtorsemargumentosedarumnome(id)paraessavarivel.Narealidadeessatagfaz
muito mais do que isso, mas para nossos exemplos quesero descartados mais pra frente
quandoaprendermosomvcissomaisquesuficiente.
PortantovamosutilizarataguseBeanparainstanciarnossoContatoDao:

Captulo8JSTLJavaServerPagesTagLibraryPgina54

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

<jsp:useBean id="dao" class="br.com.caelum.jdbc.dao.ContatoDAO"/>


C:OUT

Apartirdestemomento,temosavarivel dao nochamadoescopodepgina,esseo


escopochamadopageContext,ondeosbeansficamarmazenados.Podemosmostraronomedo
primeirocontatousandoaJSTLcore.Paraissousaremosoprefixoconfiguradonocabealho:c.

<c:outvalue="${dao.lista[0].nome}"/>

Ouoseuemail:
<c:outvalue="${dao.lista[0].email}"/>

Muito complexo? Com o tempo fica, felizmente, mais legvel. No primeiro exemplo,
chamadoomtodogetLista,oprimeiroitem,eentoomtodogetNome.Oresultadoenviado
paraavarivelout:nossoPrintWriter.
EXPRESSION
LANGUAGE

Quetal?Aindanotoelegantequantoqueramos,certo?Ocdigodentrodoatributo
value chamado de Expression Language (EL), e parte de uma linguagem que
utilizaremosduranteessecurso.
Agora que temos a varivel dao na mo desejamos chamar o mtodo getLista e
podemosfazerissoatravsdaEL:

${dao.lista}

Eagoradesejamosexecutarumloopparacadacontatodentrodacoleoretornadapor
essemtodo:

arrayoucoleo:dao.lista
variveltemporria:contato
NonossoexemplocomscriptletsoquefaltaachamadadomtodogetListaeaiterao:

<%
//...
Listcontatos=dao.getLista();
for(inti=0;i<contatos.size();i++){
Contatocontato=(Contato)contatos.get(i);
%>
<li><%=contato.getNome()%>,<%=contato.getEmail()%>:
<%=contato.getEndereco()%></li>
<%
}
%>
C:FOREACH

AJSTLcoredisponibilizaumatagchamadac:forEachcapazdeiterarporumacoleo,
exatamenteoqueprecisamos.Oexemploaseguirmostraousodeexpressionlanguagedeuma
maneiramuitomaiselegante.

<c:forEach var="contato" items="${dao.lista}">


<li>${contato.nome}, ${contato.email}: ${contato.endereco}</li>
</c:forEach>
Maiselegantequeocdigoquefoiapresentadousandoscriptletss,no?

forEachevarStatus
possvel criar um contador do tipo int dentro do seu lao forEach. Para isso basta definir o
Captulo8JSTLJavaServerPagesTagLibraryPgina55

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

atributochamadovarStatusparaavariveldesejadaeutilizarapropriedadecountdessavarivel.
<c:forEachvar="contato"items="${dao.lista}"varStatus="id">
<li>${id.count}${contato.nome}</li>
</c:forEach>

8.6 - Exerccios
1)ListeoscontatosdeContatoDAOusandojsp:useBeanejstl.
a)Crieoarquivolistaelegante.jsp
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<html>
</html>

b)ColoqueouseBean
<!criaalista>
<jsp:useBean id="dao" class="br.com.caelum.jdbc.dao.ContatoDAO"/>

c) FaaoforEach
<!for>

<c:forEach var="contato" items="${dao.lista}">


<li>
nome: ${contato.nome},
email ${contato.email},
endereo ${contato.endereco}
</li>
</c:forEach>
d)Acessehttp://localhost:8080/jspteste/listaelegante.jsp

Reparequeapscriarumanovapginajspnoprecisamosreiniciaronossocontainer!
3)scriptletssouJSTL.Qualdosdoismaisfcilparaodesignerentender?

8.7 - c:out e c:set


Captulo8JSTLJavaServerPagesTagLibraryPgina56

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Tente substituir ${contato.nome} por <c:out value="${contato.nome}"/>. Qual a


diferena?
Atagc:outaceitatambmumatributochamadodefault,queindicaovalorpadrocasoo
valor mencionado seja null (por padro vazio). Seria impossvel fazer isso somente com a
expressionlanguage(semnenhumagambiarra).
Atagc:setpermitearmazenaroresultadodaexpressocontidanoatributovalueemoutra
varivel,paraalgumtipodemanipulaofutura.
C:SET

Teste,porexemplo:
<c:setvar="nome"value="${contato.nome}"/>
<c:outvalue="${nome}"/>
Comovocpodepercebermuitosimplesaprenderautilizarumataglib,bastaleroque
elafaz,passarosargumentoscorretosepronto.
SugerimosaleituracompletadaespecificaodaJSTLnositedasun:
http://java.sun.com/products/jsp/jstl/
http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/index.html
Noprecisadecorartudo,bastalerporcimaesaberoqueexisteeoquenoexiste.
Quandosurgiranecessidadedousodeumadessastagsvoctereladisponvelem
suasmos.

8.8 - Mas quais so as tags da taglib core?


Alistacompletadastagsdaverso1.1daJSTLcorepodeserfacilmentecompreendida:
c:catch
c:choose
c:forEach
c:forTokens
c:if
c:import
c:otherwise
c:out
c:param
c:redirect
c:remove
c:set
c:url
c:when

blocodotipotry/catch
blocodotiposwitch
for
foremtokens(ex:a,b,cseparadosporvrgula)
if
import
defaultdoswitch
sada
parmetro
redirecionamento
remoodevarivel
criaodevarivel
vejaadiante
testeparaoswitch

8.9 - Import: trabalhando com cabealhos e rodaps


C:IMPORT

Umaperguntaquesempreaparecenavidadosprogramadoresadecomoexecutaro
cdigodeoutro arquivojspdentrodeumprimeiroarquivojsp,isto,vocquercolocarum
cabealho?Umrodap?
ExisteumatagdaJSTLcorequefazissoparavoc:

<c:importurl="outrapagina.jsp"/>
Captulo8JSTLJavaServerPagesTagLibraryPgina57

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

8.10 - Exerccios
1)Crieumapginachamada jstl-import.jsp.
a)DefinaaJSTLcore
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>

b)Importecabecalho.jsp
<c:importurl="cabecalho.jsp"/>

c)Escrevaalgumamensagemdetexto
c)Importerodape.jsp
<c:importurl="rodape.jsp"/>

2)Crieapginacabecalho.jspeescreva:
<html><head><h2>Aplicacaowebbasica</h2><br/></head>

3)Crieapginarodape.jspeescreva:
<br/><hr/>CopyrightCaelum</html>

4)Testenobrowserabrindooendereo:
http://localhot:8080/jspteste/jstlimport.jsp

Ainclusofeitanesseexercciodinmica,ouseja,feitaumarequisioparaapgina
includaacadaacessoeoresultadoadicionadonapginaatual.

8.11 - Erros Comuns


Vocobteveessapginaaoinvsdadecima?

Captulo8JSTLJavaServerPagesTagLibraryPgina58

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

1)Verifiqueseasuatagliburiestdigitadacorretamente.

8.12 - Incluso esttica de arquivos


@INCLUDE

ExisteumamaneiraemumarquivoJSPdeincluirumoutroarquivoestaticamente.Istofaz
comqueoarquivoaserincludosejaliteralmentecopiadoecoladodentrodoseuarquivoantes
daprimeirainterpretao(compilao)doseujsp.
Avantagemquecomoainclusofeitaumanicavezantesdoarquivosercompilado,
essainclusoextremamenterpida,pormvalelembrarqueoarquivoncluidopodeouno
funcionarseparadamente.

<%@includefile=outra_pagina.jsp%>

8.13 - Exerccios
1) Crie uma pgina chamada titulo.jsp. Esse arquivo ir mostrar o contedo da
variveltitulo:
<h1><%=titulo%></h1>

2)Crieumapginachamadatestatitulo.jsp.Essejspvaidefinirumavarivelchamada
tituloeincluiroarquivotituloestaticamente:
<html>

Captulo8JSTLJavaServerPagesTagLibraryPgina59

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

<%
Stringtitulo=Testedetitulo;
%>
<%@includefile=titulo.jsp%>

<br/>
<fontcolor=blue>Contedodasuapginaaqui...</font>
</html>

3)Testeaurlhttp://localhost:8080/jspteste/testatitulo.jsp

4)Testeaurlhttp://localhost:8080/jspteste/titulo.jsp.Porqueelanofunciona?Talvezno
fizessesentidoessearquivotitulo.jspficarnodiretrioweb.Quetalmovereleparaodiretrio
WEBINF?
5)Altereseuarquivolistascriptlets.jspeincluaapginatitulo.jsp:
<%
Stringtitulo=Listadecontatosviascriptlets;
%>
<%@includefile=titulo.jsp%>

8.14 - Trabalhando com links


C:URL

Asvezesnosimplestrabalharcomlinkspoistemosquepensarnaurlqueocliente
acessaaovisualizaranossapgina.
Captulo8JSTLJavaServerPagesTagLibraryPgina60

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

AJSTLresolveesseproblema,supondoqueasuaaplicaosechamejspteste,ocdigo
abaixogeraastring/jspteste/imagem/banner.jpg.
<c:urlvalue="/imagem/banner.jpg"/>

8.15 - Exerccios opcionais


1)Crieumapginachamada jstl-url.jsp.
a)DefinaaJSTLcore
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>

b)Crieumlinkutilizando atagc:urlparatodasaspginasjsp quevoc jcriou,por


exemplo:
<ahref="<c:urlvalue="/bemvindo.jsp"/>"/>linkparabemvindo.jsp</a>
<ahref="<c:urlvalue="/listaelegante.jsp"/>"/>linkparalista
elegante.jsp</a>
<ahref="<c:urlvalue="/jstlimport.jsp"/>"/>linkparajstlimport.jsp</a>
<ahref="<c:urlvalue="/testaidade.jsp"/>"/>linkparatestaidade.jsp</a>
<ahref="<c:urlvalue="/testatitulo.jsp"/>"/>linkparatestatitulo.jsp</a>

2)Testeasuapginaevejaoresultado(cdigofonteHTML).

8.16 - Tag <c:if>


Aousaratag<c:if>possvelconstruirexpressescondicionaissimples.Porexemplo:
<c:if test="${empty param.nome}">
Voce nao preencheu o campo nome.
</c:if>
A tag <c:if> tem uma condio e um pedao de cdigo. Caso a condio da tag for
satisfeitaopedaodecdigoexecutado.
NoJSTLnoexisteatag<c:else>porquestesestruturaisdoXML.

8.17 - Exerccios
1)Crieumarquivojspweb/preenchenome.jsp:
<html>
Digiteseunomeepressioneoboto:<br/>

Captulo8JSTLJavaServerPagesTagLibraryPgina61

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


<formaction="testapreencheu.jsp">
Nome:<inputname="nome"/><inputtype="submit"/>
</form>
</html>

2) Crieumarquivoweb/testapreecheu.jsp, elevaichecar senoformulrioanteriora


pessoapreencheuounoonome.
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<html>

<c:iftest="${emptyparam.nome}">
Vocenaopreencheuocamponome.
</c:if>
<c:iftest="${notemptyparam.nome}">
Vocepreencheu${param.nome}.
</c:if>
</html>
a)Exemplocasoapessoatenhapreenchido:

b)Casoapessoanotenhapreenchido:

Captulo8JSTLJavaServerPagesTagLibraryPgina62

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

Controle de erro

Divide as dificuldades que tenhas de examinar em tantas partes


quantas for possvel, para uma melhor soluo.
RenDescartes

Desvantagensnautilizaodeblocostry/catchemumarquivojsp;
Desvantagensnautilizaodatagc:catchemumarquivojsp;
Vantagensnocontroledeerrosatravsdeconfiguraodeclarativa;
Controledeerrosatravsdeexceptions;
Controledeerrosatravsdeerrorcodes.

9.1 - Exceptions
Oqueacontecequandodiversospontosdanossaaplicaoprecisamtratarseuserros?
Oqueacontecequandoumtipodeerroqueocorreemdiversospontosdeveseralterado?
Devemospassarportodosasservletsparatratarisso?Portodososarquivosjsp?
Uma idia bem simples seria colocar em toda pgina jsp um cdigo imenso do tipo
try/catchcomonoexemploaseguirdonossojconhecidolistascriptlet.jsp:
<%@ page
import="java.util.*,br.com.caelum.jdbc.*,br.com.caelum.jdbc.dao.*,br.com.caelum.jdbc.mode
lo.*" %>
<html><ul>
<%
try{
ContatoDAOdao=newContatoDAO();
Listcontatos=dao.getLista();
for(inti=0;i<contatos.size();i++){
Contatocontato=(Contato)contatos.get(i);
%>
<li><%=contato.getNome()%>,<%=contato.getEmail()%>:
<%=contato.getEndereco()%></li>
<%
}
}catch(SQLExceptionex){
%>
Ocorreualgumerroaoacessarobancodedados.
<%
}
%>

</ul></html>
Bastaolharocdigoacimaparaperceberquenoomelhorcaminho.Imaginacomo
seria tratar os erros dessa maneira em toda sua aplicao? E se a mensagem de erro
Captulo9ControledeerroPgina63

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

mudasse?Teramosquemudartodasaspginas?

9.2 - JSTL a soluo?


Poderamosusaratagc:catch,comomesmotipodeproblemadasoluoanterior:

<c:catchvar=error>
<jsp:useBean id="dao" class="br.com.caelum.jdbc.dao.ContatoDAO"/>
<c:forEach var="contato" items="${dao.lista}">

<li>
nome: ${contato.nome},
email ${contato.email},
endereo ${contato.endereco}
</li>
</c:forEach>
</c:catch>
<c:iftest=${notemptyerror}>
Ocorreualgumerroaoacessarobancodedados.
</c:if>

ReparequeaprpriaJSTLnosapresentaumasoluoquenosemostraboaparaesse
tipodeerroquequeremostratar.importantedeixarclaroquedesejamostratarotipodeerro
que no tem volta, devemos mostrar uma mensagem de erro para o cliente e pronto, por
exemploquandoaconexocomobancocaiouquandoocorrealgumerronoservidor.
Essessoerrosdoservidor(oudoprogramador)enoerrosdocliente,comoproblemas
devalidaodecampo,quetrataremosnocaptulodostruts.

9.3 - Exerccios opcionais


1) Trateoerrodalistagemdecontatoscom<c:catch>criandoumarquivochamado
testaccatch.jsp.
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<html>
<h1>Tratandoerrocomc:catch</h1>
</br>
<c:catchvar=error>
<jsp:useBean id="dao" class="br.com.caelum.jdbc.dao.ContatoDAO"/>
<c:forEach var="contato" items="${dao.lista}">

<li>
nome: ${contato.nome},
email ${contato.email},
endereo ${contato.endereco}
</li>
</c:forEach>
</c:catch>
<c:iftest=${notemptyerror}>
Ocorreualgumerroaoacessarobancodedados.
</c:if>
</html>

Captulo9ControledeerroPgina64

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

9.4 - Tratamento padro de erros modo declarativo


O processo declarativo para controle de
erros o mais fcil de usar pois no impe
mudanas nas pginas jsp quando surge a
necessidadedealterartalprocesso.

Jsp 1

Atravs do arquivo web.xml possvel


configurar para cada tipo de erro (atravs de
cdigo ou exception), qual a pgina html,
jsp,servletetc,deveserutilizada.

Jsp 2

web.xml

O diagrama ao lado mostra o que


erro.jsp ou outra pgina qualquer
acontece se uma exception ocorrer em algum
pontodesuaaplicaowebatravsdoprocesso
declarativo:todasasexceesdeumtipooudeumcdigodefinidovaiparaumacertapgina
deerro.

9.5 - Pgina de erro


Comeamoscriandoumapginajspchamadaerro.jspqueutilizaumadiretivaparaindicar
queumapginadecontroledeerro,isto,quandoerrosocorrem,ofluxoserredirecionado
paraessapgina.
Adiretivaaserutilizadaamesmaqueusamosparaimportarclassesepacotes.Nesse
casoutilizamosoatributeisErrorPageparadisponibilizaroerro(exception)queocorreuparao
nossocdigojsp.
<%@pageisErrorPage=true%>

AgorapodemosmostraramensagemdeerrousandoEL.Lembresequeavarivela
seguirssercriadaseoerroforumaexception!
${pageContext.errorData.throwable}
Portantoapginachamadaerro.jspacabasendoocabealhocomamensagemdeerro:
<%@pageisErrorPage="true"%>
<html>
Umerroocorreu.<br/>
${pageContext.errorData.throwable}
</html>

9.6 - Configurando a pgina de erro


ERROR-PAGE

Agora precisamos configurar no arquivo web.xml qual tipo de exception vai para qual
pginajsp.Esseummapeamentosimples,bastaadicionaronomedaclassedaexception
(exceptiontype)eonomedapginaalvo(location).

<errorpage>
<exceptiontype>classe</exceptiontype>
<location>/pgina.jsp</location>
</errorpage>

9.7 - Quando acontece um erro em uma pgina jsp


Captulo9ControledeerroPgina65

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

muitosimplescontrolarerrosempginasjsp.Imagineapginaaseguirquesimulaum
errodeconexoaobancodedados:
<html>
<%
java.sql.DriverManager.getConnection("jdbc:teste:invalido","usuario","senha");
%>
</html>

Agoraquejconfiguramos,quandoocorrerumaSQLException,apginaerro.jspser
mostradasenadaforfeitopeloprogramador: noprecisamosfazerNADAnapginajspque
podegerarumerro.Simplesno?
Quem trata o erro oservlet conteiner, que lo arquivo web.xml eenvia ofluxo da
requisioparaapginadeerroindicadanaquelearquivo.

9.8 - Exerccios
1)Crieoarquivotestaerro.jsp(reparequenaprticavocnoircriaressearquivo)
<html>
<%
java.sql.DriverManager.getConnection("jdbc:teste:invalido");
%>
</html>

a)Testeaurlhttp://localhost:8080/jspteste/testaerro.jsp

2)Crieoarquivoerro.jsp.
<%@pageisErrorPage="true"%>
<html>
<h1>Umerroocorreu.</h1><br/>
${pageContext.errorData.throwable}
</html>
Captulo9ControledeerroPgina66

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)Altereoarquivoweb.xmleadicioneumaerrorpage:
a)exceptiontype:java.sql.SQLException
b)location:/erro.jsp
<errorpage>
<exceptiontype>java.sql.SQLException</exceptiontype>
<location>/erro.jsp</location>
</errorpage>

5)Testeaurlhttp://localhost:8080/jspteste/testaerro.jsp

6) Para generalizar os erros que so direcionados para erro.jsp mapeie


java.lang.Exceptionparaasuapginadeerro.
<errorpage>
<exceptiontype>java.lang.Exception</exceptiontype>
<location>/erro.jsp</location>

</errorpage>
Obs:OTomcat5.5.17temumbugfazendooexerccionofuncionar.

9.9 - Tratamento de outros erros


Para muitas aplicaes importante mostrar mensagens de erro padronizadas, por
exemploquandoousuriotentaacessarumapginaquenoexiste,eledeverecebercomo
respostaumapginaeleganteindicandoquenofoipossvelencontrarapginarequisitada,
incluindooerro404(quefazpartedoprotocolohttp).
Parafazerissoiremosdefinirumanovaerrorpagenoarquivoweb.xmlmasaoinvsde
colocar o exceptiontype iremos utilizar a tag errorcode. Ser necessrio criar uma pgina
separada para o erro 404 pois a que criamos anteriormente assumia a existncia de uma
exception,quenoessecaso:
<errorpage>
<errorcode>404</errorcode>
<location>/paginaNaoEncontrada.jsp</location>
</errorpage>

Captulo9ControledeerroPgina67

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

9.10 - Erros comuns


Noexerccioanteriormuitocomumerrarnosseguintesdetalhes:
1)Erraralgonapginadeerro(comootextodaexpressionlanguage),evisualizara
pginadeerronormaldotomcat.
2)Esquecera/nomapeamentodapginadeerroeverumapginadotipo404.Porque?
Acontecequequandovocinicouotomcat,elepercebeuqueseuxmlinvlidoeno
inicializouseucontexto.Esteumbommomentoparavocpegaraprticade,sempreque
reinicializaroseutomcat,verificarseaparecealgumaexceptionnoconsoledomesmoe,se
aparecer,lla.
Maisimportanteaindaaprenderalerexceptionssemaajudadeterceiros.Onomedo
erro,amensagem,easlinhasondeelaocorreunapilhadeexecuoentregamtodasasdicas
paravocdescobriroqueaconteceunamaiorpartedasvezes.
Verifiqueseuarquivodeconsole:

Pginadeerroerro.jspnocomeacomuma/,isto,eleestdizendoexatamenteoseu
erro!

9.11 - Exerccios
1)Trateoerrotipo404nasuaaplicao.
Captulo9ControledeerroPgina68

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

a) Teste a url http://localhost:8080/jspteste/qualquer_coisa.jsp eveja qual a mensagem


padrodoTomcat.

b)Crieumapaginadeerroparapginasnoencontradas:web/paginaNaoEncontrada.jsp
<%@pageisErrorPage="true"%>
<html>
<h1>404Pginanoencontrada.</h1><br/>
</html>

c)Mapeieoerro404paraapgina/paginaNaoEncontrada.jsp
<errorpage>
<errorcode>404</errorcode>
<location>/paginaNaoEncontrada.jsp</location>
</errorpage>

d)Testeaurlhttp://localhost:8080/jspteste/qualquer_coisa.jsp

9.12 - Erros Comuns


Captulo9ControledeerroPgina69

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Mesmodepoisquevocmapeousuaspginasdeerroparecequeoweb.xmlno
existe,nohouveredirecionamentonenhum?
1)Reinicieotomcat

Captulo9ControledeerroPgina70

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

10

captulo

Servlets

10

Vivemos todos sob o mesmo cu, mas nem todos temos o


mesmo horizonte.
KonradAdenauer

Nestecaptulovociraprenderacriarpequenosobjetosquefuncionamcomoaplicaesweb.

10.1 - Servlet
SERVLET

Umaservletfuncionacomoumpequenoservidor(servidorzinhoemingls)querecebe
chamadasdediversosclientes.
Umaprimeiraidiadaservletseriaquecadaumadelasresponsvelporumapgina,
sendoqueelaldadosdarequisiodoclienteerespondecomoutrosdados(html,gifetc).
ComonoJavatentamossemprequepossveltrabalharorientadoaobjetos,nadamaisnatural
queumaservletsejarepresentadacomoumobjeto.

REQUEST
RESPONSE
CGI

HTTP

Resumindo,cadaservletumobjetojavaquerecebetaisrequisies(request)eretorna
algo(response),comoporexemploumapginahtmlouumaimagemdoformatojpeg.
Diversas requisies podem ser
feitasumamesmaservletaomesmo
tempo em um nico servidor, por isso
elamaisrpidaqueumprogramaCGI
comum.Aespecificaodaservletcita
algumasvantagensdamesmasobreo
antigoCGI.
O diagramaao lado mostra trs
clientes acessando o mesmo servidor
web/continer de servlets atravs do
protocolohttp.
A pgina a ser retornada pela
servlet pode ser um jpeg, um gif, um
arquivo html etc: arquivos de texto ou
simplesmentebinrios.

HTTPSERVLET

SERVLET

ClienteIE
ServidorWeb

Cliente
Firefox

Cliente
Opera

Servlet
Continer

recebe
requisiesvia
http

O comportamento das servlets que iremos ver neste captulo foi definido na classe
HttpServletdopacotejavax.servlet.Elesseaplicamsservletsquetrabalhamatravsdo
protocoloHttp.
Ainterface Servlet aquedefineexatamentecomoumaservletfunciona,masno
necessariamente o que vamos utilizar neste captulo uma vez que ela possibilita o uso de
qualquerprotocolobaseadoemrequisieserespostas.

Captulo10ServletsPgina71

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

importantefrisarqueamesmainstnciadeumaservlet(omesmoobjeto)podeser
chamadamaisdeumavezparadiferentesrequisiesaomesmotempo,justamenteparaobter
asvantagensmencionadasanteriormentecontraousodeCGI.
Ofuncionamentobsicodeumaservletcompreende:
ainicializaodamesma(veremoscommais
detalhesmaisadiante)
SERVICE

chamadas a mtodos de servio, essas


chamadas passam dois argumentos para o mtodo
service,arequisioqueoclientefazearespostaque
permiteenviardadosparaomesmo:
voidservice(HttpServletRequestreq,
HttpServletResponseres);

finalizao (veremos com detalhes mais


adiante),
O exemplo a seguir mostra uma servlet
implementandoomtododeservice.
Um primeiro exemplo de mtodo service seria
aquelequenoexecutanadaemostraumamensagem
debemvindoparaousurio.Paraissoprecisamosalterararespostaqueaservletenviar
paraocliente.
O writer de sada do cliente pode ser obtido atravs do mtodo getWriter da varivel
responseeentoficasimplesutilizarumPrintWriterparaimprimiralgocomorespostaparao
cliente:
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException{

//recebeowriter
PrintWriterout=response.getWriter();
//escreveotexto
out.println("<html>");
out.println("Caelumexplica");
out.println("</html>");
}

ServletxCGI
ficanamemriaentrerequisies,noprecisaserreinstanciado
onveldeseguranaepermissodeacessopodesercontrolado
emCGI,cadaclienterepresentadoporumprocesso,enquantoquecomServlets,cadacliente
representadoporumalinhadeexecuo
Esse captulo est focado na HttpServlet, um tipo que gera aplicaes web baseadas no
protocoloHTTP,masvalelembrarqueaapinofoicriadasomenteparaesteprotocolo,podendo
serfacilmenteextendidaparaoutros.

Captulo10ServletsPgina72

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

10.2 - A estrutura de diretrios


Aestruturadediretriosamesmautilizadaemumaaplicaoqueusavapginasjspe,
portanto,usaremosomesmoprojeto.

10.3 - Mapeando uma servlet no web.xml


ParafazerummapeamentodeumaURLespecficaparaumaservletnecessriousaro
arquivoweb.xml.
Umavezquechamaraservletpelopacoteenomedaclasse acabariacriandoURLs
estranhasecomplexas,comummapear,porexemplo,umaservletcomonoexemplo,chamada
OiMundoparaonomeservletDeTeste:
<servlet>
<servletname>servletDeTeste</servletname>
<servletclass>br.com.caelum.servlet.OiMundo</servletclass>
</servlet>

nome

EagoracolocaronomeservletDeTesteparaaurl/oi:

<servletmapping>
<servletname>servletDeTeste</servletname>
<urlpattern>/oi</urlpattern>
</servletmapping>

url

Portantosonecessriosdoispassosparamapearumaservletparaumaurl:
1)Definironomeeclassedaservlet
2)Usandoonomedaservlet,definiraurl
Agoraaservletpodeseracessadaatravsdasseguintesurls:
http://localhost:8080/jspteste/oi
Assim que o arquivo web.xml e a classe de servlet de exemplo forem colocados nos
diretrioscorretosbastaconfigurarotomcatparautilizarodiretriodebasecomopadropara
umaaplicaoweb.

10.4 - Exerccios
1)CrieaservletOiMundonopacotecorreto.EscolhaomenuFile,New,Class.

Captulo10ServletsPgina73

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

a)EstendaHttpServlet.
publicclassOiMundoextendsHttpServlet{
}

b)UtilizeoCTRL+SHIFT+OparaimportarHttpServlet.
c)Escrevaaestruturadomtodoservice.Muitocuidadocomonomedosargumentosetc.
Aanotao@Overrideserveparanotificarocompiladorqueestamossobrescrevendoo
mtodoservicedaclassepai,seporalgumacasoerrarmosonomedomtodooutrocarmosa
ordemdosparmetros,ocompiladorirreclamarevocvaiperceberoerroaindaemtempode
compilao.
@Override
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
}

d)Escrevaocdigodomtodoservice.
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException{

Captulo10ServletsPgina74

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

//recebeowriter
PrintWriterout=response.getWriter();
//escreveotexto
out.println("<html>");
out.println("Caelumexplica");
out.println("</html>");
}

2)Abraoarquivoweb.xmlemapeieaurl/oiparaaservletOiMundo.
<servlet>
<servletname>servletDeTeste</servletname>
<servletclass>br.com.caelum.servlet.OiMundo</servletclass>
</servlet>
<servletmapping>
<servletname>servletDeTeste</servletname>
<urlpattern>/oi</urlpattern>
</servletmapping>

3)Testeaurlhttp://localhost:8080/jspteste/oi

10.5 - Erros comuns


Existemdiversoserroscomunsnosexercciosanteriores.Aquivoalgunsdeles:
1)Esquecerdabarrainicialnourlpattern:
<urlpattern>oi</urlpattern>

Captulo10ServletsPgina75

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

2)Digitarerradoonomedopacotedasuaservlet:
<servletclass>br.caelum.servlet.OiMundo</servletclass>

3)Esquecerdecolocaronomedaclassenomapeamentodaservlet:
<servletclass>br.com.caelum.servlet</servletclass>

Captulo10ServletsPgina76

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

10.6 - Init e Destroy


Todaservletdevepossuirumconstrutorsemargumentosparaqueocontinerpossacri
la. Oservletcontinerinicializaaservletcomomtodoiniteausadurantetodooseu
perodoativo,atqueirdesativlaatravsdomtodo destroy,paraentoliberaro
objeto.
Nainicializaodeumaservlet,quandoparmetrospodemserlidosevariveis
comunsatodasasrequisiesdevemserinicializadas.Porexemplo,conexesaobanco
dedadossoestabelecidasnessemomento:

INIT

voidinit(ServletConfigconfig);
DESTROY

Nafinalizao,quandoosrecursosdevemserliberados:

voiddestroy();

Omtodoinitedestroy,quandoreescritos,soobrigadosachamarosuper.init()e
super.destroy() respectivamente. Isso acontece pois um mtodo diferente de um
construtor, quando estendemos uma classe e criamos o nosso prprio construtor da
classe filha, ela chama o construtor da classe pai sem argumentos, preservando a
garantiadachamadadeumconstrutor.
Supondoqueomtodoinit(oudestroy)executaalgumatarefafundamentalemsuaclasse
pai,sevocesquecerdechamarosuperterproblemas.
Oexemploaseguirmostraumaservletimplementandoosmtododeinicializaoe
finalizao.
Osmtodosinitedestroypodemserbemsimples(lembresequesoopcionais):

Captulo10ServletsPgina77

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


packagebr.com.caelum.servlet;
//importsaqui
publicclassOiMundoextendsHttpServlet{
publicvoiddestroy(){
super.destroy();
log("Destruindoaservlet");
}
publicvoidinit()throwsServletException{
super.init();
log("Iniciandoaservlet");
}

//mtodoserviceaqui
}

10.7 - Curiosidades do mapeamento de uma servlet


Existeoutramaneiradeconfigurarservletsnoweb.xml.Osegundotipodemappingo
queespecificadiversasurlsparaapontarparaamesmaaservlet.
Se marcarmos o urlpattern como /teste/*, toda url que acessar o padro
http://localhost:PORTA/jspteste/teste/*iracessarnossaservlet:
<servletmapping>
<servletname>servletDeTeste</servletname>
<urlpattern>/teste/*</urlpattern>
</servletmapping>

Outraopoqueoweb.xmlnosdademarcaraservletparainicializaojuntocoma
aplicaoweb.Paraistobastausarumatagchamada load-on-startup eatribuirumvalor
nonegativo.
<servlet>
<servletname>servletDeTeste</servletname>
<servletclass>br.com.caelum.servlet.OiMundo</servletclass>
<loadonstartup>1</loadonstartup>
</servlet>

RecursoAvanado:loadonstartup
As servlets marcadas com nmeros menores sero inicializadas antes que as de nmeros
maiores.Servletsmarcadascomomesmonmeronopossuemumaordemdeinicializaoque
sejadefinidapelaespecificao.

10.8 - OutputStream x PrintWriter


No nosso primeiro exemplo de servlet usamos o mtodo getWriter para acessar um
PrintWriterdoJava.
OUTPUTSTRE
AM

Pararetornaralgoaocliente,podemosusaraOutputStreamouoPrintWriterque
retornadoatravsdoobjetoresponse.

PrintWriterwriter=response.getWriter();
OutputStreamstream=response.getOutputStream();

Tambm possvel redirecionar o usurio para outra pgina atravs do mtodo


Captulo10ServletsPgina78

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


SENDREDIRE
CT

sendRedirect(String):

response.sendRedirect(novaURL);

Oimportanteaquiquessedevechamarumdostrsmtodosacima.Sevocescreve
algoatravsdowriter,ocabealhoenviadoaoclienteeimpedeoredirecionamento,enquanto
que se voc chamar o mtodo getWriter e depois o getOutputStream ocorrer uma
exceptionpoisnosedeveenviarbytesdepoisdeterabertoumfluxodecaracteres(oencoding
jfoidefinido,nofazmaissentidoenviarbytesquenorepresentemcaracteres).
Para mais informaes sobre bytes e caracteres, Writers e OutputStreams, confira a
nossaapostiladeJavaeOrientaoaObjetos.

10.9 - Parmetros
Toda requisio pode vir acompanhada de parmetros que costumam ser de extrema
importncianodesenvolvimentoparaaweb.

Internethttp

cliente

ServletContiner
1.GET
2.Formemensagens

3.POST

Servlet
Novamensagem
4.Formemensagens

tempo

No mtodo get comum ter uma url que termine com ?parametro=valor
enquantonomtodopostpodemosenviartodososparmetrosatravsdeumformulrioou
simplesmenteescondidosdaurl.
Independentedomtodochamado,osvaloresdosparmetrospodemserlidoscomo
seguintecdigo,quelovalordaidade:
request.getParameter("idade");

Sendoassim,aservletaseguirrecebeumparmetrochamadoidadeeoimprimecomo
resposta:
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{

//recebeowriter
PrintWriterwriter=response.getWriter();
//escreveotexto
writer.println("<html>");
writer.println("Caelumexplicaoparametro:"+
request.getParameter(idade));
writer.println("</html>");
}

OmtodogetParameterretornaumaString,portantotodotipodetratamentodeveser

Captulo10ServletsPgina79

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

feito manualmente. Caso o parmetro no tenha sido passado pela requisio esse mtodo
retornanull.
Paraenviartaisdadospodemosutilizarumlinkcomparmetroatravsdeumarequisio
dotipoget,ouumformulriocomcamposdetexto(mtodogetoupost).
Reparequeemumarquivojsp,asvariveisrequesteresponsetambmexistem,portanto
vocpodeescreveromesmocdigodorequest.getParameterdentrodeumjsp.Fazsentido
fazerisso?Scriptlet?Lerparmetroemjsp?Cdigojavanomeiodocdigohtml?

10.10 - Exerccios
1)CrieaservletTestaParametrosnomesmopacote.

2)EstendaHttpServlet.UtilizeoCTRL+SHIFT+OparaimportarHttpServlet.
3)Escrevaocdigodomtodoservice.
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException{

//recebeowriter
PrintWriterwriter=response.getWriter();
//escreveotexto
Captulo10ServletsPgina80

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


writer.println("<html>");
writer.println("Caelumexplicaoparametro:"+
request.getParameter(idade));
writer.println("</html>");
}

4)Abraoarquivoweb.xmlemapeieaservletTestaParametrosparaaurl/testaidade.
<servlet>
<servletname>idade</servletname>
<servletclass>br.com.caelum.servlet.TestaParametros</servletclass>
</servlet>
<servletmapping>
<servletname>idade</servletname>
<urlpattern>/testaidade</urlpattern>
</servletmapping>

5)Crieumarquivochamadotestaget.jsp:
<html><body>
<ahref=/jspteste/testaidade?idade=24>TestaParmetros</a>
</body></html>

6)Crieumarquivochamadotestapost.jsp:
<html><body>
<formaction=/jspteste/testaidademethod=POST>
<inputtype=textname=idadevalue=24/>
<inputtype=submitvalue=Enviar/>
</form>
</body></html>

7)Testeaurlhttp://localhost:8080/jspteste/testaget.jsp

Captulo10ServletsPgina81

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

8)Testeaurlhttp://localhost:8080/jspteste/testapost.jsp

Captulo10ServletsPgina82

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

10.11 - Exerccios opcionais


1)CrieumanovaservletqueutilizaomtodogetParameterNamesparamostrartodosos
parmetrosqueforamenviados.

Todososparmetros
O mtodo request.getParameterNames() retorna uma Enumeration com todos os nomes de
parmetrosenviados.

10.12 - doGet, doPost e outros


PorcausadaarquiteturadaAPIdasservlets,omtodoserviceopontoinicialdeuma
nova requisio e delega o processo para o representante adequado, de acordo com a
requisio.
Aimplementaodenenhumdosmtodosabaixoobrigatriaseasuaservletextender
aclasseHttpServlet.
Outros dois mtodos comuns para programadores iniciantes na api de servlets e no
protocolohttpsoosquetratamrequisiesespecifcasdeummtodocomooGETouoPOST:
DOGET

doGetresponsvelpelosmtodosGET
protectedvoiddoGet(HttpServletRequest,HttpServletResponse)throws
ServletException,
IOException;

DOPOST

doPostresponsvelpeloPOST
protectedvoiddoPost(HttpServletRequest,HttpServletResponse)throws
ServletException,
IOException;

Captulo10ServletsPgina83

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

service

init

doGet
doPost
doPut
doDelete

destro

ServletContiner
tempo

Uma das boas prticas de programao com servlets diz que devemos implementar
sempreomtodoserviceenoumdosmtodoscomodoGet,doPost,doHeaderetc.

10.13 - Converso de parmetros


Amaiorcomplicao(echatice)dosparmetrosenviadosatravsdoprotocoloHttpque
elesestolimitadosaStrings,portantodevemserconvertidosparaotipodesejado.
Essatarefaficarepetitivaechatasefeitamanualmenteconformemostramosnocdigoa
seguir.UtilizandobibliotecasfamosascomoStruts,Webworketcessatraduoficatransparente
(ouseparada),maissimplesemenosperigosa.
packagebr.com.caelum.servlet;
//importsaqui
publicclassTestaConversaoParametrosextendsHttpServlet{
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException{

//recebeowriter
PrintWriterwriter=response.getWriter();
//escreveotexto
writer.println("<html>");
intidade=Integer.parseInt(request.getParameter(idade));
writer.println("Caelumexplicaoparametro:"+
idade);
writer.println("</html>");
}
}

10.14 - Exerccios
1)CrieaclasseTestaConversaoParametrosnopacotecerto.

Captulo10ServletsPgina84

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

2)Escrevaocdigoquevimosanteriormente:
packagebr.com.caelum.servlet;
//faaimportsaqui,useCTRL+SHIFT+O
publicclassTestaConversaoParametrosextendsHttpServlet{
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException{

//recebeowriter
PrintWriterwriter=response.getWriter();
//escreveotexto
writer.println("<html>");
intidade=Integer.parseInt(request.getParameter(idade));
writer.println("Caelumexplicaoparametro:"+
idade);
writer.println("</html>");
}
}

3)Abraoarquivoweb.xml emapeieaservlet TestaConversaoParametrosparaaurl


conversoridade.
Captulo10ServletsPgina85

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

<servlet>
<servletname>conversor</servletname>
<servletclass>br.com.caelum.servlet.TestaConversaoParametros
</servletclass>
</servlet>
<servletmapping>
<servletname>conversor</servletname>
<urlpattern>/conversoridade</urlpattern>
</servletmapping>

4)Crieumarquivochamadoconverteidade.jsp
<html><body>
<formaction="/jspteste/conversoridade"method="POST">
<inputtype="text"name="idade"value="32"/>
<inputtype="submit"value="Enviar"/>
</form>
</body></html>

5)Testeaurlhttp://localhost:8080/jspteste/converteidade.jsp

6)Oqueaconteceaopassarumnmeroinvlido?
a)Umexemplodenmeroinvlido:

10.15 - Exerccios opcionais


1)TenteutilizaraclasseSimpleDateFormatparafazeroparsingdedatas.

10.16 - Variveis membro


Nossoprximoexemploilustraumexemplosimplesdecontadorutilizandoumavarivel
Captulo10ServletsPgina86

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

membrodeumaservlet.
Damaneiraqueestamostrabalhando,aespecificaodaservletgarantequesexistir
umainstnciadessaservletpormquina,portantosomenteumainstncianototalanoserque
vocrodesuaaplicaoemumcluster.
Baseadonessefatovamoscriar umavarivelmembrochamadacontadorparafixara
idiadequesomenteumainstnciadessaservletexistirnamemriaequeelasobrevivea
requisies:suasvariveismembronosolimpadasapsotrminodasrequisies.
Escolhendoumavariveldotipointparanossocontador,nossaservletdeve:
a)estenderHttpServlet
b)conterumavarivelmembrodotipoint,chamadacontador
c)acadarequisiosomarumnocontadoreimprimironmerodovisitante
E,apartirdostrspontosacima,devemostestarasnossasurlsdiversasvezes,fecharo
browseretentarnovamenteetc.
Baseandosenonossoprimeiroexemplovejamosomtodoservice:
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException{
contador++;//algumproblemaaqui?

//recebeowriter
PrintWriterout=response.getWriter();
//escreveotexto
out.println("<html>");
out.println("Caelumexplica:"+contador+visita.");
out.println("</html>");
}

10.17 - Exerccios
1)CrieaservletContadornopacotecorreto.EscolhaomenuFile,New,Class.

Captulo10ServletsPgina87

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

a)EstendaHttpServlet.
publicclassContadorextendsHttpServlet{
}

b)UtilizeoCTRL+SHIFT+OparaimportarHttpServlet.
c)Adicioneumavarivelmembrodotipoint,chamadacontador.
privateintcontador=0;

d)Escrevaaestruturadomtodoservice.Muitocuidadocomonomedosargumentosetc.
@Override
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
}

e)Escrevaocdigodomtodoservice.
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException{
contador++;//algumproblemaaqui?

//recebeowriter
Captulo10ServletsPgina88

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


PrintWriterout=response.getWriter();

//escreveotexto
out.println("<html>");
out.println("Caelumexplica:"+contador+visita.");
out.println("</html>");
}

2)Abraoarquivoweb.xmlemapeieaurl/contaparaaservletContador.
<servlet>
<servletname>nossoContador</servletname>
<servletclass>br.com.caelum.servlet.Contador</servletclass>
</servlet>
<servletmapping>
<servletname>nossoContador</servletname>
<urlpattern>/conta</urlpattern>
</servletmapping>

3)Testeaurlaseguirduasvezeshttp://localhost:8080/jspteste/conta

4)Passadoalgumtempo,fecheobrowser.Abranovamente.Lembresequeobrowser
oclientequenomandouemnenhummomentooserverexecutarumdestroyemsuaservlet...
portantoaservletaindaestlviva:acesseamesmaurl.Qualoresultado?

Servletseconcorrncia
SINGLETHREA
DMODEL

Muitosprogramadoresquecomeamausarservletsacabamesquecendodosproblemasquea
concorrnciagera....membrosdeumaclassequerepresenteumaservletdevemsertratadoscom
muitocuidadoparaevitarsituaesondeaperdadedadosirocorrer.
ImplementarainterfaceSingleThreadModelnaservletumasadaaltamentedesaconselhada,
Captulo10ServletsPgina89

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

uma vez que poder perder a grande vantagem das servlets de processarem mais de uma
requisioaomesmotempo.
Apartirdaverso2.4daapideservlets,ainterfaceSingleThreadModelfoidepreciada,isto,
nodeveserutilizada.
Portanto, jamais utilize variveis membros em uma servlet, use argumentos de mtodos para
passarvaloresentreosmesmos.

10.18 - HTML e Java: eu no quero cdigo Html na minha servlet!


Foipossvelinferirdosexemplosanterioresquecomplicadoescreverhtmldentrode
umaservletotempotodo.
Vejascomofoidifcillerumparmetrodentrodeumaservleteretornarohtmlparao
clientecomdiversosout.println.
Primeiroficatudomalescritoedifcildeler.Ohtml passa a atrapalhar o cdigo
Java.Depois,quandooresponsvelpelodesigngrficodapginaquiseralteraralgoterque
conhecerjavaparaentenderoqueestescritoldentro...hmm...nopareceumaboasoluo.
Mudouocss,mudouocampo,recompilaaservleteenvianovamenteparaocliente......
umasoluo invivel.

10.19 - Como funciona uma pgina JSP


OwebcontinerinterpretaoarquivoJSP,ocompilaetransformaemumaservlet!Assim
sendo,logoqueoarquivoJSPchamadopelaprimeiravezporumcliente,umaservletqueo
representacriada,aplicandotodososbenefciosdamesmaparaumapginaJSP.

Internethttp
cliente

ServletContiner
1.Primeiravez
Jsp
Compiler

3.Segundavez

tempo

Cria
umaservlet

servlet

Vantagens
Obenefciomaisclaronocolocarumasrieimensadecdigohtmldentrodeumaclasseem
java,oquedificultamuitoaalteraodapginaporumdesigner.Compareocdigodalistagemdo
OiMundocomoservlet.Muitomaissimplesdeeditarohtml:masodesignernocompreendeo
cdigoJava.
DuascoisasqueajudamacombateresseproblemasoosJavaBeansepadresdearquitetura
variadosexistentesnomercado.
Captulo10ServletsPgina90

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

JSP:ficamaisfcilparaodesigneralterarocdigohtml
Servlets:ficamaisfcildeprogramarorientadoaobjetoseemJava

10.20 - Web archive (.war)


WAR

Oprocessopadrodedeploy(envio,submisso)deumaaplicaowebodecriarum
arquivodeextensowar,queumarquivozipcomodiretriobasedaaplicaosendoaraiz
dozip.
Nonossoexemplo,todoocontedododiretriowebdeveriaserincludoemumarquivo
teste.war. Aps compactar o diretrio web com esse nome, iremos efetuar o deploy.
No tomcat, basta copiar o arquivo .war no diretrio TOMCAT/webapps/ e ele ser
descompactado,porfimonovocontextochamadotesteestardisponvel.

10.21 - Exerccios
1)Entrenofilebrowser.
2)Entrenodiretrioworkspace,jspteste,web.

3) Selecione todos os arquivos desse diretrio (CTRL+A), clique da direita e escolha


CreateArchive.Chameoarquivodeteste.zip.Renomeieoparateste.war.

Captulo10ServletsPgina91

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

4)Selecioneoseuarquivoteste.war,vnomenuEditeescolhaCut.

5) V para o diretrio apachetomcat, webapps. Certifiquese que seu tomcat est


rodando.

Captulo10ServletsPgina92

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

6)Coleoseuarquivoaqui(Edit,Paste).Reparequeodiretriotestefoicriado.

7) Agora podemos acessar o projeto atravs da url: http://localhost:8080/teste/lista


elegante.jsp

Captulo10ServletsPgina93

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

10.22 - Quando acontece um erro em uma servlet


Imaginefazerotratamentodeerroemnossasservletsassimcomofizemoscomnossos
jsps:nada.Seriapossvel?
RetomandoocursoFJ11ouosfundamentosdalinguagemetecnologiaJava,omtodo
servicefoidefinidonaclasseHttpServleteportantospodemosjogarasexceptionsquetal
mtododefiniu.
Olhando de perto a assinatura desse mtodo encontramos IOException e
ServletException. Lembramostambmquetodos oserrosdotipo unchecked(queestendem
RuntimeException)noprecisamserdeclaradosnothrowsportantonoprecisamostratlos.
MasoquefazercomerrosdotipoSQLException?Ouqualqueroutroerroqueestenda
Exception no atravs de RuntimeException (seja um checked exception) diferente de
IOException e ServletException? No podemos jogar. Porque? Pois a classe pai definiu o
mtodosemessethrows.
ComonoJavastemosduasopes:oujogamosaexceptionouusamosumtryecatch
restaumanicaopo...

10.23 - O try e catch


Portantocomservletsahistriajoutra.Temosque'tratar'oserrosantesdejoglos
adiante.
Aquibastalembrardaassinaturadomtodoservice(oudoGet,doPostetc),elespermite
fazerothrowdeServletException,IOExceptione(claro)RuntimeException.
AclasseServletExceptionfoicriadaparaserutilizadacomowrapperparaasnossas
exceptions,isto,devemos'embrulhar'nossaexceoemumaServletExceptionantesde
sairdonossomtodo.Porexemplo:
try{
java.sql.DriverManager.getConnection("jdbc:teste:invalido","usuario","senha");
}catch(SQLExceptione){
thrownewServletException(e);
}
Captulo10ServletsPgina94

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Neste caso, SQLException est dentro de ServletException. Repare que essa


tcnica de injetar uma causa de uma exception dentro de outra amplamente utilizada na
bibliotecapadroJavaeemmuitasextenses.

ServletException
SQLException

OqueacontecequandooservletcontinerpegaumaServletException?
Primeiroeleverificaseexistiualgumacausa(rootcause)paraessaexception,sesim,ele
usaessacausaparaprocuraromapeamentonoweb.xml.Senoexistirnenhumacausaele
procuraServletExceptionnoarquivoweb.xml.
Portantonocasoquedefinimosacima,oservletcontinerprocuraromapeamentode
SQLExceptione,repare,jfizemosissonoexemplodojsp!
Nofinalocontroledeerrocentralizadonoservletcontinerajudamuitopoisbastamapear
umaoumaispginasdeerronoweb.xmlepronto,todoerrodessetipo,sejaemjspsouservlets,
serredirecionadoparanossapginadeerro.

10.24 - Exerccios
1)Crieumaservletparatestarocontroledeexceptions:
a)Pacote:br.com.caelum.servlet,classeTestaErro

b)EstendaHttpServlet
Captulo10ServletsPgina95

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

c)Mtodoservice:
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
try{
java.sql.DriverManager.getConnection("jdbc:teste:invalido","usuario","senha");
}catch(SQLExceptione){
thrownewServletException(e);
}
}

2)CrieaservletchamadaTestaErronoseuweb.xml:
<servlet>
<servletname>TestaErro</servletname>
<servletclass>br.com.caelum.servlet.TestaErro</servletclass>
</servlet>

3)Crieaurl/testaerroservletparaaservletTestaErronoseuweb.xml:
<servletmapping>
<servletname>TestaErro</servletname>
<urlpattern>/testaerroservlet</urlpattern>
</servletmapping>

4)Acesseaurlhttp://localhost:8080/jspteste/testaerroservlet

response.sendError()eresponse.setStatus()
Existem dois mtodos sendError que podemos utilizar e esto na interface
HttpServletResponse.Elessoosmtodosresponsveisporlidarcomasexceesemestilo
programtico.
Osdoismtodosrecebemumintcomocdigodoerroqueocorreu(constantesestodisponveis
atravsdainterface HttpServletResponse).Osegundomtodorecebetambmumavarivel
dotipoStringquerepresentaamensagemdeerro.
OmtodosetStatusquerecebeumintfuncionadomesmojeitomasnogeraoprocessodeerro
correspondente,somentemarcanocabealhooqueocorreu.

10.25 - Servlet para adicionar contatos no banco


Captulo10ServletsPgina96

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

muitoimportanteapartirdeagora queoalunopercebasercapazdeadicionarum
contatonobancodedadosutilizandotudooquevimosatomomento.
Imagineummtodoservicequerecebetrsparmetros:nome,emaileendereo.
Sendoextremamentelgicosbasta:
lerosparmetrosepreencherumobjetodotipoContato
instanciarContatoDAOeadicionartalobjetonobanco
mostrarumamensagemdeokparaocliente
Portantovamosaoexerccio...

10.26 - Exerccio
1)CrieumaservletchamadaAdicionaContatoServletnopacotebr.com.caelum.servlet

2)NoseesqueadeextenderaclasseHttpServlet.
publicclassAdicionaContatoServletextendsHttpServlet{

3)Coloqueomtodoservice.
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{

Captulo10ServletsPgina97

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

4)UseCTRL+SHIFT+Oparafazerosimportsnecessrios.
5)CrieumobjetodotipoContato,chameodecontato.
Contatocontato=newContato();
6)Atravsdavarivelrequestleiaoparmetronomeeuseseuvalorparachamaro
setterdocontato.Faaomesmoparaoscamposemaileendereo.
Stringnome=request.getParameter(nome);
Stringendereco=request.getParameter(endereco);

Stringemail=request.getParameter(email);
contato.setNome(nome);
contato.setEndereco(endereco);
contato.setEmail(email);

7)CrieumobjetodotipoContatoDao,chameodedaoeutilizeasvariveiscontatoedao
paraadicionarocontatoaobancodedados.
try{
ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);
}catch(SQLExceptione){
thrownewServletException(e);

}
9)Atravsdoresponse.getWriter()mostreumamensagemdeokparaocliente.
PrintWriterwriter=response.getWriter();
writer.println("<html>");
writer.println("ContatoAdicionado");
writer.println("</html>");

10)MapeieaclasseAdicionaContatoServletnoweb.xml.
<servlet>
<servletname>adicionaContato</servletname>
<servletclass>br.com.caelum.servlet.AdicionaContatoServlet</servletclass>
</servlet>

<servletmapping>
<servletname>adicionaContato</servletname>
<urlpattern>/testaadiciona</urlpattern>
</servletmapping>

11)Faaumarquivotestaadicionacontato.jsp.
<html><body>
Digiteseusdadosepressioneoboto:<br/>
<formaction="testaadiciona"method="POST">
Nome: <inputtype="text"name="nome"/><br/>
Email:
<inputtype="text"name="email"/><br/>
Endereo:
<inputtype="text"name="endereco"/><br/>
<inputtype="submit"value="Enviar"/>
</form>
</body></html>
<html>

12)Testeaurlhttp://localhost:8080/jspteste/testaadicionacontato.jsp

Captulo10ServletsPgina98

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Captulo10ServletsPgina99

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

11

11

Servlet e JSP API

Vivemos todos sob o mesmo cu, mas nem todos temos o


mesmo horizonte.
KonradAdenauer

NestecaptulovociraprenderautilizaroutrosrecursosavanadosdaAPIdeservlets.

11.1 - Incio e trmino da sua aplicao


O que acontece se desejamos executar algum cdigo no nicio e trmino da nossa
aplicao?Isso,quandoonossocontextoinicializadoedestrudo?
Umexemploclssicoainicializaodasconexescomobancodedados,dosarquivos
delogouderecursosexternosaosistema.
SERVLET
CONTEXT
LISTENER

AapideservletsdisponibilizaumainterfacechamadaServletContextListenercapazde
recebernotificaesdessesdoiseventos.
Aoimplementartalinterface,precisamosescreverdoismtodos,umparainicializaoe
outroparaadestruiodenossaaplicao(quetambmserchamadoservletcontext,contexto
deservletsouainda,escopodeaplicao).
publicvoidcontextDestroyed(ServletContextEventevent){
//...
}
publicvoidcontextInitialized(ServletContextEventevent){
//...
}

Podemos,porexemplo,manteremumavarivelomomentodeinicializaodanossa
aplicao:
Dateinicializacao=newDate();
ESCOPO DE
APLICAO

Mascomoveresseresultadoatravsdeumaservlet?Precisamoscolocaresseobjetoem
algumescopoquesejaomesmoparatodososusuriosetodasasservlets,issoexiste?Sim:o
escopodeaplicao.

SERVLETCONTE
XT

ServletContextcontext=event.getServletContext();

Utilizamostalescopocomoummapa(apalavramapadosfsicos,querdizerquepara
cadachavetemumvalorassociado,nsusamosnormalmenteapalavradicionrio,mascomo
emjavausaapalavramaptraduzimosparamapa)portantodefinimosumachavequalquerpara
nossoobjeto,porexemplo:br.com.caelum.inicializacaoeutilizamosomtodosetAttributepara
atribuiroobjetoreferenciadopelavarivelinicializaoparatalchave:
Dateinicializacao=newDate();
ServletContextcontext=event.getServletContext();
context.setAttribute("inicializacao",inicializacao);
Captulo11ServleteJSPAPIPgina100

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

LISTENER

Falta ainda configurar nossa aplicao para procurar por tal Listener e registralo
devidamente. Como isso na realidade uma configurao, iremos cadastrar um listener no
nossoweb.xml:

<listener>
<listenerclass>br.com.caelum.servlet.ControleDeAplicacao</listenerclass>
</listener>

11.2 - Exerccios
1)Crieaclasse ControleDeAplicacao nopacotebr.com.caelum.servlet.Escolhao
menuFile,New,Class.

a)ImplementeServletContextListener.
publicclassControleDeAplicacaoimplementsServletContextListener{
}

b)UtilizeoCTRL+SHIFT+O
c)ResolvaosproblemasqueocompiladorreclamautilizandooCTRL+1nalinhadoerro:
implementeosdoismetodos:.
publicvoidcontextDestroyed(ServletContextEventevent){
}
publicvoidcontextInitialized(ServletContextEventevent){
Dateinicializacao=newDate();
ServletContextcontext=event.getServletContext();
context.setAttribute("inicializacao",inicializacao);
}

2)Abraoarquivoweb.xmlemapeieoseulistener.
<listener>
<listenerclass>br.com.caelum.servlet.ControleDeAplicacao</listenerclass>
</listener>

11.3 - getServletContext()
TodaservletpossuiummtodochamadogetServletContextqueretornaumareferncia
Captulo11ServleteJSPAPIPgina101

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

paraonossocontextodeaplicao:
ServletContextaplicacao=getServletContext();

Apartirdabastabuscarovalordoatributoinicializao:
Dateinicializacao=(Date)aplicacao.getAttribute("inicializacao");

Eimprimirosresultados:
Dateagora=newDate();
longdiferenca=agora.getTime()inicializacao.getTime();
doubleminutos=diferenca/(60*1000.0);
PrintWriterwriter=response.getWriter();
writer.println("<html>");
writer.println("Momentoinicial:"+inicializacao+"<br/>");
writer.println("Momentoatual:"+agora+"<br/>");
writer.println("Minutos:"+minutos+"<br/>");
writer.println("</html>");

11.4 - Exerccios
1)CrieaclasseAcessaAplicacaonopacotebr.com.caelum.servlet.
a)EstendaHttpServlet.UtilizeCTRL+SHIFT+O.
b)Escrevaomtodoservice:
@Override
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException{
ServletContextaplicacao=getServletContext();
Dateinicializacao=(Date)aplicacao.getAttribute("inicializacao");
Dateagora=newDate();
longdiferenca=agora.getTime()inicializacao.getTime();
doubleminutos=diferenca/(60*1000.0);
PrintWriterwriter=response.getWriter();
writer.println("<html>");
writer.println("Momentoinicial:"+inicializacao+"<br/>");
writer.println("Momentoatual:"+agora+"<br/>");
writer.println("Minutos:"+minutos+"<br/>");
writer.println("</html>");
}

2)Mapeieasuaservletparaaurl/testaaplicacao:
<servlet>
<servletname>acessaAplicacao</servletname>
<servletclass>br.com.caelum.servlet.AcessaAplicacao</servletclass>
</servlet>
<servletmapping>
<servletname>acessaAplicacao</servletname>
<urlpattern>/testaaplicacao</urlpattern>
</servletmapping>

Captulo11ServleteJSPAPIPgina102

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)Testeaurlhttp://localhost:8080/jspteste/testaaplicacao.

11.5 - Acessando a aplicao no jsp


Ecomofazemosparaacessaroescopodeaplicaononossojsp?
Simples,umadasvariveisquejexisteemumjspsechamaapplication,algocomo:
ServletContextapplication=getServletContext();

Portantopodemosutilizalaatravsdescriptlet:
<%=application.getAttribute("inicializacao")%><br/>

Comojvimosanteriormente, ocdigodotiposcriptletpodesermalficoparanossa
aplicao,sendoassimvamosutilizarexpressionlanguageparaacessarumatributodoescopo
aplicao:
AcessandocomEL:${inicializacao}<br/>

Repare que a expression language ir procurar tal atributo no s no escopo do


application,comoveremosmaisafrente.Paradeixarclaroquevocprocura umavariveldo
escopodeaplicao,usamosavarivelimplcitachamadaapplicationScope:
Acessandoescopoapplication:${applicationScope['inicializacao']}<br/>

11.6 - Exerccios
1)Crieumarquivochamadotestaaplicacao.jsp.
<html>
AcessandocomEL:${inicializacao}<br/>
Acessandoescopoapplication:${applicationScope['inicializacao']}<br/>
Acessandoapplicationcomscriptlet:<%=application.getAttribute("inicializacao")%><br/>
</html>

2)Testeaurlhttp://localhost:8080/jspteste/testaaplicacao.jsp

Captulo11ServleteJSPAPIPgina103

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

11.7 - Propriedades de pginas jsp


Comodizerqualoencodingdenossosarquivosjspdeumamaneiraglobal?Comonos
protegerdeprogramadoresiniciantesemnossaequipeedesabilitarocdigoscriptlet?Como
adicionarumarquivoantese/oudepoisdetodososarquivosjsps?Oudetodososjspsdentrode
determinadodiretrio?
Pararesponderessaseoutrasperguntas,aapidejspresolveupossibilitardefiniralgumas
tagsnonossoarquivoweb.xml.
Porexemplo,paradesativarscripting:
<scriptinginvalid>false</scriptinginvalid>

Ativarexpressionlanguage(quejvemativado):
<elignored>false</elignored>

Determinaroencodingdosarquivosdeumamaneiragenrica:
<pageencoding>ISO88591</pageencoding>

Incluirarquivosestaticamenteantesedepoisdeseusjsps:
<includeprelude>/antes.jspf</includeprelude>
<includecoda>/depois.jspf</includecoda>

Ocdigoaseguirmostracomoaplicartaiscaractersticasparatodososjsps,repareque
atagurlpatterndeterminaogrupodearquivoscujosatributosseroalterados:
<jspconfig>
<jsppropertygroup>
<displayname>todososjsps</displayname>
<description>configuracoesdetodososjsps</description>
<urlpattern>*.jsp</urlpattern>
<scriptinginvalid>false</scriptinginvalid>
<elignored>false</elignored>
<pageencoding>ISO88591</pageencoding>
<includeprelude>/antes.jspf</includeprelude>
<includecoda>/depois.jspf</includecoda>
</jsppropertygroup>
</jspconfig>

Captulo11ServleteJSPAPIPgina104

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

12

Model View Controller

12

Ensinar aprender duas vezes.


JosephJoubert

Opadroarquiteturalfeijocomarrozeorequestdispatcher.

12.1 - Servlet ou JSP?


ColocartodoHTMLdentrodeumaServletrealmentenopareceamelhoridia.Oque
acontecequandoprecisamosmudarodesigndapgina?Oseudesignernovaitertempode
editarsuaServlet,recompillaecoloclanoservidor.
Umaidiamaisinteressanteusaroquebomdecadaumdosdois.
OJSPfoifeitoapenasparaapresentaroresultado,eelenodeveriafazeracessosa
bancoseoutros.IssodeveriaestarnaServlet.
REGRAS DE
NEGCIO

OidealentoqueaServletfaaotrabalhosujoerduo,eoJSPapenasapresente
essesresultados.AServlet possui a lgica de negcios(ouregrasdenegcio)eoJSP
tem a lgica de apresentao.
ImagineocdigodomtododaservletAdicionaContatoServlet:

protectedvoidservice(
HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
//log
System.out.println("Tentandocriarumnovocontato...");
//acessaobean
Contatocontato=newContato();
//chamaossetters
...

//adicionaaobancodedados
ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);

//ok....visualizao
request.getWriter().println("<html>Ok</html>");
}

Reparequenofinaldonossomtodomisturamosocdigohtml,portantooquequeremos
extrairdocdigoacimajustamenteessaltimalinha.
Seriamuitomaisinteressanteparaoprogramadoreparaodesignerterumarquivojsp
chamadocontatoadicionado.jspcomohtml:
<html>
Captulo12ModelViewControllerPgina105

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


Ok
</html>

Aferramentaquebuscamosumredirecionadorderequisies,capazdeenviaruma
requisioparaumnovorecursodoservidor:umjsp,umaservlet,umaimagemetc.
REQUEST
DISPATCHER

Podemos usar o recurso de dispatch das requisies para que o JSP s seja
chamadodepoisdequesuasregrasforamexecutadas.

Cliente

servlet

JSP

servlet
JSP

BD

Pega um
(select)

usurio

12.2 - Request dispatchers


Poderamosmelhoraranossaaplicaosetrabalhssemoscomocdigojavanaservlet
edepoisocdigohtmlemumapginajsp.
Aapidaservletnospermite fazertalredirecionamento.Bastaconhecermosaurlque
queremosacessarepodemosusaroqueforachamadodeRequestDispatcherparaacessar
outrorecursoweb,sejaesserecursoumapginajspouumaservlet:
RequestDispatcherrd=request.getRequestDispatcher(/contatoadicionado.jsp);
rd.forward(request,response);
return;

Agorapodemosfacilmenteexecutaralgicadenossaaplicaowebemumaservlete
entoredirecionarparaumapginajsp,ondevocpossuiseucdigohtml.

Forwardeinclude
Omtodoforwardspodeserchamadoquandonadaforaescritoparaasada.Nomomentoque
algoforescritoficaimpossvelredirecionarousuriopoisoprotocolohttpnopossuimeiosde
voltaratrsnaquiloquejfoienviadoaocliente.
ExisteoutromtododaclasseRequestDispatcherquerepresentaainclusodepginaenoo
redirecionamento.Essemtodosechamaincludeepodeserchamadoaqualquerinstantepara
acrescentaraoresultadodeumapginaosdadosdeoutra.
Captulo12ModelViewControllerPgina106

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Apesardosdoismtodospareceremteiselesnocostumamserusadosanosernapartede
controladordeumaaplicaowebutilizandoopadromvc.

12.3 - Exerccio
1) Altere sua servlet AdicionaContatoServlet para que aps a execuo da lgica de
negcios,ofluxodarequisiosejaredirecionadoparaumjspchamadocontatoadicionado.jsp:
a)Substituaaslinhas:
PrintWriterwriter=response.getWriter();
writer.println("<html>");
writer.println("ContatoAdicionado");
writer.println("</html>");

por:
RequestDispatcherrd=request.getRequestDispatcher(/contatoadicionado.jsp);
rd.forward(request,response);
return;

b)Faaoarquivocontatoadicionado.jsp.
<html>
ContatoAdicionado
</html>

2)Testeaurl:http://localhost:8080/jspteste/testaadicionacontato.jsp

12.4 - Resultado
Percebaquejatingimosumresultadoquenoerapossvelanteriormente.
MuitosprojetosantigosqueforamescritosemJava,utilizavamsomentejspouservletseo
resultadoeraassustador.Comocontedomostradoatessemomento,possvelescreverum
cdigocommuitomaisqualidadedoqueessesprojetos.

Captulo12ModelViewControllerPgina107

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

12.5 - Melhorando o processo


Aqui temos vrias servlets acessando o banco de dados, trabalhando com osdaos e
pedindoparaqueoJSPapresenteessesdados,odiagramaaseguirmostraarepresentaodo
AdicionaContatoServletapsamodificaodoexerccioanterior.

Cliente

AdicionaContatoServlet
contato-adicionado.jsp

ContatoDao

BD

Agoratemosoproblemadetermuitasservlets.Paracadalgicadenegcios,teramos
uma servlet diferente, que significa oito linhas de cdigo no web.xml... algo abominvel em
projeto de verdade. Imagine dez classes de modelo, cinco lgicas diferentes, isso totaliza
quatrocentaslinhasdeconfigurao.
Sabemosdaexistnciadeferramentasparagerartalcdigoautomaticamente,masisso
noresolveoproblemadacomplexidadedeadministrartantasservlets.
Utilizaremosumaidiaquediminuiraconfiguraoparaapenasoitolinhas:colocartudo
numa Servlet s,edeacordocomqueargumentosoclientenospassa,decidimosoque
executar.TeramosaumaServletmonstro.
packagebr.com.caelum.servlet;
//importsaqui
publicclassTesteServletextendsHttpServlet{
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException{
StringbusinessLogic=request.getParameter("business");
Contatocontato=newContato();
ContatoDAOdao;
contato.setNome(request.getParameter("nome"));
contato.setEndereco(request.getParameter("endereco"));
contato.setEmail(request.getParameter("email"));
try{
dao=newContatoDAO();
}catch(SQLExceptione){
Captulo12ModelViewControllerPgina108

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


thrownewServletException(e);
}
if(businessLogic.equals("AdicionaContato")){
try{
dao.adiciona(contato);
}catch(SQLExceptione){
thrownewServletException(e);
}
}elseif(businessLogic.equals("ListaContato")){
try{
dao.adiciona(contato);
}catch(SQLExceptione){
thrownewServletException(e);
}
}
}

}
Paracadaaoteramosumif/elseif,ficariagiganteno?
Podemosmelhorarfazendorefactoringdeextrairmtodos.Mascontinuariagigante.
Seria melhor colocar cada regra de negcio (como inserir aluno, remover aluno, fazer
relatriodeumaluno,etc...)emumaclasseseparada.Cadaao(regradenegcio)emnossa
aplicaoestariaemumaclasse.
Entovamosextrairclasses:
if(businessLogic.equals("AdicionaContato")){
newAdicionaContato().execute(request,response);
}elseif(businessLogic.equals("ListaContato")){
newListaContatos().execute(request,response);
}

Pormacadalgicanova,lgicaremovida,alteraoetc,temosquealteraressaservlet.
Issotrabalhosoemuitopropensoaerroshumanos.
Reparequeocdigoacimaumswitch!EswitchemJavatoruimquesubstitumos
porpolimorfismo,comoveremosaseguir.
Vamostentargeneralizarento,queremosexecutaroseguintecdigo:
Stringbusiness=request.getParameter(business);
newbusiness().execute(request,response);

Entretantonopodemos,poisbusinessonomedeumavarivel.Onossoproblema
quessabemosoquevamosinstanciaremtempodeexecuoenoemtempodecompilao.
Temoscomofazerisso?Sim.
StringbusinessLogicClassName=br.com.caelum.mvc.+
request.getParameter("business");
ClassbusinessLogicClass=Class.forName(businessLogicClassName);

Maseagoracomoinstanciaressaclasse?
Objectobj=businessLogicClass.newInstance();

Ecomochamaromtodoexecute?Reparequeusamosomesmomtodoemtodasas
lgicasdenegcio:issoumpadroquedefinimos.Quandoissoaparece,normalextrairuma
Captulo12ModelViewControllerPgina109

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

interfacecomumatodasessasclasses:BusinessLogic.
BusinessLogicbusinessLogicObject=
(BusinessLogic)businessLogicClass.newInstance();
businessLogicObject.execute(request,response);

Algumprecisacontrolarentoqueaoserexecutadaparacadarequisio,equeJSP
ser utilizado. Podemos usar uma servlet para isso, e ento ela passa a ser a servlet
controladoradanossaaplicao,chamandoaaocorretaefazendoodispatchparaoJSP
desejado.
Reparenafiguraaseguirque,apesardosJSPsnoestaremacessandoapartedasua
modelagem,isto,asclassesquediretaouindiretamentemexemnobancodedados,eletem
uma referncia a um Usurio, para poder colocar suas informaes na pgina resultante.
Chamamosissodepushdasinformaes.

Cliente
controladora
JSP
JSP
Usurio
Referncia ao us
urio X

BD

JSP

Ao de pegar info
de um usurio
Formulrio
para
ver info do usurio

Captulo12ModelViewControllerPgina110

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

13

Construindo um Framework MVC

13

H duas tragdias na vida. Uma a de no obter tudo o que se


deseja ardentemente; a outra, a de obt-lo
BernardShaw

NoexistemistrioportrsdeumframeworkMVC.VamoscriaraquioSYPMVCFrameworkSimple
YetPorwerfulMVCFramework.

13.1 - Nossa interface de execuo


Paraonossopatterndecomando,quetodasaslgicasiroseguir,definiremosaseguinte
interfacedeexecuo:
publicinterfaceBusinessLogic{
voidexecute(HttpServletRequestreq,HttpServletResponseres)throwsException;
}

Pareceumaservletcerto?Aprimeiravistasim,maspercebaquenotemnadacomuma
servlet.EstendeServlet?Possuimtodochamadoservice?No.
Vamoscriarumalgicadenegciodeexemploparatestlaembreve:
publicclassTestaMVCimplementsBusinessLogic{
publicvoidexecute(HttpServletRequestreq,HttpServletResponseres)
throwsException{
System.out.println(Executandoalogicaeredirecionando...);
RequestDispatcherrd=req.getRequestDispatcher("/testamvc.jsp");
rd.forward(req,res);
}
}

13.2 - Exerccios
1)Crieasuainterfacenopacotebr.com.caelum.mvc:
publicinterfaceBusinessLogic{
voidexecute(HttpServletRequestreq,HttpServletResponseres)throwsException;
}

2) Crie uma implementao da interface BusinessLogic, nossa classe TestaMVC, no


mesmopacote:
publicclassTestaMVCimplementsBusinessLogic{
Captulo13ConstruindoumFrameworkMVCPgina111

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

publicvoidexecute(HttpServletRequestreq,HttpServletResponseres)
throwsException{
System.out.println(Executandoalogicaeredirecionando...);
RequestDispatcherrd=req.getRequestDispatcher("/testamvc.jsp");
rd.forward(req,res);
}
}

13.3 - Criando um controlador e um pouco mais de reflection


NossoobjetivoqueonomedaclassequeimplementaainterfaceBusinessLogicseja
passada como parmetro por HTTP. Esse argumento ser o business. Nossa Servlet
controladoraresponsvelporinstanciaressaclasseechamaroseumtodoexecute.
Vamoscomearcomadeclaraodaservletepegaronomedaclassecomoparmetro:
publicclassControllerServletextendsHttpServlet{
publicvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
StringbusinessLogicClassName=request.getParameter("business");

Nessemomentotemosonomedaclassequeprecisamosinstanciar.
Quando vimos JDBC aprendemos que a classe Class possui um mtodo esttico
chamadoforNamequecarregaumadeterminadaclasse.Almdecarregaraclasse,oforName
devolveumarefernciaaumobjetodotipo Class querepresentaaquelaclasse.issoque
iremosfazer:
ClassbusinessLogicClass;
try{

businessLogicClass=Class.forName(businessLogicClassName);
}catch(ClassNotFoundExceptione){

thrownewServletException("Noencontroaclasse"+
businessLogicClassName);
}

Essa String businessLogicClassName deveserprecedidadonomedopacoteao


qualessaclassepertence,comobr.com.caelum.mvc.AdicionaContatoporexemplo.
Casoaclassenosejaencontrada,umaexceodisparada.
Agoraquetemosumarefernciaparaaoobjetoquerepresentaessaclasse,podemos
verificarseessaclasserealmenteimplementaanossainterface BusinessLogic.Casono
implemente,disparamosumaexceo:
if(!BusinessLogic.class.isAssignableFrom(businessLogicClass)){
thrownewServletException("classenoimplementaainterface:"
+businessLogicClassName);
}

Um objeto do tipo Class possui um mtodo newInstance, que tenta instanciar um


objetodaqueletipousandooconstrutorpblicoquenorecebenenhumargumentodaclasse.
Casooconstrutornoexista,nosejapblico,oulanceuma Exception,umaexceoser
lanada:

Captulo13ConstruindoumFrameworkMVCPgina112

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


BusinessLogicbusinessLogicObject;
try{
businessLogicObject=(BusinessLogic)businessLogicClass.newInstance();
}
catch(InstantiationExceptione){
thrownewServletException(e);
}
catch(IllegalAccessExceptione){
thrownewServletException(e);
}

Reparequeestamos instanciando um objeto para cada nova requisio,o


quedeixaousuriodonossoframeworklivredapreocupaodeestarsendoacessadopormais
deumaThreadaomesmotempo.Issopossibilitaousodeatributosdeinstnciasemmaiores
problemas,almdetirarosaboresttico/proceduraldasservlets.
Tendoemmosoobjetoquerepresentaanossalgicadenegciosaserexecutada,
bastachamarmosomtododeexecuodanossainterface,enosprepararmosparaqualquer
problema:
try{
businessLogicObject.execute(request,response);
}
catch(Exceptione){
thrownew
ServletException(Algicadenegcioscausouuma
exceo,e);
}
}
}

Eassimterminaonossocontrolador,queagoradelegouaresponsabilidadedeexecuo
paraanossalgicadenegcios.
Ocdigocompletocomtodootratamentodeerroficabemgrande,porissousaremos
algosimplificadonoexerccio.
publicclassControllerServletextendsHttpServlet{
publicvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
StringbusinessLogicClassName=request.getParameter("business");
ClassbusinessLogicClass=null;
try{
businessLogicClass=Class.forName(businessLogicClassName);
}catch(ClassNotFoundExceptione){
thrownewServletException("Noencontroaclasse"+
businessLogicClassName);
}
if(!BusinessLogic.class.isAssignableFrom(businessLogicClass)){
thrownewServletException("classenoimplementaainterface:"
+businessLogicClassName);
}
BusinessLogicbusinessLogicObject=null;
try{
businessLogicObject=(BusinessLogic)businessLogicClass.newInstance();
}
catch(InstantiationExceptione){
thrownewServletException(e);
}
catch(IllegalAccessExceptione){
Captulo13ConstruindoumFrameworkMVCPgina113

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


thrownewServletException(e);
}
try{
businessLogicObject.execute(request,response);
}
catch(Exceptione){
thrownew
ServletException(Algicadenegcioscausouuma
exceo,e);
}
}
}

13.4 - Configurando o web.xml


VamosconfigurarparaqueoControllerrespondaaURL/mvc:
<webapp>
<servlet>
<servletname>syp</servletname>
<servletclass>br.com.caelum.mvc.ControllerServlet</servletclass>
</servlet>
<servletmapping>
<servletname>syp</servletname>
<urlpattern>/mvc</urlpattern>
</servletmapping>
</webapp>

13.5 - Exerccios
1)CriesuaservletchamadaControllerServletnopacotebr.com.caelum.mvc:
publicclassControllerServletextendsHttpServlet{
publicvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
StringbusinessLogicClassName="br.com.caelum.mvc."+
request.getParameter("business");
try{
ClassbusinessLogicClass=Class.forName(businessLogicClassName);
if(!BusinessLogic.class.isAssignableFrom(businessLogicClass)){
thrownewServletException("classenoimplementaainterface:"
+businessLogicClassName);
}
BusinessLogicbusinessLogicObject=(BusinessLogic)
businessLogicClass.newInstance();
businessLogicObject.execute(request,response);
}catch(Exceptione){
thrownewServletException(Algicadenegcioscausouumaexceo,
e);
}
}
}

2)Mapeieaurl/mvcparaessaservletnoarquivoweb.xml.
Captulo13ConstruindoumFrameworkMVCPgina114

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

<servlet>
<servletname>syp</servletname>
<servletclass>br.com.caelum.mvc.ControllerServlet</servletclass>
</servlet>
<servletmapping>
<servletname>syp</servletname>
<urlpattern>/mvc</urlpattern>
</servletmapping>

3)Faaumarquivojspchamadomvcok.jsp
<html>
<h1>MVCOK</h1>
</html>

3) Crie uma implementao de lgica chamada TestaMVC que imprime algo no


consoleeredirecionaparaojspchamado/mvcok.jsp.
publicclassTestaMVCimplementsBusinessLogic{
publicvoidexecute(HttpServletRequestreq,HttpServletResponseres)
throwsException{
System.out.println("Executandoalogicaeredirecionando...");
RequestDispatcherrd=req.getRequestDispatcher("/mvcok.jsp");
rd.forward(req,res);
System.out.println("teste...");
}
}

4)Testeaurlhttp://localhost:8080/jspteste/mvc?business=TestaMVC

13.6 - Exerccios
Captulo13ConstruindoumFrameworkMVCPgina115

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

1) Crie uma nova classe chamada AdicionaContatoLogic no mesmo pacote


br.com.caelum.mvc.DevemosimplementarainterfaceBusinessLogicedurantesuaexecuo
adicioneumcontatonobanco.

//importaquiCTRL+SHIFT+O
publicclassAdicionaContatoLogicimplementsBusinessLogic{
publicvoidexecute(HttpServletRequestrequest,
HttpServletResponseresponse)throwsException{

System.out.println("Executandoalogicaeredirecionando...");

Contatocontato=newContato();
contato.setNome(request.getParameter("nome"));
contato.setEndereco(request.getParameter("endereco"));
contato.setEmail(request.getParameter("email"));
try{
ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);
}catch(SQLExceptione){
thrownewServletException(e);
}
RequestDispatcherrd=
request.getRequestDispatcher("/listaelegante.jsp");
rd.forward(request,response);
System.out.println("teste...");
}
}

2) Crie um formulrio chamado /testaadicionamvc.jsp atravs do mtodo post que


chamaalgicacriadanoexerccioanterior.
<html><body>
Digiteseusdadosepressioneoboto:<br/>
<formaction="mvc"method="POST">
Nome: <inputtype="text"name="nome"/><br/>
Email:<inputtype="text"name="email"/><br/>
Endereo:<inputtype="text"name="endereco"/><br/>
<inputtype="hidden"name="business"value="AdicionaContatoLogic">
<inputtype="submit"value="Enviar"/>
</form>
</body></html>

3)Testeaurlhttp://localhost:8080/jspteste/testaadicionamvc.jsp

Captulo13ConstruindoumFrameworkMVCPgina116

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Olheseuconsole:

13.7 - Exerccios opcionais


1)CrieumalgicachamadaRemoveContatoLogicetesteamesmaatravsdeumlinkna
listagemquevoccriounaauladeservlets.

13.8 - Model View Controller


VIEW

Generalizandoomodeloacima,podemosdarnomesacadaumadaspartesdessanossa
arquitetura.Quemresponsvelporapresentarosresultadosnapginawebchamadode
Apresentao(View).

CONTROLLER

Aservlet(eauxiliares)quefazosdispatchsparaquemdeveexecutardeterminadatarefa
chamadadeControladora(Controller).

MODEL

Asclassesquerepresentamsuasentidades,easqueteajudamaarmazenarebuscaros
dados,sochamadasdeModelo(Model)

MVC

Esses trs formam um padro arquitetural chamado de MVC, ou Model View


Controller. Ele pode sofrer variaes de diversas maneiras. O que o MVC garante a
separaodetarefas,facilitandoassimareescritadealgumaparte,eamanutenodocdigo.
OfamosoStrutsajudavocaimplementaroMVC,poistemumacontroladorajpronta,
comumasriedeferramentasparateauxiliar.OHibernatepodeserusadocomoModel,por
exemplo.EcomoViewvocnoprecisausarsJSP,podeusaraferramentaVelocity,por
exemplo.

Captulo13ConstruindoumFrameworkMVCPgina117

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Cliente
View
Controller

JSP
JSP

Model

JSP

BD

13.9 - Lista de tecnologias: camada de controle


Aseguirvocencontraumalistacomdiversasopesparaacamadadecontroleeum
poucosobrecadaumadelas:
1.StrutsActionocontroladormaisfamosodomercadoJava,utilizadoprincipalmente
porseromaisdivulgadoecomtutoriaismaisacessveis.Possuevantagenscaractersticasdo
mvcedesvantagensquenapocaaindanoerampercebidas.ocontroladorpedidonamaior
partedasvagasemJavahojeemdia.umprojetoquenotergrandesatualizaespoisa
equipe dele se juntou com o Webwork para fazer o Struts Shale, nova verso do Struts
incompatvelcomaprimeira.
2.Webworkparaaprenderausarowebworkalinhadeaprendizadomaisleveecurta,
sendooframeworkrecomendadoparaaprendizadopelaCaelumquandooalunojestiverbem
adaptadoasidiasdoMVC.umprojetoquenotergrandesatualizaespoisaequipedele
sejuntoucomoStrutsparafazeroStrutsShale.
3.Springframeworkumacoleodeboasidiascolocadasdemaneirapadronizadaem
um nico controlador. Possui configuraes complexas (e longas) mas extremamente
poderoso.
4.Stripesumdosframeworksdapenltimagerao(2005),abusadasanotaespara
facilitaraconfigurao.
5.JbossSeamsegueasidiasdoStripesnareadeanotaesedesenvolvidopelo
pessoalquetrabalhoutambmnoHibernate.TrabalhamuitobemcomoJavaServerFacese
EJB3.0.
6.StrutsShaleassimcomooJbossSeam,oStrutsShalefazpartedanovageraode
controladores,integrandoJSFcomidiasdoscriadoresdoStrutsAction.
7. Iniciativas brasileiras: Vraptor 2desenvolvido tambmpor professores daCaelum e
baseadonoJbossSeam,JbananadesenvolvidonosuldoBrasilebaseadoemxml.

13.10 - Lista de tecnologias: camada de visualizao


Aseguirvocencontraumalistacomdiversasopesparaacamadadevisualizaoe
Captulo13ConstruindoumFrameworkMVCPgina118

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

umpoucosobrecadaumadelas:
1.JSP:comojvimosoJavaServerPages,temosumaboaidiadoqueele,suas
vantagensedesvantagens.Ousodetaglibs(aJSTLporexemplo)eexpressionlanguage
muitoimportantesevocescolherJSPparaoseuprojeto.aescolhadomercadohojeemdia.
2.Velocity:umprojetoantigo,noqualaELdojspsebaseou,capazdefazertudooque
vocprecisaparaasuapginadeumamaneiraextremamentecompacta.IndicadopelaCaelum
paraconhecerumpoucomaissobreoutrasopesparacamadadevisualizao.
3. Freemarker: similar ao Velocity e com idias do JSP como suporte a taglibs o
freemarkervemsendocadavezmaisutilizado.
4.Sitemesh:noumaaltenativaparaasferramentasanterioresmassimumamaneira
de criar templates para seu site, com uma idia muito parecida com o struts tiles, porm
genrica:funcionainclusivecomoutraslinguagenscomophpetc.
Empequenasequipesimportanteumaconversaparamostrarexemplosdecadauma
dastecnologiasacimaparaodesigner,afinalquemirtrabalharcomaspginasele.Aqueele
preferirvocusa,afinaltodaselasfazemamesmacoisademaneirasdiferentes.Comoemum
projetocomumterpoucosdesigneremuitosprogramadores,talvezsejaproveitosofacilitarum
poucootrabalhoparaeles.

13.11 - MVC 2
ProntoparaaprenderoqueoMVC2?Preparese...
O MVC 2 nada mais que uma genial confuso generalizada. O Model1 o antigo
padroqueosblueprints(boasprticas)dojeedasunindicavaparaousodejsp'sejavabeans.
DepoissurgiuoMVC(idiaemprestadadoSmalltalk),quefoilogochamadodemodelo2...
MVC,Modelo2,Modelo2,MVC,algumaspessoasacabamfalandoMVC2.
Noseengane,MVC2,MVCeModelo2tudoamesmacoisa:Model,View,Controller.

Captulo13ConstruindoumFrameworkMVCPgina119

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

14

14

Jakarta Struts
A qualidade a quantidade de amanh
HenriBergson

Aotrminodessecaptulo,vocsercapazde:
utilizarostrutsparacontrolarsualgicadenegcios
criaratalhosparasuacamadadevisualizao
criareconfigurarmapeamentosdeaesetemplates
utilizarformbeansparafacilitaraleituradeformulrios
validarseuformulriodeformasimples
controlaroserrosdevalidaodomesmo

14.1 - Struts
STRUTS
MVC

StrutsumframeworkdogrupoJakartaqueservecomoocontroller de uma
arquitetura MVC.ApesardetersuporteparaqualquertipodeServlets,focadonouso
deHttpServlets.

Naverso1.2,oStrutssuportanosJSP,pormsuaintegraocomframeworkscomo
oVelocityrequerplugins(comooVelocityToolsporexemplo).
Suadocumentaoe.jarpodemserencontradosem:
http://struts.apache.org
Paraleressecaptulo,importantequevocjtenhalidoocaptulosobreModelView
Controller.

14.2 - Configurando o Struts


Depois de baixar o Struts do site da Jakarta, vamos precisar de seus jars e de suas
dependncias,quesomuitosdoscommonsdoJakarta.
Descompacteoarquivobaixadoemalgumdiretrioecrieaestruturadediretrioscomo
sesegue,oqueilustracomoficamosdiretriosemumatpicaaplicaoqueutilizaoStruts.

14.3 - Exerccios
1)Descompacteoarquivoprojetostruts.zipnoseuworkspace:
a)Abraofilebrowser
b)Entrenapastacaelumedepois21.Escolhaoarquivoprojetostruts.zip

Captulo14JakartaStrutsPgina120

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

c)Cliquedadireitanoarquivoprojetostruts,escolhaExtractTo.
d)Escolhaparamudarodiretorioalvo.

e)Escolhaseuworkspaceemandeextrair.

Captulo14JakartaStrutsPgina121

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

f)Oresultadopodeservistoaovoltaraoseuworkspace.

2)Crieumprojetochamadostrutsnoeclipse:

Captulo14JakartaStrutsPgina122

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Captulo14JakartaStrutsPgina123

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3) Configure a servlet e o mapping de *.do para o Struts no seu arquivo WEB


INF/web.xml.Ateno,nocursoestepassojfoifeito.
<?xmlversion="1.0"encoding="ISO88591"?>
<webappxmlns="http://java.sun.com/xml/ns/j2ee"version="2.4">
<servlet>
<servletname>testeDeStruts</servletname>
<servletclass>org.apache.struts.action.ActionServlet</servletclass>
<loadonstartup>1</loadonstartup>
</servlet>
<servletmapping>
<servletname>testeDeStruts</servletname>
<urlpattern>*.do</urlpattern>
</servletmapping>
Captulo14JakartaStrutsPgina124

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

</webapp>

4) Cliquedadireitanonomedoseuprojeto,escolhaTomcat,Updatecontextdefinition
paraqueeleatualizeotomcat.
5)Cliquedadireitanonomedoseuprojeto,escolhaproperties.NaabaAmateras,altere
odiretriopara/web,conformefizemosnoprojetodetestedejsps.

6)Inicializeotomcatetesteaurlhttp://localhost:8080/struts/

Captulo14JakartaStrutsPgina125

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

ConfigurandooprojetonoTomcatsemoplugindoeclipse
NoseesqueadeconfiguraroProjetonoTomcatdamesmaformaquevimosnocaptulodeJSP!
Para isso, crie um arquivo <diretorio_do_tomcat>/conf/Catalina/localhost/struts.xml com o
seguintecontedo:
<Context path=/struts docBase=/home/usuario/workspace/struts/web/
reloadable=true>
</Context>
Vocobteveatelaseguinte?

Issopodeterocorridoporquealgumdeseusarquivosxmlfoidigitadoerradoouporqueno
seusistemanoestconfiguradoparaquelisteosarquivosdosdiretrios.Senoseucasofoi
porquenoestconfiguradoalistagemumbomsinal,alistagemdearquivosdosdiretrios
podetrazerriscosaoseusistemasemcasodeusuriosmaliciosos.
Masondeconfigurarparalistarounomeusarquivos?Noarquivo web.xml dotomcat
queestnapasta$CATALINA_HOME/conf/.Mudeoseguintetrechodoarquivo:
<initparam>
<paramname>listings</paramname>
<paramvalue>false</paramvalue>
</initparam>

Captulo14JakartaStrutsPgina126

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Deixe<paramvalue>false</paramvalue>casonoqueiraalistageme<param
value>true</paramvalue>casocontrrio.

14.4 - Arquivo de mensagens


Ostrutspossuiumsistemabemsimplesdeinternacionalizao.

MESSAGE
RESOURCES

Esseoprocessoondecentralizamostodasasmensagensdosistemaemum(oumais)
arquivosdeconfiguraoquesobaseadosnaantigaidiadechavevalor,umdicionriode
mensagens.Porexemplo:
menu.nome=Menuprincipal
menu.arquivo=Arquivo
menu.editar=Editar
menu.sair=Sair
site.titulo=SistemadetestedoStruts
Paraconfigurarostrutseusarumtipodearquivocomoesse,comeamosindicandoqual
o arquivo de configurao que usaremos. O nome mais comum
MessageResources.properties.Essearquivodevesercriadononossodiretriosrc.
ParaoStrutslertalarquivobastaconfigurlonostrutsconfig.xml,localizadonodiretrio
WEBINF:
<strutsconfig>
<!ArquivodeMensagens>
<messageresourcesparameter="MessageResources"/>
</strutsconfig>

Para utilizar tal arquivo bem simples, basta no nosso jsp usar uma taglib do struts
chamadabean:
<%@tagliburi="http://struts.apache.org/tagsbean"prefix="bean"%>
BEAN:MESSA
GE

Dadaumachave (menu.nome porexemplo), podemoschamara tag message que


capazdemostraramensagemMenuprincipal:

<bean:messagekey="menu.nome"/><br/>

Portantooexemploaseguirmostraummenucompletousandoessataglib:
<html>
<head><title><bean:messagekey="site.titulo"/></title></head>
<body>
<bean:messagekey="menu.nome"/><br/>
<bean:messagekey="menu.arquivo"/><br/>
<bean:messagekey="menu.editar"/><br/>
<bean:messagekey="menu.sair"/><br/>
</body>
</html>

14.5 - Exerccios
1)Crieumarquivochamadotestamensagens.jsp.

Captulo14JakartaStrutsPgina127

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

a)Incluaataglibbean:
<%@tagliburi="http://struts.apache.org/tagsbean"prefix="bean"%>

b)Incluaasmensagens:
<html>
<head><title><bean:messagekey="site.titulo"/></title></head>
<body>
<bean:messagekey="menu.nome"/><br/>
<bean:messagekey="menu.arquivo"/><br/>
<bean:messagekey="menu.editar"/><br/>
<bean:messagekey="menu.sair"/><br/>
<bean:messagekey="site.titulo"/><br/>
</body>
</html>

2)AbraoarquivochamadoMessageResources.propertiesnoseudiretriosrceadicione:
#comentariodeumarquivo.properties
menu.nome=Nomedomenu
menu.arquivo=EscolherArquivo
menu.editar=EditarArquivo
menu.sair=Sairdaaplicao
site.titulo=SistemadetestedoStruts

3)Adicioneaconfiguraoaseguirnoarquivostrutsconfig.xmlparautilizartalarquivode
mensagens:
<strutsconfig>
<!ArquivodeMensagens>
<messageresourcesparameter="MessageResources"/>
</strutsconfig>

4)Reinicieotomcat.Sersemprenecessriofazerissoaoalterarseuarquivostruts
config.xml.
5)Testeaurlhttp://localhost:8080/struts/testamensagens.jsp

14.6 - Erros comuns


Infelizmenteamaiorpartedoserrospossveisnoexerccioanteriortrazemamesmatela
Captulo14JakartaStrutsPgina128

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

de erro: cdigo 500, incapaz de achar o valor de uma mensagem: Cannot find message
resourcesunderkeyorg.apache.struts.action.MESSAGE.
1)Nasuapginahtml,digitarovalordeumamensagemdemaneiraerrada.OStruts
encontraseuarquivomasnoencontraamensagem.Verifiqueoexerccio1.
2)EsquecerdealteraroarquivoMessageResources.propertiesecolocar amensagem
nele.OStrutsencontraseuarquivomasnoencontraamensagem.Verifiqueoexerccio2.
Paraosdoiserrosacimaamensagemamesma:

3) Esquecer de alterar o arquivo strutsconfig.xml para configurar o arquivo


MessageResources.properties.Verifiqueoexerccio3.
4)Esquecerdereiniciaroservidor.Verifiqueoexerccio4.
Teladoserros3e4:

Captulo14JakartaStrutsPgina129

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

14.7 - Uma ao Struts


NonossoexemploanteriordeMVCutilizvamosumainterfacecomumatodasasnossas
lgicasdenegcio.ComoStrutstemosumaclassechamadaActionqueiremosestenderpara
implementarnossaslgicas.
Muitosprogramadoresrecomendamcomoboaprticanocolocaralgicadenegciona
Action,esimemumanovaclassequechamadaporela.
ACTION
STRUTS

Vocdevereescreveromtodoexecute,comonoexemploabaixo:
packagebr.com.caelum.struts.action;
//imports....
publicclassTesteSimplesActionextendsAction{
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{

//...
}
}

Porenquantotemosquatroparmetros,doisquejconhecemos,eumretorno.Essestrs
itensseroexplicadosembreve,passoapassoparaevitarcomplicaesumavezquenesse
pontoqueosprogramadoressentemumacertadificuldadeinicialcomoStruts.
Primeiro,precisamosdevolverumobjetodotipoActionForward,queindicaparaondeo
usuriodeveserredirecionadoaotrminodaexecuodaquelaao.Podeserparaoutraao,
ou,normalmente,paraum.jsp.

Captulo14JakartaStrutsPgina130

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Poderamosretornaralgodotipo:
returnnewActionForward(/exemplo.jsp);

Masissonorecomendado.Porque?Umavezquecolocamosonomedoarquivojspna
nossa camada de lgica de negcios, estamos criando uma ligao muito forte entre as
mesmas.Qualqueralteraononomedoarquivoresultaemumgrandeesforoparaencontrar
todosospontosquesereferenciamatallugar.
Portantoessanoserasoluoqueutilizaremos.PartimosparaalgoqueoStrutsfacilita
desdeoinciodeseuprojeto:desejamosretornarok!Lembresedisso.
muitoimportanteressaltarqueoStrutspodeinstanciarapenasumaActiondecadatipo,
fazendocom que voc aindatenha dese preocupar comproblemas desincronismo, j que
existe a possibilidade de existir mais de uma Thread acessando o mesmo objeto Action ao
mesmotempo.
Onossojspfinalseralgobemsimplesparaesseexemplo:
<html>
MinhaprimeirapginausandooStruts!
</html>

14.8 - Configurando a ao no struts-config.xml


Voltamosaoarquivostrutsconfig.xml:essearquivoirmapearasurlsqueosusurios
acessarem (chamados de path) e as classes (chamadas de type). Sendo assim, nada mais
naturaleelegantedoquemapearmosopath/testeparaaclasseTesteSimples.
Ateno: o nome do path no precisa ser igual ao nome da classe! Isto um
mapeamento!
<?xmlversion="1.0"encoding="ISO88591"?>
<!DOCTYPEstrutsconfigPUBLIC
"//ApacheSoftwareFoundation//DTDStrutsConfiguration1.2//EN"
"http://struts.apache.org/dtds/strutsconfig_1_2.dtd">
<strutsconfig>
<actionmappings>
<actionpath="/teste"type="br.com.caelum.struts.action.TesteSimples">
<forwardname="ok"path="/exemplo.jsp"/>
</action>
</actionmappings>
<!ArquivodeMensagens>
<messageresourcesparameter="MessageResources"/>
</strutsconfig>

Dentrodatagaction,colocamosumatagforward.Essatagdefineumredirecionamento
com um apelido (atributo name) e o caminho (path). No cdigo, quando fazemos
map.findForward(ok), o Struts procura um forward com apelido ok e devolve o objeto
ActionForward correspondente (no caso, redirecionando para exemplo.jsp). Desta forma,
podemostrabalharcomnossaslgicassemnosatrelarmosmuitocamadadevisualizao.
O parmetro path de action indica qual URL vai acionar essa ao, no caso ser o
/teste.dopoisparaacessarostrutsprecisamosdaterminao.dononossocaso.

Captulo14JakartaStrutsPgina131

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Aaopadro
Paramarcarumaaocomoapadro,isto,aquelaquedeveserexecutadacasonenhumadas
outrasforacorreta,bastaadicionarumatributochamadounknown.Somenteumaaopodeter
talatributocomvalortrue.
<actionpath=/seupathaquitype=suaclasseaquiunknown=true/>

Aessdeforward
Asvezesinteressantecriarumapelidoparaumapginajsp.Paraisso,umadasalternativas
criarumaaoqueemvezdepossuirumtype,possuiumatributochamadoforward:
<actionpath=/apelidoforward=/minha_pagina.jsp/>
Noexemploacima,comumnomercado,aurlqueterminacom/apelido.doserredirecionadapara
apginajspdentrododiretrioWEBINF/jsp.

GlobalForwards
O Struts permite configurar no strutsconfig.xml uma lista de forwards globais que podem ser
utilizadosportodasasaes.Paraisso,bastaadicionaratagglobalforwardsantesdosaction
mappings.
<globalforwards>
<forwardname=exceptionpath=/error.jsp/>
</globalforwards>
Sevoc quisercontrolaroserrosatravsdesse forward,bastausaralgosimilaraocdigoa
seguir:
catch(Exceptione){
returnmap.findForward(exception);
}

14.9 - Exerccios
1)CriesuaprimeiraaodoStruts.
a)CrieumaclassechamadaTesteSimplesActionnopacotebr.com.caelum.struts.action.

Captulo14JakartaStrutsPgina132

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

b)FaasuaclasseestenderAction(doStruts!).
c)UtilizeCTRL+SHIFT+Oparaimportaraclasse.
d)Escrevaomtodoexecuteeimplementeomesmo,retornandooresultadoexemplo.
@Override
publicActionForwardexecute(ActionMappingmap,ActionFormform,HttpServletRequest
request,HttpServletResponseresponse)throwsException{
System.out.println("Executandoocdigodalgicadenegcios...");
returnmap.findForward(ok);
}

2)Crieseuarquivoexemplo.jspdentrododiretrioweb.
<html>
MinhaprimeirapginausandooStruts!
</html>

3) Abra o seu arquivo strutsconfig.xml e configure sua ao dentro da tag action


mappings,quevemantesdomessageresources.
<strutsconfig>
<actionmappings>
<actionpath="/teste"type="br.com.caelum.struts.action.TesteSimplesAction">
<forwardname="ok"path="/exemplo.jsp"/>
</action>
</actionmappings>
<!ArquivodeMensagens>
<messageresourcesparameter="MessageResources"/>
</strutsconfig>

4)ReinicieoTomcat.
5)TesteaURLhttp://localhost:8080/struts/teste.do

Captulo14JakartaStrutsPgina133

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Reloadautomticodostrutsconfig.xml
OStrutsnofazoreloadautomticodoarquivostrutsconfig.xml.
Umtruqueparafazerissofuncionar(questilduranteodesenvolvimentodasuaaplicao)
colocaressearquivonoseudiretriosrc,portantoserjogadonodiretrioclasses,oclasspath.
Jnoseuarquivoweb.xmlconfigureostrutscomumparmetrodeinicializaodeservletparaler
oarquivodentrododiretrioclasses(/WEBINF/classes/strutsconfig.xml):
<initparam>
<paramname>config</paramname>
<paramvalue>/WEBINF/classes/strutsconfig.xml</paramvalue>
</initparam>
Agoratodavezqueoarquivoforalterado,oTomcatpercebeumamudananoclasspathdoprojeto
ereiniciaasuaaplicaoweb.
Cuidado pois essa funcionalidade de reinicializao de contextos nem sempre pode funcionar
como voc espera. Um caso simples iniciar threads separadas e deixlas rodando no
background,oqueacontece?

14.10 - Erros comuns


1)OerromaisfamosonosprimeirosexemplosdeumaActiondoStrutscolocaronome
doforwarddemaneirainvlida,porexemplo,emminsculonostrutsconfig.xmleemmaisculo
na sua classe. Lembrese, o Java casesensitive e assim ser a maior parte de suas
bibliotecas!
ComooStrutsnoencontraumredirecionamentocomtalchave,omtodofindForward
retornanull,resultado:umatelaembranco.

Captulo14JakartaStrutsPgina134

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

2)Outroerrocomumesquecerdecolocarabarraantesdonomedoredirecionamento.
Todopathdeforwarddevecomearcomumabarra.Sevoccolocarsomenteexemplo.jspo
errodizclaramentequefaltouumabarra:

3)comumerraronomedaclassedesuaaction,comoporexemploesquecero.come
digitarbr.caelum.struts.action.TesteSimplesAction.NessecasooStrutsnoconsegueinstanciar
suaaction:

4)Porltimo,oerrodosesquecidos.Sevocnocriaroarquivojspoucolocarumnome

Captulo14JakartaStrutsPgina135

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

invlidooerroojconhecido404:

14.11 - Pesquisando um banco de dados


Continuandocomnossaaplicaocriadanocaptuloanterior,iremosmontaragoraum
esquemadesimulaodeacessoaumbancodedadosparalistartodososcontatosatravsdo
MVCeusandoStruts,JSPeJDBC.
Reparequejestamosusandotrscamadasetrsbibliotecasdiferentes!

14.12 - Criando a ao
Paracriaraaodelistagembastautilizarmosaidiadecriarumnovoobjetodotipo
DAOechamaromtodolista:
//pesquisanobancodedadosalistacompleta
List<Contato>lista=newContatoDAO().getLista();

Masespereumpouco,esseoexemploquevimosnocomeodaapostila?Ataqui,
semnovidades.Aquestoqueficacomoenviarocontedoreferenciadopelavarivellista
paraapginajspqueseracessadaembreve.
Precisamos de um escopo de varivel que sobreviva ao mtodo execute e continue
duranteoforwarddarequisioatoarquivojsp.Reparequeafraseanteriorentregaasoluo:
oescopodarequisio.
Iremosatrelaro valorreferenciadopelavarivellistaparaumnomequalquerligadaa
requisiodocliente.Essevalorsficarlatotrminodarequisio,temposuficientepara
mostrlonoarquivojsp.
Podemosadicionlacomoatributonorequest,paraquenossapginajsppossareceber
talobjeto.Suponhaquedesejamoschamarnossalistadecontatos:
request.setAttribute("contatos",lista);

Captulo14JakartaStrutsPgina136

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Eoredirecionamentosimples:
returnmap.findForward("lista");

Portanto,ocdigofinaldenossaao:
packagebr.com.caelum.struts.action;
//importsaqui
publicclassListaContatosActionextendsAction{
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
//pesquisanobancodedadosalistacompleta
List<Contato>lista=newContatoDAO().getLista();
request.setAttribute("contatos",lista);
//ok....paraondeiragora?
returnmap.findForward("lista");
}
}

14.13 - O arquivo web/lista.jsp


Paracriarmosojspdelistagemtemostrsopes.Aprimeiraseriaescreverocdigo
atravsdescriplets,quejvimosnocaptulodejsp:noumaboasoluo.Asegundaopo
utilizar a biblioteca de tags de lgica do Struts, a strutslogic, que funciona e uma boa
alternativa.
Aterceira,utilizarJSTL.Qualadiferenaentreastrutslogiceajstlcore?Aconteceque
abibliotecadoStrutsveioantesdaJSTL,aJSTLatentativadepadronizaressastaglibsque
aparecerampelomundointeiro,sendoassim,todos,inclusiveogrupoApache,estomigrando
para a JSTL. A seguir voc ver um exemplo que utiliza a taglib de lgica do Struts mas
seguiremosutilizandoonovopadro(jnotonovo)queaJSTL.
Como fizemos antes, primeiro devemos declarar a varivel, que est sendo lida do
request.Logodepoisiteramosportodosositens:
<!for>
<c:forEachvar="contato"items="${contatos}">
${contato.id},${contato.nome}<br>
</c:forEach>

Portanto,oarquivofinal,comcabealhoetudooquefaltava,ficasendo:
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<html>
<!for>
<c:forEachvar="contato"items="${contatos}">
${contato.id}${contato.nome}<br/>
</c:forEach>
</html>

Nessemomentovocsepergunta:masojspnodeclarouavarivelcontatos?!Sim,ele
nodeclarou.Aexpressionlanguageirbuscarovalordetalchavenorequest(eemoutros
lugares,queveremosadiantenocurso)eutilizlaparaaiterao,ousejaelenotemligao
diretacomodao,elesabequevemumavarivelcontatos,masnosabedeonde.
Captulo14JakartaStrutsPgina137

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

14.14 - struts-config.xml
Porfim,vamosalterarostrutsconfig.xmlparaconfigurarnossaao:
<actionpath="/listaContatos"type="br.com.caelum.struts.action.ListaContatosAction">
<forwardname="lista"path="/lista.jsp"/>
</action>

Portanto, para testarmos nossa aplicao, devemos reiniciar o tomcat e utilizar o link
/listaContatos.do.
Repare queagora no faz mais sentido acessar ojsp delistagem diretamente pois a
varivelnoexiste!

14.15 - Exerccio
Vamoscriarsualistagemdecontatos:
1)CriesuaclassedelgicaListaContatosAction
a)LembresedeestenderaclasseAction
b)Implementeomtodoexecute:
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
//pesquisanobancodedadosalistacompleta
List<Contato>lista=newContatoDAO().getLista();
request.setAttribute("contatos",lista);
//ok....paraondeiragora?
returnmap.findForward(lista);
}

2)Configureostrutsconfig.xml
<actionpath="/listaContatos"type="br.com.caelum.struts.action.ListaContatosAction">
<forwardname="lista"path="/lista.jsp"/>
</action>

3)Crieseujspderesultadoweb/lista.jsp
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<html>
<!for>
<c:forEachvar="contato"items="${contatos}">
${contato.id}${contato.nome}<br/>
</c:forEach>
</html>

4)ReinicieoTomcat.
5)Testeaurlhttp://localhost:8080/struts/listaContatos.do

Captulo14JakartaStrutsPgina138

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

6)Oqueaconteceseacessarmosdiretamenteojsp?Oqueestamosfazendodeerrado?
Testeaurlhttp://localhost:8080/struts/lista.jsp

Nestemomento,seuarquivostrutsconfig.xmlpossuiduasactionseaconfiguraodo
MessageResources.properties:
<strutsconfig>
<actionmappings>
<actionpath="/teste"type="br.com.caelum.struts.action.TesteSimplesAction">
<forwardname="ok"path="/exemplo.jsp"/>
</action>
<actionpath="/listaContatos"

type="br.com.caelum.struts.action.ListaContatosAction">

<forwardname="lista"path="/lista.jsp"/>
</action>
</actionmappings>
<!ArquivodeMensagens>
<messageresourcesparameter="MessageResources"/>
</strutsconfig>

O seguinte diagrama descreve o que acontece com o nosso sistema ao requisitar a


listagemdecontatos:

Captulo14JakartaStrutsPgina139

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

14.16 - Resultado condicional com o Struts


ComofazerparamostraramensagemNenhumcontatoforaencontrado?
Aprimeiraidiaadecolocarumifdentrodoseujsperesolveroproblema,certo?Mas
issostrarproblemasparaodesigner,quenosabetantodelgicaquantovocepodeser
queoeditorqueeleusanosuportetaistiposdelgicas...
Ento,amelhorsadaverificar,aindadentrodesuaao,seobancodedadosretornou
umacoleodetamanhozero.E,nessecaso,redirecionarparaoutrapgina.

14.17 - Exerccios
1)Crieumjspnovochamadolistavazia.jsp.
<html>
Vocnopossuinenhumcontato.
</html>

2)Alterandosomentesualgicaeadicionandoumnovoforward,quandoalistaestiver
vazia,apginalistavazia.jspsejamostrada:
//pesquisanobancodedadosalistacompleta
List<Contato>lista=newContatoDAO().getLista();
request.setAttribute("contatos",lista);
//ok....paraondeiragora?
if(lista.isEmpty()){
returnmap.findForward(vazia);
}else{
returnmap.findForward(lista);
}

Captulo14JakartaStrutsPgina140

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)Altereseustrutsconfig.xmlparaadicionarumnovoforwardparaalistavazia:
<actionpath="/listaContatos"type="br.com.caelum.struts.action.ListaContatosAction">
<forwardname="lista"path="/lista.jsp"/>
<forwardname="vazia"path="/listavazia.jsp"/>
</action>

4)Testeasualistagemcomobancodedadosvazio.Parasimularalistavazia,voc
pode,porexemplo,chamaromtodolista.clear();ouremovertodososseuscontatosdobanco.

14.18 - Resultado do struts-config.xml


Nestemomento,seuarquivostrutsconfig.xmlpossuiduasactionseaconfiguraodo
MessageResources.properties:
<strutsconfig>
<actionmappings>
<actionpath="/teste"type="br.com.caelum.struts.action.TesteSimplesAction">
<forwardname="ok"path="/exemplo.jsp"/>
</action>
<actionpath="/listaContatos"

type="br.com.caelum.struts.action.ListaContatosAction">

<forwardname="lista"path="/lista.jsp"/>
<forwardname="vazia"path="/listavazia.jsp"/>
</action>
</actionmappings>
<!ArquivodeMensagens>
<messageresourcesparameter="MessageResources"/>
</strutsconfig>

14.19 - Novos contatos


Agora,jestamosprontosparacriaralgicadenegcioseacamadadevisualizao
parapermitiradicionarnovosclientese,consequentemente,listlos.
Comodecostume,seguiremosospassos:
1)Criaralgicadenegcios
2)Criarojspdevisualizao
Captulo14JakartaStrutsPgina141

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)Criaromappingdalgicaparaavisualizao
Edepoisospassosopcionais:
4)Criaravalidaodoformulrionalgicadenegcios
5)Criarocontroledeerronavisualizao

14.20 - Formulrio
NuncaeleganteficartrabalhandocomomtodogetParameterdorequest,sendoque
muitomelhortrabalharcomclassesquensmesmosescrevemos.Portantovamosimaginarum
cenriosimples:desejamosadicionaronome,emailedescricodocliente.
ACTIONFORM

OStrutspossuiumaclassechamadaActionFormqueaoserestendidapermiteleros
parmetrosdorequestsemnospreocuparmoscomomesmo!
Sendoassim,noStruts,paracadaformulriohtmlqueexistenonossositecriamosuma
classeemJavapararepresentaroscamposdomesmo.
Nonossocasoprecisamosdoscamposnome,emailedescrio,masopa,issoum
Contato!Resultado:

packagebr.com.caelum.struts.form;
importorg.apache.struts.action.*;
publicclassContatoFormextendsActionForm{
privateContatocontato=newContato();
publicContatogetContato(){
returnthis.contato;
}
}

Ateno:oformulriohtmldeverteroscamposcomomesmonomequeasvariveis
membrodoseuformulrio!
Existe uma opo avanada de fazer o formulrio atravs de xml, no deixa de ser
bastantecdigoeaindacomadesvantagemdenotererrosdecompilao.

14.21 - Mapeando o formulrio no arquivo struts-config.xml


FORM-BEAN

Assimcomoaaction,devemosconfigurarnossoformnoarquivostrutsconfig.xml.Para
issousamosatagchamadaformbean.

Atributosdeumatagformbean:
name:umnomequalquerquequeremosdaraumformulrio
type:aclassequerepresentaesseformulrio
Ateno: Taltag vem antes dasdefinies dos actionmappings! Todos osformulrios
devemserdefinidosdentrodeumanicatagformbeans.
<formbeans>
<formbeanname="ContatoForm"type="br.com.caelum.struts.form.ContatoForm"/>
</formbeans>

Captulo14JakartaStrutsPgina142

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

14.22 - Exerccio
1)Oprimeiropassocriaroformulriocomoclasse:
a)CrieaclasseContatoFormnopacotebr.com.caelum.struts.form.
b)FaacomqueseuformulrioestendaaclasseActionFormdoStruts.
publicclassContatoFormextendsActionForm{
}

c)ColoqueumavariveldotipoContatonoformulrio,chameadecontatoeinstanciea
varivel.
publicclassContatoFormextendsActionForm{
privateContatocontato=newContato();
}

e)VnomenuSource,GenerateGettersandSetterseescolhaomtodogetContato.
publicclassContatoFormextendsActionForm{
privateContatocontato=newContato();
publicContatogetContato(){
returnthis.contato;
}
}

2)Agoravamosmapearesseformulrionostrutsconfig.xml.
<formbeans>
<formbeanname="ContatoForm"type="br.com.caelum.struts.form.ContatoForm"/>
</formbeans>

14.23 - Lgica de Negcios


Podemos escrever um cdigo bem simples que adiciona um novo contato (recebido
atravsdeumformulrio)paraobancodedados:
Criamosumcontato,recuperamososvaloresdoformulrioeadicionamosesteclienteao
bancodedados:
packagebr.com.caelum.struts.action;
//sriedeimportsaqui
publicclassAdicionaContatoActionextendsAction{
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
//log
System.out.println("Tentandocriarumnovocontato...");
//formulriodecliente
ContatoFormformulario=((ContatoForm)form);
//acessaobean
Contatocontato=formulario.getContato();

//adicionaaobancodedados
Captulo14JakartaStrutsPgina143

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);
//ok....visualizao
returnmap.findForward("ok");
}
}

14.24 - Exerccio
1)VamoscriaraclasseAdicionaContatoAction
a)CrieaclasseAdicionaContatoActionembr.com.caelum.struts.action
b)FaacomquesuaclasseestendaActiondoStruts.
c)Digiteexecute,CTRL+ESPAOedenter:implementeomtodoexecutelembrando
dealterarosnomesdeseusargumentos:
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
//log
System.out.println("Tentandocriarumnovocontato...");
//formulriodecliente
ContatoFormformulario=((ContatoForm)form);
//acessaobean
Contatocontato=formulario.getContato();

//adicionaaobancodedados
ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);
//ok....visualizao
returnmap.findForward("ok");
}

2)Vamosconfigurarsuaao
a)Definesuaao/novoContatonoarquivostrutsconfig.xmlapontandoparaaclasse
AdicionaContatoAction.
<actionpath="/novoContato"name="ContatoForm"
type="br.com.caelum.struts.action.AdicionaContatoAction">
</action>

b)Emcasodesucesso(ok),redirecioneparao/listaContatos.do(istomesmo,estamos
encadeandoduasaes).
<forwardname="ok"path="/listaContatos.do"/>

3)Crieseuarquivonovo.jsp
<%@tagliburi="http://struts.apache.org/tagshtml"prefix="html"%>
<html:html>
<head><title>SistemadeTestedoStruts</title></head>
<html:errors/>
<html:formaction="/novoContato"focus="contato.nome">
Captulo14JakartaStrutsPgina144

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Nome:
<html:textproperty="contato.nome"/>
<br/>
Email:
<html:textproperty="contato.email"/>
<br/>
Endereo:
<html:textproperty="contato.endereco"/>
<br/>
<html:submit>Enviardados</html:submit>
<br/>
</html:form>
</html:html>

6)Testeaurlhttp://localhost:8080/struts/novo.jsp

7)Agoratentecriarumcontatocomnomevazio,funciona?

14.25 - Erros comuns


Aseguirvejaoserrosmaiscomunsnoexerccioanterior:
1) Esquecer de fazer seu ContatoForm estender ActionForm: como ContatoForm e
ActionFormnopossuemconexo,ocompilador(nocaso,oEclipse),reclamadocastingque
estsendofeito dentrodasuaclasse Action, afinalnenhumActionFormumContatoForm.
Soluo:estendaActionForm.
2) Esquecer de colocar o atributo name=ContatoForm na sua tag action dentro do
strutsconfig.xml.ComovocnonotificouoStrutsquesuaActionprecisadeumform,elepassa
nullparaseumtodoe,quandocheganalinhaquetentachamaromtodogetContato,acontece
um NullPointerException. Percebeu que o NullPointerException foi um erro do programador?
Elesnormalmentesodescuidosdoprogramador,portantosemprepresteatenonaquiloque
voc faz e configura! Soluo: v no seu arquivo strutsconfig.xml e coloque o atributo

Captulo14JakartaStrutsPgina145

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

name=ContatoFormnasuatagaction.

14.26 - Validando os campos


VALIDAO
STRUTS

Parafacilitarnossotrabalho,podemosagoraimplementaromtododevalidaoquevem
juntocomoStruts.
Iremos, atravs do formulrio, escrever um mtodo que retorna uma lista de erros
encontrados.Paratanto,vamoscriarprimeiroummtodocomumqueverificaoserrosbsicos
emumastring:

publicbooleanstringVazia(Stringvalor){
returnvalor==null||valor.trim().length()==0;
}

Omtododevalidaodoformulrioomtodovalidate.Casoocorraalgumerrode
validao,devemosadicionaroserrosaoobjetoActionErrors.Porexemplo:
publicActionErrorsvalidate(ActionMappingmap,HttpServletRequestreq){
ActionErrorserros=newActionErrors();
if(stringVazia(nome)){
erros.add("nome",newActionMessage("erro.campoNome"));
}
returnerros;
}

Nessecaso,iremosusarapalavraerro.campoNomecomochaveparaamensagemde
erro!Issomesmo,ficamuitomaisfcilcontrolaroquevaiserapresentadoaoseuusuriocomo
mensagemdeerropoisiremosconfigurlonoarquivoMessageResources.properties.
Acrescentando as verificaes dos outros campos, temos o cdigo final do mtodo
validate:
publicActionErrorsvalidate(ActionMappingmap,HttpServletRequestreq){
ActionErrorserros=newActionErrors();
//verificaonome
if(stringVazia(contato.getNome())){
erros.add("nome",newActionMessage("erro.campoNome"));
}
//verificaoemail
if(stringVazia(contato.getEmail())){
erros.add("email",newActionMessage("erro.campoEmail"));
}
//verificaoendereci
if(stringVazia(contato.getEndereco())){
erros.add("endereco",newActionMessage("erro.campoEndereco"));
}
returnerros;
}

Agora, basta alterar nossa configurao do strutsconfig.xml e adicionar o atributo


chamadoinput.

Captulo14JakartaStrutsPgina146

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


<actionpath="/novoContato"name="ContatoForm"input="/novo.jsp"
type="br.com.caelum.struts.action.AdicionaContatoAction">
<forwardname="ok"path="/listaContatos.do"/>
</action>

14.27 - Exerccio
1)AbraasuaclasseContatoForm.
a)CrieomtodostringVazia:
publicbooleanstringVazia(Stringvalor){
returnvalor==null||valor.trim().length()==0;
}

b)Crieomtodovalidate:
publicActionErrorsvalidate(ActionMappingmap,HttpServletRequestreq){
ActionErrorserros=newActionErrors();
//verificaonome
if(stringVazia(contato.getNome())){
erros.add("nome",newActionMessage("erro.campoNome"));
}
//verificaoemail
if(stringVazia(contato.getEmail())){
erros.add("email",newActionMessage("erro.campoEmail"));
}
//verificaoendereco
if(stringVazia(contato.getEndereco())){
erros.add("endereco",newActionMessage("erro.campoEndereco"));
}
returnerros;
}

2)Altereomapeamentodeseuxml,noadicione!
<actionpath="/novoContato"name="ContatoForm"input="/novo.jsp"
type="br.com.caelum.struts.action.AdicionaContatoAction">
<forwardname="ok"path="/listaContatos.do"/>
</action>

3)Coloqueasmensagensdeerronoseuarquivoderesources.
erro.campoNome=Preenchaocamponomecorretamente.
erro.campoEmail=Preenchaocampoemailcorretamente.
erro.campoEndereco=Preenchaocampoenderecocorretamente.

4)Tentecriarumnovocontatocomnomevazio:http://localhost:8080/struts/novo.jsp

Captulo14JakartaStrutsPgina147

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

14.28 - Erros comuns


1)Esquecerdecolocaroatributoinput=/novo.jsp.OStrutsficasemsaberparaondeir
no caso da validao dar errado, ento ele reclama que voc no colocou o atributo input.
Soluo:coloqueoatributoinputnasuatagaction.
2)Emvezdealteraromapeamentodoseuxml,copiarnovamenteomapeamentointeiro,
isto,possuirduasactionscomopath/novoContato.OStrutsficaperdidoenofunciona.

14.29 - Limpando o formulrio


Adicioneumcontatonobancodedados,acesseumoutrositequalquerevolteaoseu
novo.jsp.Oqueacontece?Oformulriocontinuapreenchido?
Issoocorrepordoismotivos:
Primeiro,oStrutsreciclaobjetosdotipoActionFormentrediferentesrequests,fazendo
comqueseuobjetopermaneasujo,maselechegaadarumachanceparaseuformulriose
limpar:omtodoresetimportanteparaapagarosdadosutilizadosanteriormente.
Paraisso,bastareescreveromtodoemseuformulriopoisomesmoserchamado
antesdeutilizado:
@Override
publicvoidreset(ActionMappingmap,HttpServletRequestreq){
this.contato=newContato();
}

Escopodoformulrio
Existeumatributoopcionalnatagactionquandoutilizandoumformulrio:scope.Esseatributo
utilizadoparalerosdadosdoformulriodorequestoudasesso.
Utilizamos o escopo de sesso (padro) quando desejamos que os dados se mantenham
atreladosaqueleclientepormaisdeumrequest,enquantoqueoescopoderequestatrelaos
dadossomenteatoterminodarequisio.
Captulo14JakartaStrutsPgina148

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Portantovocpodecolocarnoseuaction:
scope=session
scope=request
comumutilizaroescopodesessoparamanterosdadosdeumformulrioatravsdediversas
requisies.

14.30 - Exerccios
1)AltereseuContatoFormparautilizaromtodoreseteatagscope:
a)coloqueomtodoresetnoseuContatoForm:
@Override
publicvoidreset(ActionMappingmap,HttpServletRequestreq){
this.contato=newContato();
}

b)configureoescopodoseuformulriopararequest:
<actionpath="/novoContato"name="ContatoForm"input="/novo.jsp"
type="br.com.caelum.struts.action.AdicionaContatoAction"scope=request>
<forwardname="ok"path="/listaContatos.do"/>
</action>

14.31 - Exerccios
1)CrieumformulriochamadoRemoveContatoFormemapeieelenostrutsconfig.xml.
2)CrieumaaochamadaRemoveContatoAction
a)ElarecebeumformulriodotipoRemoveContatoForm
b)Elaremovedobanco(usandooContatoDAO)ocontatocomidigualaodocontatodo
formulario.Algocomo:
Contatocontato=((RemoveContatoForm)form).getContato();
newContatoDAO().remove(contato);
c) Mapeie uma ao no strutsconfig.xml chamada removeContato para sua classe
RemoveContatoAction
d)Redirecionepara/listaContatos.doapsremoverumcontato
e)Nasualista,altereocdigoparaincluirumlinkpararemoo:
<c:forEachvar="contato"items="${contatos}">
${contato.id}${contato.nome}
(<ahref="removeContato.do?contato.id=${contato.id}">remover</a>)<br/>
</c:forEach>

f)Testeasualistagemedepoisremovaalgumcontato.

14.32 - Dois formulrios para a mesma ao

Captulo14JakartaStrutsPgina149

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Nesse momento do aprendizado bem comum que um aluno pense em reutilizar


formulriosparaduasaesdiferentes.Serquevaleapena?Serqueasduasaestem
exatamenteamesmavalidao?Serqueelassemprevoteramesmavalidao?
Como ou (1) duas aes no costumam ter a mesma validao ou (2) no podemos
preverofuturoesabersealteraesnonegcioirotrazervalidaesdiferentesparaessas
duas aes considerado boa prtica criar formulrios diferentes para aes diferentes,
utilizandosempreobomsenso.

14.33 - Exerccios opcionais


1)Vamosinternacionalizarnossosistema:
a)CrieumaaochamadaMudaLinguaAction
b)ElachamaomtodosetLocalequealteraolocaledoclienteeretornaoforwarddeok:
Stringlingua=request.getParameter("lingua");
Localelocale=newLocale(lingua);
System.out.println("Mudandoolocalepara"+locale);
setLocale(request,locale);
returnmap.findForward("ok");

c)Mapeieessaactionparaopath/mudaLingua.
<actionpath="/mudaLingua"
type="br.com.caelum.struts.action.MudaLinguaAction">
<forwardname="ok"path="/testamensagens.jsp"/>
</action>

d)Altereseuarquivotestamensagens.jspparaadicionardoislinksparaaaodealterar
alngua:
<ahref="mudaLingua.do?lingua=en">EN</a>|
<ahref="mudaLingua.do?lingua=pt">PT</a><br/>

e)CrieoarquivoMessageResources_en.propertiesnoseudiretriosrc.
site.titulo=StrutsTest
pergunta.usuario=Whatisyourusername?
pergunta.senha=Whatisyourpassword?
pergunta.enviar=Senddata
#comentariodeumarquivo.properties
menu.nome=Menuname
menu.arquivo=Choosefile
menu.editar=Editfile
menu.sair=Quit

f)ReinicieoTomcat.
g)Testeaurlhttp://localhost:8080/struts/testamensagens.jsp:
Ositeapareceporpadronalnguaqueoseubrowserpediu,quealnguaconfigurada
noseussistemaoperacional.
h)Escolhaolinkparaportugus:

Captulo14JakartaStrutsPgina150

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

i)Escolhaolinkparaingls:

OdiagramaaseguirrepresentaoqueaconteceaoalteraroLocale:

Captulo14JakartaStrutsPgina151

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

2)Vamosmostraragoraosdetalhesdeumcontato.
a)CrieaclasseMostraContatoFormsimilaraoContatoForm.
b)CrieumaaochamadaMostraContatoAction
c)Elachamaomtodoprocura:
Contatocontato=((MostraContatoForm)form).getContato();
Contatoencontrado=newContatoDAO().procura(contato.getId());
request.setAttribute("contato",encontrado);

d) Mapeie uma ao no strutsconfig.xml chamada mostraContato para sua classe


MostraContatoAction
e)Redirecionepara/mostraContato.jspapsmostrarumcontato.Ocdigodelemostraos
dadosdocontato(semformulrio).
f)Nasualista.jsp,altereocdigoparaincluirumlinkparamostraContato.do:
<c:forEachvar="contato"items="${contatos}">
${contato.id}${contato.nome}
(<ahref="removeContato.do?contato.id=${contato.id}">remover</a>)
(<ahref="mostraContato.do?contato.id=${contato.id}">mostrar</a>)<br/>
</c:forEach>

3)Vamosterminarapartedealterarocontato.
a) Altere a pagina mostraContato.jsp para mostrar um formulario acessando
/alteraContato.do.Nastagshtml:textutilizeocampovalue=${...}paracolocarovalorinicialnos
mesmos.
b)CrieumaaochamadaAlteraContatoAction
Captulo14JakartaStrutsPgina152

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

c)Elachamaomtodoaltera:
Contatocontato=((AlteraContatoForm)form).getContato();
newContatoDAO().altera(contato);
d) Mapeie uma ao no struts.config.xml chamada alteraContato para sua classe
AlteraContatoAction
e)Redirecionepara/listaContatos.doapsalterarumcontato

14.34 - Struts-logic taglib: um exemplo antigo de for


Aseguiraversodoarquivolistaelegante.jspusandoataglibdelgicadoStruts.Repare
comoficamaiscomplexo:
<%@tagliburi="http://struts.apache.org/tagslogic"prefix="logic"%>
<%@tagliburi="http://struts.apache.org/tagsbean"prefix="bean"%>
<html>
<head><title>SistemadeTestedoStruts</title></head>
<body>
<logic:iterateid="contato"name="contatos"type="br.com.caelum.struts.model.Contato">
<bean:writename="contato"property="id"/>,
<bean:writename="contato"property="nome"/><br/>
</logic:iterate>
</body>
</html>

Valelembrarqueoprpriogrupoquedesenvolveostrutsjrecomendaousodastaglibs
dajstlemvezdaproprietriadostruts.

14.35 - Um pouco mais...


1)OStrutsTilesajudavocacomponentizarospedaosdassuaspginas.Dando
nomeparaosdiversoscomponentescomunsaspginas,vocpodeinclulosdinamicamente
emqualquerjsp.
2)OStrutsValidatorpodeserconfiguradoparaqueosformbeanssejamverificados
antesdesuasaesseremexecutadas.Ele,delonge,opluginmaisfamosoepoderosodo
Struts.
3)OprojetoVelocityToolsfazaponteentreoVelocityeoStruts,entreoutrascoisas.

AlwaysLinkToActions
ALWAYS LINK
TO ACTIONS

UmdospatternsmaissimplesefamososqueoStrutsconstruiuoAlwaysLinkToActions.Voc
sempredevesereferenciarasaesdoStrutsenuncaassuaspginasjspdiretamente.Sevoc
jescondesuaspginasjspnodiretrioWEBINF,estseobrigandoautilizartalprocedimento.
Qualavantagem?
Seemalgumdiasuapginajspprecisaexecutarumalgicaantesdeserchamadaouseeladeve
ser renomeada, basta alterar o arquivo strutsconfig.xml, caso contrrio voc deveria procurar
todososlinksemsuaaplicao!

Captulo14JakartaStrutsPgina153

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

15

Jakarta Struts

15

Verifica se o que prometes justo e possvel, pois promessa


dvida.
Confcio

Aotrminodessecaptulo,vocsercapazde:
utilizarsessesemservlets;
desenvolverumsistemadelogin.

15.1 - Preparando um sistema de login


VamosnosprepararparaumexemplobemprticoutilizandooStruts,comeandopelo
logindeumusuriononossosite.
Semprequequeremostrabalharcomformulriosiremosseguirbasicamenteospassosa
seguir:
1)Modelaroformulriocomoclasseeconfigurlonostruts-config.xml
2)Criarapginahtmlcomoformulrio
3)Criaraaoqueserexecutadaemapelanostruts-config.xml
4)Criarapginafinal,apsaexecuodoformulrio

15.2 - Passo 1: Formbean


Ocdigodonossoformulriorazoavelmentesimples:
packagebr.com.caelum.struts.form;
importorg.apache.struts.action.*;
publicclassLoginFormextendsActionForm{
privateFuncionariofuncionario=newFuncionario();
publicFuncionariogetFuncionario(){
returnthis.funcionario;
}
@Override
publicvoidreset(ActionMappingmap,HttpServletRequestreq){

this.funcionario=newFuncionario();
}
}

Eagoravamosatagdeformulrionostrutsconfig.xml:
<formbeans>
Captulo15JakartaStrutsPgina154

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


<formbeanname="ContatoForm"type="br.com.caelum.struts.form.ContatoForm"/>
<formbeanname="LoginForm"type="br.com.caelum.struts.form.LoginForm"/>
</formbeans>

15.3 - Passo 2: A pgina de login: formularioLogin.jsp


Agorairemospartirparaonossoarquivojspquedefineoformulrio.Jiremosutilizar
algunsrecursosnovos,astaglibsdoStruts,quefacilitamotrabalhodereutilizaodecdigo,
simplificamacamadadevisualizaoepermitemumainternacionalizaomaisfcildamesma.
AseguirestoarquivoformularioLogin.jsp,queusaastaglibsmostradasanteriormente
para definir o cdigo html das mesmas. A nica tag nova nesse exemplo a chamada
html:passwordquemostraumcampodotipopassword:
<html:passwordproperty="funcionario.senha"/>

Porrazesdeseguranaessecamponovoltapreenchidonocasodeerrodevalidao.
Oexemploaseguirmostraoformulriocompleto:
<%@tagliburi="http://struts.apache.org/tagshtml"prefix="html"%>
<html:html>
<title>SistemadeTestesdoStruts</title>
<body>
<html:formaction="/efetuaLogin"focus="funcionario.usuario">
Qualseuusurio?
<html:textproperty="funcionario.usuario"/><br/>
Qualsuasenha?
<html:passwordproperty="funcionario.senha"/><br/>
<html:submit>EnviarDados</html:submit>
</html:form>
</body>
</html:html>

15.4 - Exerccio
1) Crie o seu formulrio de login: uma classe chamada LoginForm no pacote
br.com.caelum.struts.form.NoesqueadeestenderaclasseActionForm.
packagebr.com.caelum.struts.form;
//faaosimportsaquiCTRL+SHIFT+O
publicclassLoginFormextendsActionForm{
privateFuncionariofuncionario=newFuncionario();
publicFuncionariogetFuncionario(){
returnthis.funcionario;
}
@Override
publicvoidreset(ActionMappingmap,HttpServletRequestreq){

this.funcionario=newFuncionario();
}
}

2)Mapeieseuformulrionostrutsconfig.xml.
<formbeanname="LoginForm"type="br.com.caelum.struts.form.LoginForm"/>
Captulo15JakartaStrutsPgina155

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)CrieoseuarquivoformularioLogin.jsp.
<%@tagliburi="http://struts.apache.org/tagshtml"prefix="html"%>
<html:html>
<title>SistemadeTestesdoStruts</title>
<body>
<html:formaction="/efetuaLogin"focus="funcionario.usuario">
Qualseuusurio?
<html:textproperty="funcionario.usuario"/><br/>
Qualsuasenha?
<html:passwordproperty="funcionario.senha"/><br/>
<html:submit>EnviarDados</html:submit>
</html:form>
</body>
</html:html>

15.5 - A ao
Vamos pensar um pouco na nossa ao de login. Que tal utilizarmos o mtodo
getParameter paralerousurioeasenha?Jvimosqueissomuitochatoeexisteuma
grandechancedeerro.
PodemosentousarnossoFormBeanechamarapenasgetterselegantemente,usandoo
conceitoqueaprendemosnoltimocaptulo.
packagebr.com.caelum.struts.action;
//importsaquiCRTL+SHIFT+O

/**
*@authorCaelum
*/
publicclassLoginActionextendsAction{
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
System.out.println("Algumusurioesttentandoselogar...");

//1.ondeestoasvariveis?Olhaqueelegncia
LoginFormformulario=(LoginForm)form;
Funcionariofuncionario=formulario.getFuncionario();
//2.testasesovlidas
if(!ehValido(funcionario)){
//nosovlidas(oops)
returnmap.findForward(erro);
}
//ok....paraondeiragora?
returnmap.findForward(ok);
}
privatebooleanehValido(Funcionariofunc){
returnfunc.getUsuario().equals("admin")&&
func.getSenha().equals("admin");
}
}
Captulo15JakartaStrutsPgina156

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

15.6 - A ao no struts-config.xml
Agoravamosconfigurarnossaaonostrutsconfig.xml.
Iremos adicionar uma nova action, chamada de '/efetuaLogin' e ela ser ligada a
classe br.com.caelum.struts.action.LoginAction. Introduzimos um novo atributo,
chamado name,quetemovalordonossoformulrio, aquelequeirreceberosdadosdo
requestefacilitaraleituradomesmo!
<?xmlversion="1.0"encoding="ISO88591"?>
<!DOCTYPEstrutsconfigPUBLIC
"//ApacheSoftwareFoundation//DTDStrutsConfiguration1.2//EN"
"http://struts.apache.org/dtds/strutsconfig_1_2.dtd">
<strutsconfig>
<formbeans>
<formbeanname="LoginForm"type="br.com.caelum.struts.form.LoginForm"/>
</formbeans>
<actionmappings>
<actionpath="/efetuaLogin"name="LoginForm"
type="br.com.caelum.struts.action.LoginAction">
<!ForwardsquechamamosnanossaactionLogin!>
<forwardname="erro"path="/erro.jsp"/>
<forwardname="ok"path="/ok.jsp"/>
</action>
</actionmappings>
</strutsconfig>

Oweb.xmleostrutsconfig.xml...
Vocreparouquenoalteramosmaisoweb.xml?
Deagoraemdiante,semprequevocutilizaroStruts,noprecisaralterarosdadosdoweb.xml,
vocirsomenteadicionarnovasaesnoseustrutsconfig.xml.
Sevocachatrabalhosoeditarostrutsconfig.xml,vocpodeutilizarferramentascomooStruts
Consoleparaalterarparaumaediogrficadomesmo.

15.7 - ok.jsp e erro.jsp


Agoravamosescreverasduaspginasmaissimples.Ambasficamnodiretriowebeno
possuemnadadeespecial:
ok.jsp
<html>
Vocselogoucomsucesso!
</html>

erro.jsp
<html>
Ocorreualgumerroaotentarselogar!
</html>

15.8 - Exerccios
1)CriesuaaodeLogin:
packagebr.com.caelum.struts.action;

Captulo15JakartaStrutsPgina157

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

//importsaquiCTRL+SHIFT+O
/**
*@authorCaelum
*/
publicclassLoginActionextendsAction{
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
System.out.println("Algumusurioesttentandoselogar...");

//1.ondeestoasvariveis?Olhaqueelegncia
LoginFormformulario=(LoginForm)form;
Funcionariofuncionario=formulario.getFuncionario();
//2.testasesovlidas
if(!ehValido(funcionario)){
//nosovlidas(oops)
returnmap.findForward(erro);
}
//ok....paraondeiragora?
returnmap.findForward(ok);
}
privatebooleanehValido(Funcionariofunc){
returnfunc.getUsuario().equals("admin")&&
func.getSenha().equals("admin");
}
}

2)Mapeiesuaaonostrutsconfig.xml:
<actionpath="/efetuaLogin"name="LoginForm"
type="br.com.caelum.struts.action.LoginAction">
<!ForwardsquechamamosnanossaactionLogin!>
<forwardname="erro"path="/erro.jsp"/>
<forwardname="ok"path="/ok.jsp"/>
</action>

3)Crieseuarquivook.jsp
<html>
Vocselogoucomsucesso!
</html>

4)Crieseuarquivoerro.jsp
<html>
Ocorreualgumerroaotentarselogar!
</html>

5) Agora para testar a sua pgina de login, basta reiniciar o Tomcat e acessar
http://localhost:8080/struts/formularioLogin.jsp!
a)Testenossoformulriocolocandovaloreseenviandoosdados;deveraparecera
mensagem de sucesso. Agora clique em enviar deixando os campos em branco; dever
apareceramensagemdeerro.

Captulo15JakartaStrutsPgina158

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

ou

b)Asuaestruturadeclassesestparecidacomaseguir?

15.9 - Erros comuns


Aseguirvejaoserrosmaiscomunsnoexerccioanterior:
1) Esquecer de fazer seu LoginForm estender ActionForm: como LoginForm e
ActionFormnopossuemconexo,ocompilador(nocaso,oEclipse),reclamadocastingque
estsendofeitodentrodasuaclasse Action,afinalnenhum ActionForm um LoginForm.
Soluo:estendaActionForm.

15.10 - Exerccios opcionais


1) Altere os seus arquivos formularioLogin.jsp, ok.jsp e erro.jsp para utilizarem a tag
bean:message,lembresedealteraroarquivoMessageResources.properties.
2)Faaorestartdotomcat.
3)Testenovamenteseusistemadeautenticao.

15.11 - Cookies
Oprotocolohttputilizadoatagoraparaoacessopginaslimitadopornomanter
detalhescomoquemquementreumaconexoeoutra,portantofoiinventadoumsistemapara
Captulo15JakartaStrutsPgina159

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

facilitaravidadosprogramadores.
COOKIE

Umcookienormalmenteumpardestringsguardadonocliente,assimcomoummapa
destrings.Essepardestringspossuidiversaslimitaesquevariamdeacordocomocliente
utilizado,oquetornaatcnicadeutilizlosalgodoqualnosedevaconfiarmuito.Jqueas
informaes do cookie so armazenadas no cliente, o mesmo pode alterla de alguma
maneira...sendoinvivel,porexemplo,guardaronomedousuriologado...
Quandoumcookiesalvonocliente,eleenviadodevoltaaoservidortodavezqueo
clienteefetuarumanovarequisio.Destaforma,oservidorconsegueidentificaraquelecliente
semprecomosdadosqueocookieenviar.
Umexemplodebomusodecookiesnatarefadelembraronomedeusurionaprxima
vezqueelequiserselogar,paraquenotenhaqueredigitaromesmo.
Cada cookie s armazenado para um website. Cada website possui seus prprios
cookieseestesnosovistosemoutrapgina.

Cookies:facilidadeesegurana
arriscadotrabalharcomcookiesemsessesquenecessitamdesegurana.Omaisindicado
sempreusarsesses,queserodiscutidaslogoemseguida.
Almdisso,muitopenosoterqueiterarportodososcookiesparaacharumcookieespecfico.A
estruturademapasdeumaSessionfacilitaemmuitootrabalhodevaloresatreladosaumusurio.

Adicionandocookies:comportamentoestranho
Naprimeiravezqueadicionamosumcookienaresposta,elenoestdisponvelparaaleitura
atravsdarequisio.Ahn?
Pararesolveresseproblemacostumamosusarumatributodomtodorequest:request.setAttribute
erequest.getAttribute.Jpodemosperceberquetrabalharcomcookiespodesertrabalhoso.

15.12 - Sesso
Usar Cookies parece facilitar muito a vida....
exceto que atravs de um cookie no possvel
marcar um cliente com um objeto, somente com
Strings. Imagine gravar os dados do usurio logado
atravsdecookies.Serianecessrioumcookiepara
cadaatributo:usuario,senha,id,datadeinscrioetc.
Semcontarafaltadesegurana.
O Cookie tambm pode estar desabilitado no
cliente,sendoquenoserpossvellembrarnadaque
ousuriofez...
SESSO

Uma sesso facilita a vida de todos por


permitiratrelarobjetosdequalquertipoaumcliente,
no sendo limitada somente strings e
independentedecliente.
Aabstraodaapifacilitaotrabalhodoprogramadorpoiselenoprecisasabercomo
queaseofoiimplementadanoservletconteiner,elesimplesmentesabequeafuncionalidade
existeeestlparaouso.Seoscookiesestiveremdesabilitados,aseonoirfuncionare
Captulo15JakartaStrutsPgina160

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

devemosrecorrerparaumatcnica(trabalhosa)chamadaurl-rewriting.
Asessonadamaisqueumtempoqueousuriopermaneceativonosistema.Acada
pginavisitada,otempodesessozerado.Quandootempoultrapassaumlimitedemarcado
noarquivoweb.xml,oclienteperdesuasesso.

15.13 - Configurando o tempo limite


Paraconfigurar3minutoscomoopadrodetempoparaousurioperderasessobasta
incluiroseguintenoarquivoweb.xml:
<sessionconfig>
<sessiontimeout>3</sessiontimeout>
</sessionconfig>

Obs:Segundoaespecificaoessaconfiguraodeveriafuncionar,masnaverso
5.5.12dotomcat,existeumbug.

15.14 - Registrando o usurio logado na sesso


Parautilizartodososrecursosdeumasesso,necessrioprimeirocriaruma,assim
conseguimos marcar um usurio para a prxima vez que ele visitar uma pgina na mesma
aplicaoweb.
ExistemdoismtodosgetSessionnaclasseHttpServletRequest,sendoqueomais
simplesdelenorecebeargumentoseretornaumanovasessocasonoexistanenhuma,oua
sessoquejexistia:
HttpSessionsession=request.getSession();

Comumasessoemmospodemosutilizarseusmtodosmaisbsicos:
Objectsession.getAttribute(String)
Enumerationsession.getAttributeNames()
session.setAttribute(String,Object)
session.removeAttribute(String)
session.invalidate()
booleansession.isNew()

Retorna o objeto (Object) marcado com uma


chave(String)
Retorna uma enumerao com todos os nomes
dosatributos
Colocaumobjeto(Object)emumachave(String)
domapa
Removeumatributodasesso
Invalidaasesso
Verifica se a sesso nova e foi criada nessa
requisio

Comoexemplo,podemostrabalhardaseguintemaneira:
HttpSessionsession=request.getSession();
session.setAttribute(nome,valor);

EvalelembrarqueonomedeveserumaStringeovalorpodeserumobjetoqualquer!

Vantagensedesvantagens
Vantagens:
maisdifcilparaoclienteforjarseralgumqueeleno
os objetos so armazenados no servidor e noprecisam ser reenviados em toda requisio
(apenasolinkdesessoprecisaserenviado)
Captulo15JakartaStrutsPgina161

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

qualquerobjetoJavapodeserutilizadocomovalorsalvonaseo,noselimitandoapenasa
strings
Desvantagens:
oservidorperdeodadoseonavegadorforfechado
umaseonoobrigatoriamenteamesmaemdiferentesinstnciasdomesmonavegadorno
mesmoclienteacessandoamesmaaplicaoweb,oservidornocontrolaocliente!Vocno
sabecomoeleirfuncionar!

15.15 - Exerccios
1)Aologarumusuriocomsucesso,adicioneesseusuriosesso:
a)Trabalhedentrodaaodeloginantesdeirparaapginadeok
b)Acesseasesso:
HttpSessionsession=request.getSession();

c)Adicioneousuriosesso:
session.setAttribute(funcionario,funcionario);

2)CrieumapginatestaLogin.jsp
a)Adicioneocabealhoparaousodajstlcore.
b)Seobeanusuariofornull,issosignificaqueousuario noestavalogado,sefor
diferentequenullpodemosimprimirseunome!
<c:choose>
<c:whentest=${emptyfuncionario}>
Vocnoestlogado!
</c:when>
<c:otherwise>
Vocestlogadocomo${funcionario.usuario}esenha${funcionario.senha}
</c:otherwise>
</c:choose>

c)Testeacessarapginadetestesemselogar

d)Testeacessarapginadetesteapsselogar

Captulo15JakartaStrutsPgina162

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

3)Faaumanovaclassedeformulriocomnmerosinteirosefloats.
Utilizeesseformulrioemumapginaeumaao.
NoprecisafazercastingoutraduodeStringparaoutrotipo!OStrutsjfazissopara
voc!

Logandonovamente
Reparequeaoacessarapginadeloginapsterselogado,seuusuriopermanecenasesso.
Sendoassim,sevocerrarousurio/senha,voccontinualogado!
ParafazerologoutvocpodeusaromtodoremoveAttributedaclasseHttpServletRequest.

15.16 - Mas e o login acessando o banco de dados?


Uma pergunta comum como alterar a classe de login para acessar o banco. Essa
perguntaremeteaosprimeirosmomentosdocursoquandocriamosodao.
Nosso objetivo ento saber se um usurio e senha existem no banco, portanto
precisamosdeummtododeumaclassedotipoDaoquefaataltarefa.
Por exemplo, o mtodo a seguir poderia ser utilizado em uma classe chamada
ValidaLoginDao:
publicbooleanexisteUnico(Stringusuario,Stringsenha)throwsSQLException
{

//preparedstatementparaselect
PreparedStatementstmt=this.connection.prepareStatement("select*
fromfuncionarioswherenome=?andsenha=?");
//setaosvalores
stmt.setString(1,usuario);
stmt.setString(2,senha);
ResultSetrs=stmt.executeQuery();
booleanvalido=rs.next();
if(valido&&rs.next()){
//existemaisdeum
valido=false;
}
rs.close();
stmt.close();
returnvalido;
}

Captulo15JakartaStrutsPgina163

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

16

16

Hibernate 3.2

uma experincia eterna de que todos os homens com poder


so tentados a abusar.
BarondeMontesquieu

Nestecaptulo,vociraprendera:
usaraferramentadeORMHibernate
gerarastabelasemumbancodedadosqualquerapartirdesuasclassesdemodelo
automatizarosistemadeadicionar,listar,removereprocurarobjetosnobanco
utilizaranotaesparafacilitaromapeamentodeclassesparatabelas
criarclassesdedaobemsimplesutilizandoohibernate

16.1 - Vantagens
AutilizaodecdigoSQLdentrodeumaaplicaoagravaoproblemadaindependncia
de plataforma de banco de dados e complica, em muito, o trabalho de mapeamento entre
classesebancodedadosrelacional.
HIBERNATE

O Hibernate abstraiocdigoSQLdanossaaplicaoepermiteescolherotipode
bancodedadosenquantooprogramaestrodando,permitindomudarsuabasesemalterar
nadanoseucdigoJava.
Almdisso,elepermitecriarsuastabelasdobancodedadosdeumjeitobemsimples,
nosefazendonecessriotodoumdesigndetabelasantesdedesenvolverseuprojetoque
podesermuitobemutilizadoemprojetospequenos.
JprojetosgrandesondeoplanodeaopadrotomadopeloHibernatenosatisfazas
necessidadesdaempresa(comoousodeselect*,joinsetc),elepossuidezenasdeotimizaes
quepodemserfeitasparaatingirtalobjetivo.

16.2 - Criando seu projeto


Para criar seu projeto, necessrio baixar os arquivos .jar necessrios para rodar o
Hibernateecoloclosnoclasspathdomesmo.
Ositeoficialdohibernateowww.hibernate.orgelvocpodebaixaraltimaverso
estveldomesmonaseoDownload.Apsdescompactaressearquivo,bastacopiartodosos
jarsparaonossoprojeto.
HIBERNATE
ANNOTATION
S

AindafaltabaixarasclassescorrespondentesaoHibernateAnnotations,queiremos
utilizar para gerar o mapeamento entre as classes Java e o banco de dados. Eles so
encontradostambmnositedohibernateecontemoutrosjarsquedevemoscolocarnonosso
projeto.
Antigamente(ataverso2dohibernate)omapeamentoerafeitosomenteatravsde
Captulo16Hibernate3.2Pgina164

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

arquivosxml,queerabemchato,eutilizvamosdeumaferramentachamdaXdocletquecriava
taisxmls.HojeemdiaoXdocletfoisubstituidopelasAnnotations.

Bancodedados
O Hibernate traduz suas necessidades em cdigo SQL para qualquer banco de dados.
ContinuaremosutilizandooMySqlemnossosexemplos,portantonoesqueadecopiaroarquivo
.jarcorrespondenteaodriverparaodiretriolibdesuaaplicao.

16.3 - Modelo
Iremosutilizarumaclassequemodelaumprodutoparaestecaptulo:
packagebr.com.caelum.hibernate;

/**
*Classedemodeloparaumproduto
*/
publicclassProduto{
privateLongid;
privateStringnome;
privateStringdescricao;
privateDoublepreco;
//adicioneseusgettersesettersaqui!
}

16.4 - Configurando a classe/tabela Produto


Paraconfiguraranossaclasse Produto,bastaadicionaralgunscomentriosespeciais
nadefiniodaclasseenosmtodosget.Ocdigoaseguircolocanossaclassenatabela
"produtos"esetaalgumaspropriedadeseoid.
Ateno: toda classe que vai trabalhar com o Hibernate precisa de um
(ou mais) campo(s) que ser a chave primria (composta ou no).
Fora isso, existem diversas opes que podemos colocar como configurar para no
aceitarcamposnulloumudaronomedacolunaporexemplo.Paraler
packagebr.com.caelum.hibernate;

@Entity
publicclassProduto{
@Column(name=descricao,nullable=true,length=50)
privateStringdescricao;
@Id@GeneratedValue
privateLongid;
privateDoublepreco;
privateStringnome;

AespecificaodoEJB3definetaisanotaesepossuidiversasopesquepodemos
utilizaremnossoprojeto.Semprequepossuiralgumaduvidaemrelaoasanotaeslembre
sedeleratalespecificao.

Captulo16Hibernate3.2Pgina165

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

16.5 - Exerccios
1)Descompacteohibernateeohibernateannotations:
cd
tarzxf/caelum/zips/21/hibernate3<TAB>
tarzxf/caelum/zips/21/hibernateann<TAB>
2)Copieosarquivos.jardeambosprojetosnoseudiretriolib(noesqueamdos.jar
queestodentrododiretriolibdodiretriodohibernate).
3)CrieumaclassechamadaProdutonopacotebr.com.caelum.hibernate.
4)Adicioneasseguintesvariveismembro:
privateLongid;
privateStringnome;
privateStringdescricao;
privateDoublepreco;

5)Gereosgettersesettersusandooeclipse.
6)Anoteasuaclasse.Lembresedeimportarasanotaesdopacotejavax.persistence.
@Entity
publicclassProduto{
...
}

7)Anoteseufieldid:
@Id
@GeneratedValue
privateLongid;

16.6 - Propriedades do banco


HIBERNATE.
PROPERTIES

Precisamos criar nosso arquivo de configurao, o hibernate.properties. Copie o


arquivodemesmonomequeestnodiretriosrcdescompactadoquevocbaixou(odiretrio
dohibernate)nodiretriosrcdesuaaplicao.
Porpadroaconfiguraoestdetalmaneiraqueohibernateirusarumbancode
dadosdotipoHypersonicSQL.Comenteaslinhasdomesmo(colocando#nocomeo).Agora
descomenteapartequeutilizaomysqleconfigurecorretamenteamesma,porexemplo:

hibernate.dialectorg.hibernate.dialect.MySQLDialect
hibernate.connection.driver_classcom.mysql.jdbc.Driver
hibernate.connection.urljdbc:mysql://localhost/teste
hibernate.connection.usernameroot
hibernate.connection.password

16.7 - Exerccios
1)Crieoarquivohibernate.propertiesnoseudiretoriosrc.
hibernate.dialectorg.hibernate.dialect.MySQLDialect
hibernate.connection.driver_classcom.mysql.jdbc.Driver
hibernate.connection.urljdbc:mysql://localhost/teste
hibernate.connection.usernameroot
Captulo16Hibernate3.2Pgina166

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


hibernate.connection.password

16.8 - Configurando
Nosso primeiro passo configurar o hibernate, portanto iniciamos instanciando uma
org.hibernate.cfg.AnnotationConfiguration.
//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();

Apartirdapodemosadicionarquantasclassesdesejarmosanossaconfigurao.
//AdicionaaclasseProduto
cfg.addAnnotatedClass(Produto.class);

NonossocasoiremosadicionarsomenteanossaclasseProduto,gerandooseguinte
resultadoparaconfiguraroHibernate:
//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
//AdicionaaclasseProduto
cfg.addAnnotatedClass(Produto.class);

SissonosuficienteparaqueoHibernateestejaconfiguradocomaclasseProduto.
OHibernaterequerquedescrevamoscomoaclasseserelacionacomastabelasnobancode
dadosefizemosissoatravsdasanotaesdoHibernate.
Essaconfiguraopoderiaserfeitaatravsdeumarquivoxmlchamadohibernate.cfg.xml.

16.9 - Criando as tabelas


Vamos criar um programa que gera as tabelas do banco. Dada uma configurao, a
classeSchemaExportcapazdegerarocdigoDDLdecriaodetabelasemdeterminado
banco(nonossocaso,omysql).
Paraexportartaistabelas,fazemosusodomtodocreatequerecebedoisargumentos
booleanos.OprimeirodizsedesejamosverocdigoDDLeosegundosedesejamosexecut
lo.
newSchemaExport(cfg).create(true,true);

16.10 - Exerccios
1)CrieaclasseGeraTabelas.
packagebr.com.caelum.hibernate;
publicclassGeraTabelas{
publicstaticvoidmain(String[]args){

//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
newSchemaExport(cfg).create(true,true);
}
}

2)Criesuastabelasexecutandoocdigoanterior.

Captulo16Hibernate3.2Pgina167

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

OHibernatedevereclamarquenoconfiguramosnenhumarquivodelogparaele(dois
warnings)emostrarocdigoSQLqueeleexecutounobanco.

16.11 - Sesses
Agorajpodemospegarumafbricadesessesdotipo SessionFactory,paraisso
bastachamaromtodobuildSessionFactorydoobjetocfg.
packagebr.com.caelum.hibernate;
publicclassTesteDeConfiguracao{
publicstaticvoidmain(String[]args){

//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
SessionFactoryfactory=cfg.buildSessionFactory();
factory.close();
}
}

OHibernategerasessesatravsdessafactory.Essassessessoresponsveisporse
conectaraobancodedadosepersistirebuscarobjetosnomesmo.
Amaneiramaissimplesdebuscarumanovasessoefecharamesma:
packagebr.com.caelum.hibernate;
publicclassTesteDeConfiguracao{
publicstaticvoidmain(String[]args){

//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
SessionFactoryfactory=cfg.buildSessionFactory();
//criaasesso
Sessionsession=factory.openSession();
//fechaasesso
session.close();
factory.close();
}
}
Captulo16Hibernate3.2Pgina168

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

16.12 - Exerccios
1) Faa uma classe chamada TesteDeConfiguracao dentro do pacote
br.com.caelum.hibernate.NomomentodeimportarSessionlembresequenoaclassic!
packagebr.com.caelum.hibernate;
//faaimportsaquiCTRL+SHIFT+O
publicclassTesteDeConfiguracao{
publicstaticvoidmain(String[]args){

//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
SessionFactoryfactory=cfg.buildSessionFactory();
//criaasesso
Sessionsession=factory.openSession();
//fechaasesso
session.close();
factory.close();
}
}

16.13 - Hibernate Session Factory


VamoscriaragoraumaclasseHibernateFactoryquecuidarde:
instanciaraSessionFactorydoHibernate;
nosdarSessionsdohibernatequandosolicitada.
publicclassHibernateFactory{
privatestaticSessionFactoryfactory;
static{
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
factory=cfg.buildSessionFactory();
}
publicSessiongetSession(){
returnfactory.openSession();
}
}

O bloco esttico das linhas 4 a 8 cuidar de configurar o Hibernate e pegar uma


SessionFactory. Lembrese que o bloco esttico executado automaticamente quando a
classecarregadapeloClass Loaderesnestemomento;elenoserexecutadooutras
vezes,comoquandovocdernewHibernateFactory().
O mtodo getSession devolver uma Session, conseguida atravs do
SessionFactorydoHibernate.

16.14 - Exerccios
Captulo16Hibernate3.2Pgina169

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

1)CrieasuaclasseHibernateFactorynopacotebr.com.caelum.hibernate.Nomomento
deimportarSessionlembresequenoaclassic!
packagebr.com.caelum.hibernate;
publicclassHibernateFactory{
privatestaticSessionFactoryfactory;
static{
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
factory=cfg.buildSessionFactory();
}
publicSessiongetSession(){
returnfactory.openSession();
}
}

16.15 - Salvando novos objetos


AtravsdeumobjetodotipoSessionpossvelgravarnovosobjetosdotipoProduto
nobanco.Paratantobastacriaroobjetoedepoisutilizaromtodosave.

SAVE

Sessionsession=newHibernateFactory().getSession();
Produtop=newProduto();
p.setNome("Nomeaqui");
p.setDescricao("Descrioaqui");
p.setPreco(100.50);
session.save(p);
System.out.println("IDdoproduto:"+p.getId());
session.close();

16.16 - Exerccios
1)CrieumaclassechamadaAdicionaProdutonopacotebr.com.caelum.hibernate.
packagebr.com.caelum.hibernate;
//ImportsaquiCTRL+SHIFT+O
publicclassAdicionaProduto{
publicstaticvoidmain(String[]args){
Sessionsession=newHibernateFactory().getSession();
Produtop=newProduto();
p.setNome("Nomeaqui");
p.setDescricao("Descrioaqui");
p.setPreco(100.50);
session.save(p);
System.out.println("IDdoproduto:"+p.getId());
session.close();
}
}

2)Adicionecercade5produtosnobanco.
Captulo16Hibernate3.2Pgina170

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Possivelsaida:

16.17 - Buscando pelo id


Parabuscarumobjetopeloseuid,utilizamosomtodoload:
Sessionsession=newHibernateFactory().getSession();
Produtoencontrado=(Produto)session.load(Produto.class,newLong(1));
System.out.println(encontrado.getNome());

16.18 - Criando o ProdutoDAO


Com os mtodos que j conhecemos, podemos criar uma classe DAO para o nosso
Produto:
publicclassProdutoDAO{
privateSessionsession;
publicProdutoDAO(Sessionsession){
this.session=session;
}
publicvoidsalva(Produtop){
this.session.save(p);
}
publicvoidremove(Produtop){
this.session.delete(p);
}
publicProdutoprocura(Longid){
return(Produto)this.session.load(Produto.class,id);
}
publicvoidatualiza(Produtop){
this.session.update(p);
}
}

AtravsdesseDAO,podemossalvar,remover,atualizareprocurarProdutos.

16.19 - Exerccios
1)FaaumaclassechamadaProdutoDAOdentrodopacotebr.com.caelum.hibernate.dao
packagebr.com.caelum.hibernate.dao;
//importsaquiCTRL+SHIFT+O
Captulo16Hibernate3.2Pgina171

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

publicclassProdutoDAO{
privateSessionsession;
publicProdutoDAO(Sessionsession){
this.session=session;
}
publicvoidsalva(Produtop){
this.session.save(p);
}
publicvoidremove(Produtop){
this.session.delete(p);
}
publicProdutoprocura(Longid){
return(Produto)this.session.load(Produto.class,id);
}
publicvoidatualiza(Produtop){
this.session.update(p);
}
}

2) Adicione diversos objetos diferentes no banco de dados usando sua classe


ProdutoDAO.
3)Busqueumidinvlido,quenoexistenobancodedadosedescubraqualoerroqueo
Hibernategera.Eleretornanull?ElejogaumaException?Qual?

16.20 - Buscando com uma clusula where


OHibernatepossuiumalinguagemprpriadequeriesparafacilitarabuscadeobjetos.
Porexemplo,ocdigoaseguirmostraumapesquisaqueretornatodososprodutoscomidmaior
que2:
Sessionsession=newHibernateFactory().getSession();
List<Produto>lista=session.createQuery("frombr.com.caelum.hibernate.Produto
whereid>2").list();
for(Produtoatual:lista){
System.out.println(atual.getNome());
}

16.21 - ProdutoDAO: Listar tudo e fazer paginao


VamosincluirmaisdoismtodosnanossaclasseProdutoDAO.
Primeiro,vamoslistartodososprodutosexistentesnobancodedados.Paraisso,vamos
Captulo16Hibernate3.2Pgina172

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


CRITERIA

usar o mtodo createCriteria de Session que cria um Criteria. Atravs de um


Criteria,temosacessoadiversasoperaesnobancodedados;umadelaslistartudocom
omtodolist().
NossomtodolistaTudo()ficaassim:

publicList<Produto>listaTudo(){
returnthis.session.createCriteria(Produto.class).list();
}

Masomtodoacimadevolvealistacomtodososprodutosnobancodedados.Emum
sistemacomlistagenslongas,normalmenteapresentamosalistaporpginas.Paraimplementar
paginao,precisamosdeterminarquealistagemdevecomearemumdeterminadopontoeser
deumdeterminadotamanho.
FIRSTRESULT
MAXRESULTS

Usando o Criteria, como no listaTudo anteriormente, isso bastante simples. Nosso


mtodopginaficaassim:

publicList<Produto>pagina(intinicio,intquantia){
returnthis.session.createCriteria(Produto.class).
setMaxResults(quantia).setFirstResult(inicio).list();
}

O mtodo setMaxResults determina otamanho da lista (resultados por pgina) eo


mtodo setFirstResult determinaemquepontoalistagemdeveterincio.Porfim,basta
chamaromtodolist()ealistagemdevolvidaserapenasdaquelapgina!

16.22 - Exerccios
1)ModifiqueasuaclasseProdutoDaoeacrescenteosmtodoslistaTudo()ePagina()
packagebr.com.caelum.hibernate.dao;
//importsaquiCTRL+SHIFT+O
publicclassProdutoDAO{
privateSessionsession;
publicProdutoDAO(Sessionsession){
this.session=session;
}
publicvoidsalva(Produtop){
this.session.save(p);
}
publicvoidremove(Produtop){
this.session.delete(p);
}
publicProdutoprocura(Longid){
return(Produto)this.session.load(Produto.class,id);
}
publicvoidatualiza(Produtop){
this.session.update(p);
}
publicList<Produto>listaTudo(){
returnthis.session.createCriteria(Produto.class).list();
}
Captulo16Hibernate3.2Pgina173

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


publicList<Produto>pagina(intinicio,intquantia){
returnthis.session.createCriteria(Produto.class).
setMaxResults(quantia).setFirstResult(inicio).list();
}
}

16.23 - Exerccios para o preguioso


LAZY

1)Testeumprogramaquefazsomenteoseguinte:buscaumprodutoporid.Ocdigo
devesomentebuscaroprodutoenoimprimirnada!Qualoresultado?
Sessionsession=newHibernateFactory().getSession();
Produtoencontrado=(Produto)session.load(Produto.class,newLong(1));

2)Tenteimprimironomedoprodutodotesteanterior,oqueacontece?
Sessionsession=newHibernateFactory().getSession();
Produtoencontrado=(Produto)session.load(Produto.class,newLong(1));
System.out.println(encontrado.getNome());

3)Antesdeimprimironomedoproduto,tenteimprmirumamensagemqualquer,dotipo:
Oselectjfoifeito.Eagora?Comoissopossvel?
Sessionsession=newHibernateFactory().getSession();
Produtoencontrado=(Produto)session.load(Produto.class,newLong(1));
System.out.println(Oselectjfoifeito);
System.out.println(encontrado.getNome());

Ento,ondeestocdigodoselect?EledeveestarnomtodogetNome(),certo?
4)Imprimaonomedaclassedoobjetoreferenciadopelavarivelencontrado:
Sessionsession=newHibernateFactory().getSession();
Produtoencontrado=(Produto)session.load(Produto.class,newLong(1));
System.out.println(Oselectjfoifeito);
System.out.println(encontrado.getNome());
System.out.println(encontrado.getClass().getName());

OHibernateretornaumobjetocujotipoestendeProduto:elenodeixadeserumProduto
masnosomenteumProduto.
OmtodogetNomefoisobrescritonessaclasseparafazerabuscanaprimeiravezque
chamado,economizandotempodeprocessamento.
claroqueparafazerofinetuningdoHibernateinteressanteconhecermuitomaisa
fundooqueoHibernatefazecomoelefazisso.

16.24 - Exerccios opcionais


1)Crieumsistemaparacadastroelistagemdeprodutosusandoostruts.Sigaopadro
queutilizamosparacadastroelistagemdecontatos.

Captulo16Hibernate3.2Pgina174

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

17

17

E agora?
A nuca um mistrio para a vista.
PaulValry

Ondecontinuaraoterminarocurso'Javaparaodesenvolvimentoweb'.

17.1 - Certificao
Entraremdetalhesnosassuntoscontidosatagorairiamnomnimotornarcadacaptulo
quatrovezesmaiordoquej.
Ostpicosabordados(comaadioeremoodealguns)constituemboapartedoque
cobradonacertificaooficialparadesenvolvedoreswebdaSun.
ParamaioresinformaessobrecertificaesconsulteaprpriaSun,ojavaranch.comou
oguj.com.brquepossuidiversasinformaessobreoassunto.

17.2 - Frameworks
Diversos frameworks foram desenvolvidos para facilitar o trabalho de equipes de
desenvolvimento.
Aqueles que pretendem trabalhar com Java devem a qualquer custo analisar as
vantagensedesvantagensdamaiorpartedessesframeworksquediminuemonmerodelinha
decdigonecessriasefacilitamocontroleeorganizaodeumaaplicao.
Porexemplo,ovRaptorumexemplodecontroladorsimplesebomparainiciantes.O
Hibernateumtimopasso,assimcomooprevayler,parapersistncia/prevalnciadeobjetos.
Domesmojeitoqueessesarcabouossurgemecrescemrepentinamente,elespodem
perderforaparaoutrosquetenhamnovidadescriativas.Eocicloserepete.

17.3 - Revistas
Diversasrevistas,noBrasilenoexterior,estudamomundojavacomoningumepodem
ajudaroinicianteaconhecermuitodoqueestacontecendolforanasaplicaescomerciais.
GrupodeUsurios
Diversosprogramadorescomomnimooumximodeconhecimentoserenemonline
paraatrocadedvidas,informaeseidiassobreprojetos,bibliotecasemuitomais.Umdos
maisimportantesefamososnoBrasiloGUJwww.guj.com.br

17.4 - Falando em Java


O 'Falando em Java' no para por aqui, continua com o curso preparatrio para
certificaoparaprogramadoresouodeEnterpriseJavaBeans...
Captulo17Eagora?Pgina175

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Consulteositeoficialdo'FJ'emwww.caelum.com.brpararecebermaisinformaes.
Os autores dessa edio, Paulo Eduardo Azevedo Silveira e Guilherme de Azevedo
Silveira agradecem ao leitor pelo tempo investido e esperam ter ajudado a converter mais
algumparaomundodaorientaoaobjetos.

Captulo17Eagora?Pgina176

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

18

Apndice A - VRaptor

18

Aquele que castiga quando est irritado, no corrige, vinga-se


MicheldeMontaigne

Nestecaptulo,vociraprender:
oqueInversodeControle,InjeodeDependnciaseConventionoverConfiguration
comoutilizarumframeworkMVCbaseadoemtaisidias
comoabstrairacamadadehttpdesualgicadenegcios

18.1 - Eu no quero o que eu no conheo


Podemos lembrar como fica um cdigo utilizando um framework MVC simples para
acessar os parmetros enviados pelo cliente. fcil notar como as classes, interfaces e
apetrechos daquele MVC infectam o nosso cdigo e comeamos a programar voltado a tal
framework:
publicclassAdicionaContatoimplementsAction{
publicStringexecuta(HttpServletRequestreq,HttpServletResponse res)
throwsException{
Contatocontato=newContato();
contato.setNome(req.getParameter("nome"));
contato.setEndereco(req.getParameter("endereco"));
contato.setEmail(req.getParameter("email"));
ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);
return"/ok.jsp";
}
}

Baseado no cdigo acima, percebemos que estamos fortemente atrelados a


HttpServletRequest e seu mtodo getParameter. Fora isso, usamos diversas classes
estranhasaonossoprojeto: Action, HttpServletRequest e HttpServletResponse.Se
estivessemos controlando melhor a conexo, ainda teriamos que importar Connection
tambem! Nenhuma dessas classese interfaces citadas faz parte do nossoprojeto! Noo
nossocdigo!
muitochatoenadaprticorepetirissoemtodaasuaaplicao:visandofacilitaresse
tipodetrabalhovimosqueoStruts,porexemplo,utilizaumrecursochamadoActionFormque
facilitaonossotrabalho:
publicclassAdicionaContatoextendsAction{
publicActionForwardexecute(ActionMappingmap,

ActionForm
form,HttpServletRequestreq,HttpServletResponseres)
throwsException{
Contatocontato=newContato();
BeanUtils.copyProperties(contato,form);

Captulo18ApndiceAVRaptorPgina177

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);
returnmap.findForward("ok");
}
}

Masmesmoassim,imagineoslimitesdetalcdigo:
VocNOpoderecebermaisdeumactionform
SuaclasseDEVEestenderActionForm.Sevocqueriaestenderoutra,azaroseu
VocDEVErecebertodosessesargumentosquenoforavocquemcriou
VocDEVEretornaressetipoquenoforavocquemcriou
VocDEVEtrabalharcomStringsoutiposmuitopobres
O cdigo fica muito alienado: ele escrito de tal forma a agradar o framework e no o
contrrio.
Vocacabacriandoclassesrepetidas:devecriardoisbeansrepetidosouparecidos,ouainda
escrevermuitocodigoxmlparasubstituirumdeles
CUSTOMIZATI

ON OVER
CONFIGURATI
Detaisproblemassurgiramdiversosoutrosframeworks,inclusivediversospatternsnovos,
ON
INJECAO DE
entreeles,InjeodeDependncias(DependencyInjection),Inverso
de Controle (Inversion
DEPENDENCI
of
Control

IoC)
e
Prefira
convenes
em
vez
de
customizao
(Convention over
AS
INVERSAO DE
CONTROLE
Configuration CoC).

18.2 - Vantagens

Voc desconectaoseuprogramada camada web, criando aesou comandosque no


trabalhamcomrequesteresponse
Vocrecebetodososobjetosqueprecisaparatrabalhardamaneiraquedesejar

18.3 - Vraptor 2
Tudooquefaremosnestecaptuloestbaseadonoframeworkconhecidocomovraptor
(http://vraptor2.sourceforge.net).

18.4 - Instalando e configurando o VRaptor


Passo1:Entrenositeebaixeovraptor.
Passo2:Coloqueosarquivos.jarnecessriosdentrodoseudiretriolib.
Passo3:Configureasuaservletdovraptor:
<servlet>
<servletname>vraptor2</servletname>
<servletclass>org.vraptor.VRaptorServlet</servletclass>
</servlet>
<servletmapping>
<servletname>vraptor2</servletname>
<urlpattern>*.logic</urlpattern>
</servletmapping>

Passo4:Crieumarquivochamadovraptor.xmldentrodoseudiretriosrc.

18.5 - Minha primeira lgica de negcios


Captulo18ApndiceAVRaptorPgina178

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Vamos agora escrever uma classe que adiciona um Contato a um banco de dados
atravsdoDAO e do uso do Vraptor 2:
@Component(contato)
publicclassAdicionaContato{

//meucontato
@Read
@Out
privateContatocontato=newContato();

//aao
publicvoidadiciona()throwsException{
newContatoDAO().adiciona(contato);
}
}

Pronto!assimqueficaumaaodeadicionarcontatoutilizandoessecontrolador(e
podemosmelhorarmaisainda!).Vamosagoraconfigurarovraptor.xml:
<vraptor>
<component>br.com.caelum.vraptor.AdicionaContato</component>
</vraptor>

Esesurgiranecessidadedecriarummtodoatualiza?Poderamosreutilizaramesma
classeparaosdoismtodos:
@Component(contato)
publicclassContatoLogic{

//meucontato
@Read(create=true)
@Out
privateContatocontato;

//aaoadiciona
publicvoidadiciona()throwsException{
newContatoDAO().adiciona(contato);
}
//aaoatualiza
publicvoidatualiza()throwsException{
newContatoDAO().altera(contato);
}
}

Oprprioframeworkchamaosmtodos:
contato.setNome(request.getParameter("contato.nome"));
contato.setEmail(request.getParameter("contato.email"));
contato.setDescricao(request.getParameter("contato.descricao"));

Tudoissoautomaticamente!

18.6 - E o jsp com o formulrio? web/vraptor-formulario.jsp


Parafazercomqueoframeworkfuncione,bastaconfigurarmoscorretamenteoscampos
doformulriononossocdigohtml.Nohsegredoalgum!
<html>
<formaction="contato.adiciona.logic">
Nome:<inputname="contato.nome"/><br/>

Captulo18ApndiceAVRaptorPgina179

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


Email:<inputname="contato.email"/><br/>
Endereco:<inputname="contato.endereco"/><br/>
<inputtype="submit"/>
</form>
</html>

18.7 - E a pgina final? web/contato/adiciona.ok.jsp


Precisamoscriarumapginaquemostreumamensagemdesucesso,aproveitamose
confirmamosainclusomostrandoosdadosqueforamincludos:
<html>
Seucontatofoiadicionadocomsucesso!<br/>
<ahref="mailto:${contato.email}">${contato.nome}</a>,${contato.endereco}<br/>
</html>

Mas parece que esse arquivo est acessando a varivel contato. Onde est ela? O
frameworkqueimplementouoIoC vaichamaromtodo getContato() todavezquevoc
pediracessoavarivelcontato!Assimvocficalivredorequest.get/setAttribute!
Qual o nome desse arquivo? Crie um diretrio com o nome do seu component:
web/contato.
Agoracrieumarquivo comonomedalgicaeovalor deretornodasualgica(por
padro,ok):web/contato/adiciona.ok.jsp.Pronto!

18.8 - Como configurar esse redirecionamento?


Noprecisa.

18.9 - Exerccios
1)Crieumsistemadeinclusodecontatos
a)CrieaclasseContatoLogicnopacotebr.com.caelum.vraptor
@Component(contato)
publicclassContatoLogic{

//meucontato
@Read(create=true)
@Out
privateContatocontato;

//aaoadiciona
publicvoidadiciona()throwsException{
newContatoDAO().adiciona(contato);
}
//aaoatualiza
publicvoidatualiza()throwsException{
newContatoDAO().altera(contato);
}
}

b)Crieoarquivoweb/vraptorformulario.jsp
<html>
<formaction="contato.adiciona.logic">
Nome:<inputname="contato.nome"/><br/>
Email:<inputname="contato.email"/><br/>
Captulo18ApndiceAVRaptorPgina180

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


Endereco:<inputname="contato.endereco"/><br/>
<inputtype="submit"/>
</form>
</html>

c)Crieodiretrioweb/contato
d)Crieoarquivoadiciona.ok.jspnodiretrioweb/contato
<html>
Seucontatofoiadicionadocomsucesso!<br/>
<ahref="mailto:${contato.email}">${contato.nome}</a>,${contato.endereco}<br/>
</html>

e)Configureovraptor.xml
<vraptor>
<component>br.com.caelum.vraptor.ContatoLogic</component>
</vraptor>

f)Vocimportoualgumaclassedopacotejavax.servlet?
g)Testeoseuformulrio:http://localhost:8080/struts/vraptorformulario.jsp
2)Crieumsistemadelistagemdecontatos
a)CrieaclasseListaContatonopacotebr.com.caelum.vraptor
b)Crieoarquivoweb/contato/lista.ok.jsp
c)Configureovraptor.xml
d)Vocimportoualgumaclassedopacotejavax.servlet?
3)Tentevalidarprogramticamenteocontatoantesdeseradicionado.Comovoc
podefazerissodeumjeitobemsimples?Aprendamaisnositedovraptor.

18.10 - Log
Sevocdesejaverasinformaesdelogqueovraptor(eoutrasbibliotecasqueutlizamo
log4j)mostra,configureoarquivolog4j.xmlnodiretoriosrc:
<?xmlversion="1.0"encoding="UTF8"?>
<!DOCTYPElog4j:configurationSYSTEM"log4j.dtd">
<log4j:configurationxmlns:log4j="http://jakarta.apache.org/log4j/">

<appendername="stdout"class="org.apache.log4j.ConsoleAppender">
<layoutclass="org.apache.log4j.PatternLayout">
<paramname="ConversionPattern"
value="%d{HH:mm:ss,SSS}%5p[%20c{1}]%m%n"/>
</layout>
</appender>
<categoryname="org.vraptor">
<priorityvalue="ERROR"/>
<appenderrefref="stdout"/>
</category>
</log4j:configuration>
Captulo18ApndiceAVRaptorPgina181

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

18.11 - Um pouco mais...


1) Atravs de interceptadores possvel controlar o acesso a um sistema para
implementar seu componente de login ou fornecer objetos do tipo DAO para toda a sua
aplicao.

Captulo18ApndiceAVRaptorPgina182

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

19

19

Apndice B - Jakarta Velocity


Aquele que castiga quando est irritado, no corrige, vinga-se
MicheldeMontaigne

Nestecaptulo,vociraprender:
umanovacamadadevisualizao
maissimplesquejsp
comoutilizlajuntoaoStruts
menospoderosa,comumfocodiferentedomesmo

19.1 - Velocity
VELOCITY
TEMPLATES

Velocity um framework do grupo Jakarta feito para interpretar e renderizar


templates.
AidiaerasubstituiroJSPcomumacamadamaissimplesdeaprendereutilizar.Na
poca que o desenvolvimento visando o Modelo 1 (somente com pginas jsp) ainda
predominava,ogrupoJakartalanouesseframeworkparaacamadadevisualizao,queviriaa
seradotadopordiversasempresas.
Ostemplatesdevemserescritosdeumamaneiramuitosimples,emespecial,parafazer
comqueosdesignerspossamtrabalharsemterdeinterferiremalgocomplicadocomoumJSP.
ValelembrarqueoVelocity,assimcomooutrosframeworksconhecidospelomercado,
noomaisadotadopelomesmo.AtendnciadeutilizaroJSPpoistodomundoconhece
JSP.
Positivo: Sendo assim, voc que j est apto a mostrar sua prpria opinio sobre os
frameworksutilizadosnasuaempresaeaquinocurso,podeargumentarqueoJSPnouma
boasoluodevidoaliberdadequeeledaosprogramadoresdecolocarqualquercdigojava
dentrodeles.
Negativo: Do mesmo jeito que tirar a liberdade do programador na camada de
visualizaopodeservistocomopontopositivoporcontrolar melhoroserrosqueomesmo
possafazer,tambmpodemosjulgarissocomonegativo,sendoqueoprogramadornopode
fazertudooquequiser.
Paraprogramadoresplenosousniors,chegaaserindiferenteousodeumoudeoutro,
poisutilizarasmelhorestcnicasdeprogramaoemqualquerumdosdoisambientes.
J aqueles que comeam com a linguagem Java possuem aquela tendncia de no
separarocdigodavisualizaodacamadadeacessoaobancodedados.Sendoassim,para
essesprogramadores,recomendadoprimeiroumaprofundamentonatecnologiaenoMVC
antesdeescrevercdigojavanoseuarquivoJSP.
Umaregrabsicasempretiraralgicadeprogramaodasuapginaoutemplatee
Captulo19ApndiceBJakartaVelocityPgina183

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

coloclaemsuasaesouregradenegcios.Sempre.
Adocumentao,arquivos,bibliotecaetcdoVelocitypodemserencontradosem:
http://jakarta.apache.org/velocity

19.2 - Vantagens
Ogrupojakartaenumeraalgumasvantagensdovelocity,quandocomparadoaojsp:
1.
2.
3.
4.
5.

ajudaaforarumaseparaolimpaentreacamadadevisualizaodascamadasde
controleedemodelo,colaborandotantocomprogramadoresquantocomdesigners
avelocitytemplatelanguage(vtl)tempoucasdiretivasesimplesdeaprendar.
velocitytemplatesnosolimitadosahtml,podendogerarfacilmentecdigoxml, sql,
ascii,postscriptetc.
velocitypermiteacessardadosdeumamaneiraqueowebdesignerentendeoqueest
acontecendoo
ovelocityfazousodecacheparamelhoraraperformancedesuaspginas

19.3 - Templates Velocity


OsarquivosdevisualizaodoVelocitysochamadosdetemplatesecostumamterminar
comaextenso.vm,pormtalextensonoobrigatria!
Vocveraseguirquepodemosconfigurarnoweb.xmlqualaextensoquedesejamos
utilizarparaostemplatesdovelocity.

19.4 - Instalando e configurando o Velocity e Velocity Tools


Passo1:Comeamosento,baixandooarquivobinriodovelocityecolocandooseu.jar
nodiretrioWEBINF/lib.
FaaomesmoparaoprojetoVelocityToolseojardetoolsdentrodele.
Ateno:Vocencontradoisarquivos.jaraodescompactarosarquivosdovelocity.Utilize
aquele que possui a abreviao dep, que significa que possui tambm as dependncias do
mesmo.
Passo 2: Abra o arquivo WEBINF/web.xml e configure a servlet do velocity tools.
ConfiguretambmoservletmappingdoVelocity,aquivocescolheaextensodostemplatesdo
velocity(nadefiniodomapping)
<servlet>
<servletname>velocity</servletname>
<servletclass>
org.apache.velocity.tools.view.servlet.VelocityViewServlet
</servletclass>
<initparam>
<paramname>org.apache.velocity.toolbox</paramname>
<paramvalue>/WEBINF/toolbox.xml</paramvalue>
</initparam>
</servlet>
<servletmapping>
<servletname>velocity</servletname>
<urlpattern>*.vm</urlpattern>
</servletmapping>

Captulo19ApndiceBJakartaVelocityPgina184

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Passo3:Crieoarquivotoolbox.xmldentrododiretrioWEBINF.
<?xmlversion="1.0"?>
<toolbox>
<tool>
<key>text</key>
<scope>request</scope>
<class>org.apache.velocity.tools.struts.MessageTool</class>
</tool>
</toolbox>

Esteltimopassoconfiguraaferramentatextqueirajudaratrabalharcomosarquivos
deinternacionalizaodostruts.

19.5 - Exerccios

ExecuteospassosdaltimaseonoseuprojetodostrutsparaconfiguraroVelocitye
oVelocityTools.Sigaospassosdaseoanterior:
Passo1:Copieos.jarparaoWEBINF/lib
Passo2:Atualizeoweb.xml
Passo3:Crieoarquivotoolbox.xml

19.6 - Seu primeiro template


O cdigo a seguir mostra um template simples. Ele cria uma varivel e mostra uma
mensagemdeoljuntocomovalordavarivel:
<html>
#set($nome="Caelum")
Ola,$nome!
</html>

Ocdigoacimanotemmuitagraa,eleintroduzumcomandodecriaodevarivelde
simplescompreenso:#set($nome=valor),porm,issonotudoqueoVelocitycapazde
fazer.Entovamostrabalharcomidiasmaisinteressantesemumaaplicao.
PodemospedirparaqueaenginedoVelocityprocesseessetemplate.Nessemomento
elavaiprocurarporumarefernciaaumobjetoqueestejaassociadaastringnome.
Essasassociaessofeitasemumobjetoparecidocomummapadascoleesdojava:
ocontexto.Ocontextodovelocitypodeserinstanciadopornsmesmosouentoreceberele
comoparmetro.
RepareasintaxemuitomaissimplesqueadoJSP,facilitandootrabalhododesigner.
Velocity muito usado na web como substituto de JSP, mas ele pode ser usado em
qualqueraplicao,comoporexemplopararenderizarrelatriosougerarcdigojava.
Afiguraaseguirilustraoprocessodemerge/renderizao:

Captulo19ApndiceBJakartaVelocityPgina185

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Ol$nome!

context.put(nome,Caelum);

VelocityEngine
(mergeourender)

OlCaelum!

19.7 - Exerccios
1)Crieumarquivochamadooi.vmecoloqueelenodiretriotarget.Escrevaocdigodo
seuprimeirotemplate.
2)Reinicieoseucontextoeacesseapginaoi.vm.

19.8 - Mesclando velocity e o struts


Existemdiversasferramentas(tools)dovelocitytoolsquefazemaponteentreovelocitye
ostruts.
Por exemplo, voc pode usar a ferramenta definida no toolbox.xml, a text, para ler
mensagensdoseuarquivodemensagensdostruts.
Exemplo de .vm, onde as duas linhas funcionam adquirindo o texto correspondente a
chavetituloedescricao:
<html>
$text.titulo<br/>
$text.get(descricao)
</html>

19.9 - Exerccios
1)Crieumarquivochamadostruts.vmecoloqueelenodiretriotarget.
a)Escrevaocdigodaseoanterior.
b)Adicionetituloedescricaocomochavesnoseuarquivodemensagens
c)Acesseapginastruts.vm

19.10 - Objetos mais complexos


Voc no precisa associar apenas strings no contexto do velocity. Qualquer objetos
associadoseratransformadoemStringsatravsdoseutoString.Almdissovocpodenavegar
emobjetos.Vejamosumaclassesimplesparalivro:
publicclassLivro{

Captulo19ApndiceBJakartaVelocityPgina186

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


privateStringtitulo;
privateStringdescricao;
privateintnumeroDePaginas;

//...gettersesettersaqui
}
Livrolivro=newLivro();
livro.setTitulo(TheHitchhiker'sGuideToTheGalaxy);
categoria.setDescricao(UmclssicodeficodeDouglasAdams);

ParautilizaresseobjetonotemplateVelocity:
Livro:$livro.titulo
Descrio:$livro.descricao

O Velocity emprega uma srie de regras de introspeco para achar as propriedades


desejadas.Umadelasversehumatributopblicocomorespectivonome,ouumgetter
pblico.
Voc tambm pode chamar mtodos pelo template, o que nem sempre muito
aconselhado(emespecialsevocestiverquebrandooMVCeexecutandolgicadenegciosno
seutemplate).Exemplo:
$algumaReferencia.algumMetodo(5)
$algumaReferencia.outroMetodo($variavel)

ReparequevocpodepassarparmetrosparaosmtodoseoVelocitytentaconvertlos
damelhormaneirapossvel.

19.11 - Diretivas
DIRETIVAS
DO VELOCITY

Alm detrabalhar comasrefernciascolocadasno contexto, ovelocity possui alguns


comandos,chamadosdediretivas,paraauxiliarnarenderizaodotemplate.
OVelocitypossuinototalmenosdedezdiretivas,veremosasprincipaisagora.

19.12 - IF
Muitas vezes necessrio realizar um if no template, normalmente para saber se
devemosmostrarounoaquelepedaodetemplate.
#if($livro.numeroDePaginas>42)
Essamensagemsaparecerparalivroscommaisde42pginas
#end

Voctambmpodeencaixarumelse:
#if($livro.numeroDePaginas>42)
Essamensagemsaparecerparalivroscommaisde42pginas
#else
Essamensagemsaparecerparalivrospequenos,commenosde42pginas.
#end

Parasaberseumarefernciaexisteounonocontexto(isto,seelanullouno),
bastavocfazerum#ifusandoarefernciacomoargumento:
#if($livro)
Existeumlivronocontextodovelocity
#else
Captulo19ApndiceBJakartaVelocityPgina187

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web


Noexisteumlivronocontextodovelocity
#end

Sevocquerrealizarumifcomoesseapenaspara sabersedeve ounomostrar a


varivel,ovelocityofereceumrecursointeressante,poissevocfizer:
$user.nome

Se no houver uma referncia associada a user ou ao nome do user, o Velocity


renderizarotrechoacimaemostrarcomoresultadooprprio$user.nome.Paraevitarisso,
bastaadicionarumpontodeexclamaoapsocifro:
$!user.nome
Agoraissopassararenderizarumastringvazia.

19.13 - FOREACH
TendoumaCollection,sejaelaqualfor,vocpodefacilmenteiterarsobreela.
Considereoseguintecontexto:
ArrayListlista=newArrayList();
Livrolivro1=newLivro();
livro1.setTitulo(MemriasPstumasdeBrsCubas);
lista.add(livro1);
Livrolivro2=newLivro();
livro2.setTitulo(OsSertes);
lista.add(livro2);
Livrolivro3=newLivro();
livro3.setTitulo(VidasSecas);
lista.add(livro3);

Numexemplomaisreal,essaCollectionviriadeumDAO,puxadadobancodedados.
Noseutemplate:
#foreach($livroin$lista)
Livronalista:$livro.titulo
#end

Repareasimplicidadedessecdigo:odesigner,queoresponsvelpormanteresse
template,noprecisaterconhecimentodequehclasses,coleesereflectionportrazdisso!
OVelocitypodeiterardemaneiraidnticasobreumaarrayousobreumiterator.Sedentro
doloopvocprecisarsaberemqueiteraovocest,existeavarivel$velocityCountpara
isso.

19.14 - PARSE
Emmuitoscasosdividimosnossapginawebemvriospedaos,comocabealho,corpo
e rodap. Podemos distribuir isso em arquivos diferentes no Velocity, e pedir para que ele
renderizeoutrostemplatesdentrodeumdeterminadotemplate:
#parse(header.vm)

Captulo19ApndiceBJakartaVelocityPgina188

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

aquivaionossocorpo
#parse(footer.vm)

Existeumaoutradiretiva:a#include.Elafazomesmotrabalhoquea#parsepormo
templateinseridonoserinterpretado,isso,nohaveromerge.

19.15 - Comentrios
Parafazerumcomentriodeumalinha:
##essalinhanoserinterpretada

Umcomentriodotipobloco:
#*
Esseumcomentriodotipobloco,nadadissoserinterpretado
*#

19.16 - Outras ferramentas


Aseguirvocencontraadefinioeofuncionomentodeferramentassimplesquepodem
ajudaroseutrabalhocomtemplatesdovelocity.

19.17 - ImportTool
IMPORTTOOL

AImportToolumaferramentausadaparaimportarcdigohtmldeoutrasurls,estejam
elaslocalizadasnoseuservidorouemqualqueroutrolugarqueoservidortenhaacesso.
Definimoselacom:

<tool>
<key>import</key>
<scope>request</scope>
<class>org.apache.velocity.tools.view.tools.ImportTool</class>
</tool>

Eparaimportaraurlhttp://www.caelum.com.brnanossapginabastausar:
$import.read(http://www.caelum.com.br)

Vocpodeimportarurlsquaisquer.Adiferenaentreessatooleo#parsequeaquia
novapgina(seforumtemplatedovelocity)terumcontextodiferentedocontextoatual.
Maisinformaesem:http://jakarta.apache.org/velocity/tools/view/ImportTool.html

19.18 - CookieTool
COOKIETOOL

ACookieToolumaferramentaquefacilitamuitootrabalhocomcookies.
Definimoselacom:

<tool>
<key>cookie</key>
<scope>request</scope>
<class>org.apache.velocity.tools.view.tools.CookieTool</class>
</tool>

Captulo19ApndiceBJakartaVelocityPgina189

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Eusamosnonossotemplatedovelocitydeumamaneirabemsimples:
a)Paraadicionarumcookienovo
Adicionandoumcookie<br/>
$cookie.add(ultimaVisita,28/09/2003);
Cookieadicionado<br/>

b)Parareceberovalordessecookie:
Ovalordocookie:$cookie.ultimaVisita.value<br/>

Maisinformaesem:http://jakarta.apache.org/velocity/tools/view/CookieTool.html

19.19 - Um pouco mais...


1)WebmacroeFreemarkersooutrosprojetosdetemplateenginesmuitoconhecidos.

Captulo19ApndiceBJakartaVelocityPgina190

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

20

Apndice C - Design Patterns

20

Nunca chegamos aos pensamentos. So eles que vm.


MartinHeidegger

Nestecaptulo,vociraprendercomoutilizaroFactoryparacriarumcachedeobjetos.

20.1 - Factory exemplo de cache de objetos


Tomemoscomoexemploaclasseaseguirqueseriaresponsvelporpegarocontedode
umaPaginaWebdainternet:
publicclassPaginaWeb{
privateStringurl;
publicPaginaWeb(Stringurl){
this.url=url;
}
}

Poderamoscolocarumavisonanossaaplicao,avisandotodososprogramadoresde
que eles devem verificar o cache antes de dar um new. No funciona. Com um construtor
acessvel,qualquerumpoderiacriarumnovoobjetosemverificarocacheantes,algoqueno
podemospermitir.
Esedeixarmosoconstrutorprivado?Continuandocomoexemploefaremosocache
dessetipodeobjeto:
1. publicclassPaginaWeb{
2.
3.
privateStringurl;
4.
5.
/**
6.
*Construtorprivado
7.
*/
8.
privatePaginaWeb(Stringurl){
9.
this.url=url;
10.
}
11.
12. }

Noparecefazermuitosentidodeixaroconstrutordeumaclasseprivado.Quempode
acessar algo privado de uma classe? Somente ela mesma. Ento, o seguinte cdigo no
funcionariaforadela:
1.
2.
3.
4.
5.

classPesquisa{
PaginaWebpesquise(Stringurl){
returnnewPaginaWeb(url);
}
}

Captulo20ApndiceCDesignPatternsPgina191

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

PodemosdaracessoaconstruodosobjetosdotipoPaginaWebapartirdeummtodo
dentrodaclasse.Essemtododitariaasregrasdafabricaodenovosobjetos,ouemvezde
fabricarumnovo,devolverumjexistente.
Imagineagoramanterumobjeto dotipo HashMap chamado paginasJaCriadas que
seriaonossocache.Ocdigoaseguirmostracomousloparaevitaracriaodeobjetos
cacheados:
PaginaWebpagina;
if(this.paginasJaCriadas.get(url)!=null){
pagina=this.paginasJaCriadas.get(url);
}else{
pagina=newPaginaWeb(url);
this.paginasJaCriadas.put(url,pagina);
}
returnpagina;

Cachedeque?
Noaconselhadosairporafazendocachedequalquertipodeobjetos.Objetospesadosso
indicadosparaseremcacheadosouentoparaseremtiradosdeumpool.
Objetospesadossoaquelesquenitidamenteconsomemmuitosrecursosdosistemaoperacional
oudaplataforma,comoThreads,conexescombancodedadoseoutros.
Isto,sea PaginaWeb paraestaurljfoicriadaalgumdia,nohanecessidadede
criarumnovoobjeto:podemospeglodeumcache.Senoexiste,iremoscriar,guardare
retornar,paraquepossaserreutilizado.
Emquemtodocolocamosessaimplementao?Seforemummtodoparaoobjeto,s
poderemosacessaressemtodojtendoumobjetoantes,oquenofazsentido.Precisamos
deummtodoestticoparapoderseracessadopelaclasse.Almdisso,nopodemosusarum
atributodeobjetodentrodeummtodoesttico,entoonossomapanopodeseracessado
pelothis,poistratariasedeumatributodeobjeto.Nossomapadeveserumatributoesttico.
1.
2.
3.

publicclassPaginaWeb{
privatestaticMap<String,PaginaWeb>paginasJaCriadas=new
HashMap<String,PaginaWeb>();
privateStringurl;

4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25. }

privatePaginaWeb(Stringurl){
this.url=url;
}

/**
*Fbricadepginasweb.
*Sejexistirumobjetonocache,retornaele.
*/
publicstaticPaginaWebgetPaginaWeb(Stringurl){
//senoexistirnocache
if(PaginaWeb.paginasJaCriadas.get(url)==null){
//colocanocache
PaginaWeb.paginasJaCriadas.put(url,newPaginaWeb(url));
}
//retornadocache
returnPaginaWeb.paginasJaCriadas.get(url);
}

Captulo20ApndiceCDesignPatternsPgina192

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Acabamosdeencapsular comonossosobjetosso fabricados.Quandoalgumquiser


criarumaPaginaWeb:
1.
2.
3.
4.
5.

classPesquisa{
PaginaWebpesquise(Stringurl){
returnPaginaWeb.getPaginaWeb(url);
}
}

Ointeressanteperceberaquique,paraocliente,indiferenteoqueessemtodofez,se
elepegoudocacheouno.Alis,vocpodemudarasregrasdoseucachedanoiteprodia,
seminterferirnobomfuncionamentodaaplicao.
EsseDesignPatterntemonomedeFactory(Fbrica)eexistemdiversasvariaesdo
mesmo.

Memriacheia?
Fazerocachedetodososobjetospodeconsumirmuitamemria.Vocpodeestarusandoumtipo
demapaqueguardaapenasosltimos50objetosinstanciadosouentoosmaisacessados,por
exemplo.

Captulo20ApndiceCDesignPatternsPgina193

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

21

21

Apndice D - Servlets

Do rio que tudo arrasta, diz-se que violento. Mas ningum


chama violentas as margens que o comprimem.
BertoltBrecht

Configuraodeumaservleteescopodeaplicao.

21.1 - Configurao de uma servlet


Jvimosoarquivo web.xmlsendoutilizadoparaconfigurarumaponteentreasURLs
acessadasatravsdeumnavegadoreasservletsaseremutilizadas.
Agorairemosenfrentarumproblemacomumqueirutilizaressearquivocomopartede
suasoluo.Imaginequeprecisamosdeumaconexoaumbancodedadosdentrodenossa
servlet.Podemosescreveraurldobanco,ousurioesenhadentrodanossaservlet,masisso
umapssimasoluo,umavezque,imagineasituaoondesefaznecessrioalterarousurio
easenha.Precisamosalteraranossaservleterecompilla!
Oquefaltaaquiumarquivodeconfiguraoparaanossaservleteoarquivoweb.xml
podeserutilizadoparaisso!
PARMETROS
DE
INICIALIZAO

Ocdigoaseguirdefineumparmetronoarquivo web.xml pararepresentaraurlde


conexodobancodedados.

<!Definicaodeumaservlet>
<servlet>
<servletname>minhaServlet</servletname>
<servletclass>br.com.caelum.servlet.TestaBancoDeDados</servletclass>
<!Parametrodeinicializacao>
<initparam>
<paramname>bancodedados.url</paramname>
<paramvalue>jdbc:mysql://localhost/banco</paramvalue>
</initparam>
</servlet>

O parmetro deve ser lido atravs do mtodo getInitParameter da classe


ServletConfig. Para obter acesso ao servlet config basta chamar o mtodo
getServletConfig.Porexemplo:
Stringurl=getServletConfig().getInitParameter(bancodedados.url);

Arquivosdeconfigurao
Omaiscomummarcarnoweb.xmlumarquivodeconfiguraoparacadapartedaaplicao.

Captulo21ApndiceDServletsPgina194

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Por exemplo, um parmetro indica qual arquivo possui a configurao de logs, outro indica a
configuraodobancodedados.Assimficaaindamaisclaroqualconfiguraoficaaondeeainda
maissimplesparaoresponsvelpeloprocessodedeploydeconfiguraraaplicaopoiseleno
precisaalteraroweb.xml,esimosarquivosdeconfigurao.

21.2 - Exerccios
1)Crieumaservletqueutilizeoparmetrodeinicializaoparaconectarseaobancode
dados
a)CrieaservletTestaBancoDeDados
b)Mapeieaurl/testaparametrosparaaservletTestaBancoDeDados
c) Implemente o mtodo service que leia o argumento bancodedados.url,
bancodedados.usuario,bancodedados.senhaeimprimaparaoclienteessesdados.
d)Testesuaservletatravsdaurlmapeada

21.3 - Aplicao
svezesnobastamanterumobjetonasessopoisnoqueremosumdiferentepara
cadausurioconectadoaosistema.
Por exemplo, interessante manter um DataSource disponvel em toda a nossa
aplicaowebparaquequalquerservlettenhaacessofuncionalidadedeusarconexescomo
bancodedados.
Uma das solues criar uma varivel esttica do tipo DataSource que todas as
servletsiriamutilizar.Oproblemaaquiobrigaratodasasservletsutilizarumaclassefixapara
efetuaralgumprocesso.
ESCOPO DE
APLICAO
SERVLET
CONTEXT

Paraguardarobjetosqueseroutilizadosportodosasservletsutilizamosoescopo de
aplicao,chamadotambmdeservlet context.
Cadaaplicaowebpossuiumnicoservletcontext,etodasasservletspossuemacesso
aele.
Objetosguardadosemtalcontextopodem,porexemplo,serlidoseutilizadosporuma
pgina jsp. Para usar o ServletContext em uma servlet basta chamar o mtodo
getServletContextdamesma.

ServletContextcontext=getServletContext();
DataSourceds=(DataSource)context.getAttribute(datasource);
Connectioncon=ds.getConnection();
//usaaconexoaqui
con.close();
con=null;

Captulo21ApndiceDServletsPgina195

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

21.4 - Descobrindo todos os parmetros do request


ParalertodososparmetrosdorequestbastaacessaromtodogetParameterMapdo
request.
Map<String,Object>parametros=request.getParameterMap();
for(Stringparametro:parametros.keySet()){
//facaalgocomoparametro
}

Captulo21ApndiceDServletsPgina196

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

captulo

22

Apndice E - Design Patterns

22

Nunca chegamos aos pensamentos. So eles que vm.


MartinHeidegger

Nestecaptulo,vociraprendera:
13. solucionaroproblemadecontroledeacessoaoconstrutordeobjetos;
14. criarinstnciasnicasdeobjetosemumprograma;
15. resolveralgunsproblemasclssicosdeorientaoaobjetos.

22.1 - Singleton
SINGLETON

Emalgunscasos,desejamosquedeterminadaclassespossaserinstanciadaumavez.
Isto , s queremos um objeto daquela classe e que a referncia para ao mesmo seja
compartilhadapordiversosoutrosobjetos.
Istomuitocomumquandoaclasserepresentaumaentidadenicanosistema,comoo
presidentedeumaempresa,ogerenciadordelogsdaaplicaoouocontroladordeusurios.
Como faremos? Com certeza aproveitaremos o truque anterior, deixando o construtor
privadoecriandoummtodoestticopararetornarareferncia.Masoquefazerpararetornar
sempreumarefernciaparaamesmainstncia?

publicPresidentegetPresidente(){
returnreferenciaUnica;
}

Quem essa referenciaUnica? Um atributo esttico, como era o nosso mapa de


pginasnocache.
publicclassPresidente{
privatestaticPresidentereferenciaUnica=
newPresidente(Nomedo
Presidente);
privateStringnome;
privatePresidente(Stringnome){
this.nome=nome;
}
publicstaticPresidentegetPresidente(){
returnPresidente.referenciaUnica;
}
}

E,quandoalgumquiserumarefernciaparaopresidente:
Presidentepresidente=Presidente.getPresidente();

EpoderiaatserqueomtodogetPresidentenoretornassesempreumareferncia
paramesmainstncia,dependedoquevocquerquesuaaplicaofaa.Seumdiaquisermos
Captulo22ApndiceEDesignPatternsPgina197

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

deixarquemaisdeum Presidente existananossaaplicao,podemosdeixaroconstrutor


pblicoou,melhorainda,criarummtodode Factory querecebaonomedo Presidente
comoargumento.

Classescomtudoesttico
Umaoutraalternativaseriacriarumaclassecheiademtodoseatributosestticos,taiscomoa
SystemeaMath.Apesardefuncionar,essasoluonoorientadaobjetos.Sevocprecisar
passarumSystemcomoargumento,comopoderiafazerisso?
Umaclassescommtodosestticostemacaractersticadeumapequenabibliotecadefunes.

22.2 - Exerccios
1) Dado o sistema a seguir, aplique o pattern Singleton. A classe Logger usa a
varivel membro ativo para realmente imprimir informaes, enquanto que a classe
AplicacaoonossoprogramaeutilizadoisobjetosdetipoLogger.
publicclassLogger{

/*pordefaultnoimprimeolog*/
privatebooleanativo=false;
publicLogger(){
}
publicbooleanisAtivo(){
returnthis.ativo;
}
publicvoidsetAtivo(booleanb){
this.ativo=b;
}
publicvoidlog(Strings){
if(this.ativo){
System.out.println("LOG::"+s);
}
}
}

AgoraaclasseAplicacao,emoutroarquivo:
publicclassAplicacao{
publicstaticvoidmain(String[]args){
Loggerlog1=newLogger();
log1.setAtivo(true);
log1.log("PRIMEIRAMENSAGEMDELOG");
Loggerlog2=newLogger();
log2.log("SEGUNDAMENSAGEMDELOG");
}
}

Resultadodaaplicaoantesdeaplicaropattern:
PRIMEIRAMENSAGEMDELOG

Aoaplicaropattern,aclasseaplicaodeverutilizaromesmoobjetodotipo Logger
nasduaschamadasaomtodolog,portantooresultadodaaplicaoser:
Captulo22ApndiceEDesignPatternsPgina198

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

PRIMEIRAMENSAGEMDELOG
SEGUNDAMENSAGEMDELOG

Passo1:TorneoconstrutordeLoggerprivado
Passo2:Crieumavriavelestticaloggerparaconterumareferncianicaaoobjetode
Logger;instancieavarivelnadeclarao
Passo3:CrieummtodoestticogetLoggerquedevolvearefernciaparaologger
Passo4:NaclasseAplicacao,substituaonewLogger()pelousodomtodoesttico
getLoggercriadonopasso3.

22.3 - Um pouco mais...


1) Pesquise sobre outros Patterns. Strategy, Facade, Proxy e Decorator so
algunsinteressantes.
2)ComoumDesignPatterndeveseraplicado?Emquemomento?Antes,duranteou
depoisdaimplementao?

Captulo22ApndiceEDesignPatternsPgina199

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web

Termos importantes
Banco de Dados...............................6
Persistncia.....................................6
DriverManager................................7
JavaBeans......................................11
Prepared Statement......................13
Design Patterns.............................15
DAO...............................................16
ResultSet.......................................18
Referncia de implementao.......25
Continer.......................................28
JSP.................................................46
scriptlet..........................................46
el....................................................51
pojo................................................54
JSP:usebean...................................54
JSTL...............................................56
c:out...............................................58
expression language......................58
c:foreach........................................58
c:set...............................................60
c:import.........................................60
@include........................................62
c:url...............................................63
error-page......................................68
Servlet...........................................74
request...........................................74
response........................................74
CGI.................................................74
Http................................................74
HttpServlet....................................74
servlet............................................74
service...........................................75
Init.................................................80
destroy...........................................80
outputstream.................................81
sendredirect...................................81
doget..............................................86
dopost............................................86
SingleThreadModel.......................92
war.................................................94
Servlet.........................................104
context.........................................104

listener.........................................104
escopo de aplicao....................104
servletcontext..............................104
listener.........................................104
Regras de Negcio......................109
Request Dispatcher.....................110
View.............................................122
Controller....................................122
Model...........................................122
MVC.............................................122
Struts...........................................125
MVC.............................................125
MESSAGE RESOURCES..............131
Bean:message..............................132
Action Struts................................135
ActionForm..................................147
Form-bean....................................147
Validao Struts...........................150
ALWAYS LINK TO ACTIONS.......157
COOKIE.......................................163
Sesso..........................................164
Hibernate.....................................167
Hibernate annotations.................167
Hibernate. properties..................169
save..............................................172
criteria.........................................174
firstresult.....................................174
maxresults...................................174
lazy..............................................174
customization over configuration......
180
injecao de dependencias..............180
inversao de controle....................180
Velocity........................................185
Templates....................................185
Diretivas do Velocity....................189
ImportTool...................................191
CookieTool...................................191
Parmetros de Inicializao........198
Escopo de Aplicao....................199
Servlet Context............................199
Singleton......................................202

Captulo22ApndiceEDesignPatternsPgina200

Você também pode gostar