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.Seusprofissionaispublicaramj diversos 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. Em2006aempresafocaseusprojetosemtrsgrandes reas:sistemasdegerenciamento decontedoparaportais,desenvolvimentodesoluesdeintegraofinanceiraetreinamentocom intuitodeformao.

Sobre a apostila
Esta aapostiladaCaelumquetemcomointuitoensinarJavadeumamaneiraelegante, mostrandoapenasoque necessrionomomentocorretoepoupandooleitordeassuntosque nocostumamserdeseuinteresseemdeterminadasfasesdoaprendizado. ACaelumesperaquevocaproveiteessematerial,equeelepossaserdegrandevaliapara autodidataseestudantes.Todososcomentrios,crticasesugestesseromuitobemvindos. Omaterialaquicontidopodeserpublicamentedistribudodesdequenosejaalteradoe seuscrditossejammantidos.Elenopodeserusadoparaministrarqualquercurso,pormpode serrefernciaematerialdeapoio.Casovoc estejainteressadoemuslofinscomerciais,entre emcontatocomaempresa. Ateno: Voc pode verificar a data de ltima atualizao da apostila no fim do ndice. Nuncaimprimaaapostilaquevoc receberdeumamigooupegarporemail,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 oestudantenoconseguedistinguirexatamenteoque importanteaprenderereternaquele 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 j existemdiversosprojetosdotipo 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


OsistemadesenvolvidoemJavaabstraiomtodoatravsdoqual possvelfazeruma conexopoisasconexessofeitasatravsdeuma Cliente ponte queimplementa todas as funcionalidades que umbancodedadospadrodevenosfornecer. Por exemplo, toda conexo deve permitir executarcdigodeatualizao,pesquisa,etc. Essa implementao precisa ser escolhida. Essa escolha no feita programaticamente e sim bastausarumaponte. Veja no esquema ao lado a ponte (implementao)entreoprograma(cliente)eobanco dedados.
DRIVERMANAG ER

InterfaceJDBC ImplementaoJDBC.Qual?

BD

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. Atravsdele, possvelchamarummtodo getConnection comumaurlqueindica qualobancoquedesejoabrir. O padro da url para o driver do mysqlqueiremosutilizar: 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. DriverManager.getConnection("jdbc:mysql://localhost/teste"); Cliente

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

AvisandooDriverManagersobre aexistnciadeumDriverparaoMySQL

SQLServer Oracle

DriverManager

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. Pormno tudotosimplesassim,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();

PodemosperceberqueomtodoabreConexao umafbricadeconexes,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 facilmenteumavezqueamaiorconfusofeitaa fora entre 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,voc v umexemplodeumaclassejavabeanqueseriaequivalenteaonosso 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 Sevoc quersabermaissobreEnterpriseJavaBeans(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 queest escrito.Oqueocdigoacimafaz?Lendorapidamenteficadifcil.Maisdifcilainda sabersefaltouumavrgula,umfechaparntesestalvez? Outroproblema oclssicopreconceitocontraJoanad'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
No comumutilizarjdbchojeemdia.Omaispraticado ousodealgumaapideORMcomoo 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. Masalgumascoisasnopodemossimplesmenteresolvercomorientao objetospois noexistepalavrachaveparaumafuncionalidadetoespecfica. 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.

DESIGN PATTERNS

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

2.14 - DAO Data Access Object


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

Mas...Java orientadoaStrings?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(); } } }

Ocdigoanteriorj mostraopoderqueiremosalcanar:atravsdeuma nicaclasse seremoscapazesdeacessarobancodedadose,maisainda,somenteatravsdessaclasse serpossvelacessarosdados.


DAO

Estaidia,inocenteaprimeiravista,capazdeisolartodooacessoabancoemclasses bem simples, cuja instncia um objeto responsvel por acessar os dados. Da responsabilidadedesteobjetosurgiuonomedeDataAccessObjectousimplesmenteDAO,um dosmaisfamosospadresdedesenvolvimento. Oquefaltaparaocdigoacimafuncionar umaclassechamadaContatoDAOcomum 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

Oobjetoretornado dotipoResultSetquepermitenavegarporseusregistrosatravs 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


Agoraquevoc jsabeusaroPreparedStatementparaexecutarqualquertipodecdigo 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?Aidia quevoc possacriarumaaplicaoqueutilizeesses servios.Comoessesserviossobemcomplicados,voc noperder tempoimplementando 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,voc temessaliberdade,no est preso a umcdigo ea especificaogarantequesuaaplicaofuncionarcomaimplementaodeoutraempresa.

Ondeencontrarasespecificaes.
OgruporesponsvelporgerirasespecificaesusaositedoJavaCommunityProcess: http://www.jcp.org/ L voc podeencontrartudosobreas 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? Nessedownloadvoc ter adocumentao,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. OutrautilidadedaRI paraqueasempresasquedesejamvenderseuprprioproduto, 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. 3. 4. 5. 6. 7. 8. Apache,ApacheGeronimo,gratuito BEA,BEAWeblogicServer IBM,IBMWebsphereApplicationServer Jboss,JbossApplicationServer,gratuito Objectweb,ObjectwebJonas,gratuito Oracle,OracleApplicationServer Sun,SunJavaSystemApplicationServerPlatform

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

Captulo3OqueoJEE?Pgina25

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

captulo

Servlet Continer
ClariceLispector

Que ningum se engane: s se consegue a simplicidade atravs de muito trabalho.

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 possvelgerarcontedoquepermiteaousurioacesso diversasfuncionalidadesatravsde pginasHTML,comoquandovocdesejacomprarprodutosemumalojavirtual. Paramelhorarodesempenhodo ltimo,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(Fran oisMarieArouet)

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. InfelizmenteaversodoFirefoxnoLinuxqueusamosno compatvelcomoplugindo 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 siteoficialdoplugin o http://amateras.sourceforge.jp/ eiremos utilizaropluginchamado EclipseHtmlEditor. UmprrequisitoparaoEclipseHtmlEditor oGEFdoprprioprojetoEclipse.Olink o 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


Plato

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

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.Isto se 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)evmjuntocom todososservletcontinerouservidordeaplicao. Essesjarspermitemquevoc utilizeaapideservletsejsp.Sevoc noutilizasseoplugindo 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.xmlseropcionaleleser extremamenteimportantemaisparaa 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)Sevoc possusseumarquivochamado 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. Basicamenteocdigoutilizar oContatoDAOquecriamosanteriormenteparaimprimira 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=%>paraimportaraquiloqueser usadono 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,quandooresponsvelpelodesigngrficodapginaquiseralteraralgoter que conhecerJavaparaentenderoqueestescritoldentro...hmm...nopareceumaboasoluo. UmaidiaboaoMVC,queservistomaisadiantenestecurso.

7.7 - EL: Expression language


EL

PararemoverumpoucodocdigojavaqueficanapginajspaSundesenvolveuuma linguagemchamadaExpressionLanguagequeinterpretadapeloservletcontiner. Nossoprimeiroexemplocomessalinguagem utilizlaparamostrarparmetrosqueo 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

Comoj foicomentadoanteriormente,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. Oresultadofinal umconjuntodetags(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/setterdopojo to 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,quandoele transformadoem umaservlet,queseucdigojava compiladoenecessitamosdasclassesdodriverqueso 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.J auri(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,esse o 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?Aindano toelegantequantoqueramos,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}"/> Comovoc podeperceber muitosimplesaprenderautilizarumataglib,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. Quandosurgiranecessidadedousodeumadessastagsvoc ter eladisponvelem 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

Umaperguntaquesempreaparecenavidadosprogramadores adecomoexecutaro cdigodeoutro arquivojspdentrodeumprimeiroarquivojsp,isto ,voc quercolocarum 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, essaincluso extremamenterpida,pormvalelembrarqueoarquivo ncluidopodeouno 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

Asvezesno simplestrabalharcomlinkspoistemosquepensarnaurlqueocliente 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 j criou,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
RenDescartes

Divide as dificuldades que tenhas de examinar em tantas partes quantas for possvel, para uma melhor soluo.

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> Bastaolharocdigoacimaparaperceberqueno omelhorcaminho.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. 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 1

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 que umapginadecontroledeerro,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.Esse ummapeamentosimples,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>

Agoraquej configuramos,quandoocorrerumaSQLException,apginaerro.jspser mostradasenadaforfeitopeloprogramador: noprecisamosfazerNADAnapginajspque podegerarumerro.Simplesno? Quem trata o erro oservlet conteiner, que l o 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? Acontecequequandovoc inicouotomcat,elepercebeuqueseuxml invlidoeno inicializouseucontexto.Este umbommomentoparavoc pegaraprticade,sempreque reinicializaroseutomcat,verificarseaparecealgumaexceptionnoconsoledomesmoe,se aparecer,lla. Maisimportanteainda aprenderalerexceptionssemaajudadeterceiros.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

Mesmodepoisquevoc mapeousuaspginasdeerroparecequeoweb.xmlno existe,nohouveredirecionamentonenhum? 1)Reinicieotomcat

Captulo9ControledeerroPgina70

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

captulo

10

10

Servlets
KonradAdenauer

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

Nestecaptulovociraprenderacriarpequenosobjetosquefuncionamcomoaplicaesweb.

10.1 - Servlet
SERVLET

Umaservletfuncionacomoumpequenoservidor(servidorzinhoemingls)querecebe chamadasdediversosclientes. Umaprimeiraidiadaservletseriaquecadaumadelas responsvelporumapgina, sendoqueelal dadosdarequisiodoclienteerespondecomoutrosdados(html,gifetc). ComonoJavatentamossemprequepossveltrabalharorientadoaobjetos,nadamaisnatural queumaservletsejarepresentadacomoumobjeto.

REQUEST RESPONSE CGI

Resumindo,cadaservletumobjetojavaquerecebetaisrequisies( request)eretorna algo(response),comoporexemploumapginahtmlouumaimagemdoformatojpeg. Diversas requisies podem ser feitas umamesmaservletaomesmo 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.

ClienteIE ServidorWeb Servlet Continer

HTTP

Cliente Firefox

Cliente Opera

recebe requisiesvia http

HTTPSERVLET

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.

SERVLET

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,at queir desativlaatravsdomtodo destroy,paraentoliberaro objeto.
INIT

Nainicializaodeumaservlet,quandoparmetrospodemserlidosevariveis comunsatodasasrequisi esdevemserinicializadas.Porexemplo,conex esaobanco dedadossoestabelecidasnessemomento:


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 pr prio 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.Osegundotipodemapping o 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,podemosusara OutputStreamouoPrintWriterque 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.

cliente 1.GET

Internethttp ServletContiner

2.Formemensagens Servlet Novamensagem 4.Formemensagens tempo

3.POST

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 voc podeescreveromesmocdigodorequest.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. Aimplementaodenenhumdosmtodosabaixo obrigatriaseasuaservletextender 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 doGet doPost doPut doDelete

init

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,aespecificaodaservletgaranteques existir umainstnciadessaservletpormquina,portantosomenteumainstncianototalanoserque vocrodesuaaplicaoemumcluster. Baseadonessefatovamoscriar umavarivelmembrochamadacontadorparafixara idiadequesomenteumainstnciadessaservletexistir namemriaequeelasobrevivea 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,ainterface SingleThreadModelfoidepreciada,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!


Foipossvelinferirdosexemplosanterioresque complicadoescreverhtmldentrode umaservletotempotodo. Vejas comofoidifcillerumparmetrodentrodeumaservleteretornarohtmlparao 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,logoqueoarquivoJSP chamadopelaprimeiravezporumcliente,umaservletqueo representacriada,aplicandotodososbenefciosdamesmaparaumapginaJSP.

Internethttp cliente 1.Primeiravez Jsp Compiler Cria umaservlet ServletContiner

3.Segundavez

tempo

servlet

Vantagens
Obenefciomaisclaro nocolocarumasrieimensadecdigohtmldentrodeumaclasseem 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)deumaaplicaoweb odecriarum 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 servicefoidefinidonaclasseHttpServleteportantos podemosjogarasexceptionsquetal 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


Portantocomservletsahistriaj outra.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,oservletcontinerprocurar omapeamentode 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


KonradAdenauer

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

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

Aapideservletsdisponibilizaumainterfacechamada ServletContextListenercapazde 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.


ServletContextcontext=event.getServletContext();

SERVLETCONTE XT

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

Comoj vimosanteriormente, ocdigodotiposcriptletpodesermalficoparanossa aplicao,sendoassimvamosutilizarexpressionlanguageparaacessarumatributodoescopo aplicao:


AcessandocomEL:${inicializacao}<br/>

Repare que a expression language ir procurar tal atributo no s no escopo do application,comoveremosmaisafrente.Paradeixarclaroquevoc procura 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

12

Model View Controller


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

Oidealento queaServletfaaotrabalhosujoe rduo,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>

Aferramentaquebuscamos umredirecionadorderequisies,capazdeenviaruma requisioparaumnovorecursodoservidor:umjsp,umaservlet,umaimagemetc.


REQUEST DISPATCHER

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

Cliente

servlet servlet

JSP

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

Apesardosdoismtodosparecerem teiselesnocostumamserusadosanosernapartede 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. Reparequeocdigoacima umswitch!EswitchemJava toruimquesubstitumos porpolimorfismo,comoveremosaseguir. Vamostentargeneralizarento,queremosexecutaroseguintecdigo:


Stringbusiness=request.getParameter(business); newbusiness().execute(request,response);

Entretantonopodemos,poisbusiness onomedeumavarivel.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

JSP

BD

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

Captulo12ModelViewControllerPgina110

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

captulo

13

13

Construindo um Framework MVC


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,maspercebaquenotem nadacomuma 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


Nossoobjetivoqueonomedaclassequeimplementaainterface BusinessLogicseja 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)Fa aumarquivojspchamadomvcok.jsp
<html> <h1>MVCOK</h1> </html>

3) Crie uma implementao de l gica 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.Quem responsvelporapresentarosresultadosnapginaweb chamadode Apresentao(View). Aservlet(eauxiliares)quefazosdispatchsparaquemdeveexecutardeterminadatarefa chamadadeControladora(Controller). Asclassesquerepresentamsuasentidades,easqueteajudamaarmazenarebuscaros dados,sochamadasdeModelo(Model) 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.O HibernatepodeserusadocomoModel,por exemplo.EcomoViewvoc noprecisausars JSP,podeusaraferramentaVelocity,por exemplo.

CONTROLLER

MODEL

MVC

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


Aseguirvoc encontraumalistacomdiversasopesparaacamadadecontroleeum poucosobrecadaumadelas: 1.StrutsActionocontroladormaisfamosodomercadoJava, utilizadoprincipalmente porseromaisdivulgadoecomtutoriaismaisacessveis.Possuevantagenscaractersticasdo mvcedesvantagensquenapocaaindanoerampercebidas.ocontroladorpedidonamaior partedasvagasemJavahojeemdia. umprojetoquenoter grandesatualizaespoisa 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


Aseguirvoc encontraumalistacomdiversasopesparaacamadadevisualizaoe
Captulo13ConstruindoumFrameworkMVCPgina118

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

umpoucosobrecadaumadelas: 1.JSP:comoj vimosoJavaServerPages,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:no umaaltenativaparaasferramentasanterioresmassimumamaneira de criar templates para seu site, com uma idia muito parecida com o struts tiles, porm genrica:funcionainclusivecomoutraslinguagenscomophpetc. Empequenasequipes importanteumaconversaparamostrarexemplosdecadauma 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

Struts umframeworkdogrupoJakartaqueservecomoocontroller de uma arquitetura MVC.ApesardetersuporteparaqualquertipodeServlets, focadonouso deHttpServlets. Naverso1.2,oStrutssuportanosJSP,pormsuaintegraocomframeworkscomo oVelocityrequerplugins(comooVelocityToolsporexemplo). Suadocumentaoe.jarpodemserencontradosem: http://struts.apache.org Paraleressecaptulo, importantequevoc jtenhalidoocaptulosobreModelView 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 seusistemanoest configuradoparaquelisteosarquivosdosdiretrios.Senoseucasofoi porquenoest configuradoalistagem umbomsinal,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


MESSAGE RESOURCES

Ostrutspossuiumsistemabemsimplesdeinternacionalizao. 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.Ser semprenecessriofazerissoaoalterarseuarquivostruts 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:essearquivoir mapearasurlsqueosusurios 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
Asvezes interessantecriarumapelidoparaumapginajsp.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(ques tilduranteodesenvolvimentodasuaaplicao) 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.Sevoc colocarsomenteexemplo.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,esse oexemploquevimosnocomeodaapostila?At aqui, semnovidades.Aquestoquefica comoenviarocontedoreferenciadopelavarivellista paraapginajspqueseracessadaembreve. Precisamos de um escopo de varivel que sobreviva ao mtodo execute e continue duranteoforwarddarequisioatoarquivojsp.Reparequeafraseanteriorentregaasoluo: oescopodarequisio. Iremosatrelaro valorreferenciadopelavarivellistaparaumnomequalquerligadaa requisiodocliente.Essevalors ficar latotrminodarequisio,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,aJSTL atentativadepadronizaressastaglibsque 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>

Nessemomentovoc sepergunta:masojspnodeclarouavarivelcontatos?!Sim,ele nodeclarou.Aexpressionlanguageir buscarovalordetalchavenorequest(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 issos trar problemasparaodesigner,quenosabetantodelgicaquantovoc epodeser 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,j estamosprontosparacriaralgicadenegcioseacamadadevisualizao 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,isso um Contato!Resultado:

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

Ateno:oformulriohtmldever teroscamposcomomesmonomequeasvariveis 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+ESPAOed enter: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 est sendofeito dentrodasuaclasse Action, afinalnenhumActionForm umContatoForm. 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; }

Omtododevalidaodoformulrio omtodovalidate.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,bastareescreveromtodoemseuformulriopoisomesmoser chamado 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.Ser quevaleapena?Ser queasduasaestem 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)OStrutsTilesajudavoc acomponentizarospedaosdassuaspginas.Dando nomeparaosdiversoscomponentescomunsaspginas,voc podeinclulosdinamicamente emqualquerjsp. 2)OStrutsValidatorpodeserconfiguradoparaqueosformbeanssejamverificados antesdesuasaesseremexecutadas.Ele ,delonge,opluginmaisfamosoepoderosodo Struts. 3)OprojetoVelocityToolsfazaponteentreoVelocityeoStruts,entreoutrascoisas.

AlwaysLinkToActions
ALWAYS LINK TO ACTIONS

UmdospatternsmaissimplesefamososqueoStrutsconstruiu oAlwaysLinkToActions.Voc sempredevesereferenciarasaesdoStrutsenuncaassuaspginasjspdiretamente.Sevoc j escondesuaspginasjspnodiretrioWEBINF,est seobrigandoautilizartalprocedimento. 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

15

Jakarta Struts
Conf cio

Verifica se o que prometes justo e possvel, pois promessa dvida.

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.J iremosutilizar 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?J vimosqueisso muitochatoeexisteuma 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, aquelequeir receberosdadosdo 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. Sevoc achatrabalhosoeditarostrutsconfig.xml,voc podeutilizarferramentascomooStruts Consoleparaalterarparaumaediogrficadomesmo.

15.7 - ok.jsp e erro.jsp


Agoravamosescreverasduaspginasmaissimples.Ambasficamnodiretrio webeno 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;dever aparecera 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 est sendofeitodentrodasuaclasse 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
Oprotocolohttputilizadoat agoraparaoacesso pginas limitadopornomanter detalhescomoquemquementreumaconexoeoutra,portantofoiinventadoumsistemapara
Captulo15JakartaStrutsPgina159

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

facilitaravidadosprogramadores.
COOKIE

Umcookie normalmenteumpardestringsguardadonocliente,assimcomoummapa destrings.Essepardestringspossuidiversaslimitaesquevariamdeacordocomocliente utilizado,oquetornaatcnicadeutilizlosalgodoqualnosedevaconfiarmuito.Jqueas informaes do cookie so armazenadas no cliente, o mesmo pode alterla de alguma maneira...sendoinvivel,porexemplo,guardaronomedousuriologado... Quandoumcookie salvonocliente,ele enviadodevoltaaoservidortodavezqueo 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,elenoest disponvelparaaleitura 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 existeeest l paraouso.Seoscookiesestiveremdesabilitados,aseonoirfuncionare
Captulo15JakartaStrutsPgina160

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

devemosrecorrerparaumatcnica(trabalhosa)chamadaurl-rewriting. Asessonadamaisqueumtempoqueousuriopermaneceativonosistema.Acada pginavisitada,otempodesesso zerado.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 umaseono obrigatoriamenteamesmaemdiferentesinstnciasdomesmonavegadorno mesmoclienteacessandoamesmaaplicaoweb,oservidornocontrolaocliente!Voc no 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
BarondeMontesquieu

uma experincia eterna de que todos os homens com poder so tentados a abusar.

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 bancodedadosenquantooprogramaest rodando,permitindomudarsuabasesemalterar nadanoseucdigoJava. Almdisso,elepermitecriarsuastabelasdobancodedadosdeumjeitobemsimples, nosefazendonecessriotodoumdesigndetabelasantesdedesenvolverseuprojetoque podesermuitobemutilizadoemprojetospequenos. J projetosgrandesondeoplanodeaopadrotomadopeloHibernatenosatisfazas necessidadesdaempresa(comoousodeselect*,joinsetc),elepossuidezenasdeotimizaes quepodemserfeitasparaatingirtalobjetivo.

16.2 - Criando seu projeto


Para criar seu projeto, necessrio baixar os arquivos .jar necessrios para rodar o Hibernateecoloclosnoclasspathdomesmo. Ositeoficialdohibernate owww.hibernate.orgelvoc podebaixara ltimaverso 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(at averso2dohibernate)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 arquivodemesmonomequeestnodiretriosrcdescompactadoquevoc baixou(odiretrio dohibernate)nodiretriosrcdesuaaplicao. Porpadroaconfiguraoest detalmaneiraqueohibernateir usarumbancode 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);

SissonosuficienteparaqueoHibernateestejaconfiguradocomaclasse Produto. OHibernaterequerquedescrevamoscomoaclasseserelacionacomastabelasnobancode dadosefizemosissoatravsdasanotaesdoHibernate. Essaconfiguraopoderiaserfeitaatravsdeumarquivoxmlchamadohibernate.cfg.xml.

16.9 - Criando as tabelas


Vamos criar um programa que gera as tabelas do banco. Dada uma configurao, a classeSchemaExport capazdegerarocdigoDDLdecriaodetabelasemdeterminado 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
Agoraj podemospegarumafbricadesessesdotipo 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 classe carregadapeloClass Loaderes nestemomento;elenoser executadooutras 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


SAVE

AtravsdeumobjetodotipoSession possvelgravarnovosobjetosdotipoProduto nobanco.Paratantobastacriaroobjetoedepoisutilizaromtodosave.


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. claroqueparafazerofinetuningdoHibernate interessanteconhecermuitomaisa 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,ovRaptor umexemplodecontroladorsimplesebomparainiciantes.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

18

Apndice A - VRaptor
MicheldeMontaigne

Aquele que castiga quando est irritado, no corrige, vinga-se

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! No o 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,Inje odeDependncias(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
Tudooquefaremosnestecaptuloest baseadonoframeworkconhecidocomovraptor (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, no omaisadotadopelomesmo.Atendncia deutilizaroJSPpoistodomundoconhece JSP. Positivo: Sendo assim, voc que j est apto a mostrar sua prpria opinio sobre os frameworksutilizadosnasuaempresaeaquinocurso,podeargumentarqueoJSPno uma 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. Umaregrabsica sempretiraralgicadeprogramaodasuapginaoutemplatee
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! Voc ver aseguirquepodemosconfigurarnoweb.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>

Este ltimopassoconfiguraaferramentatextqueir ajudaratrabalharcomosarquivos 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,issono tudoqueoVelocity capazde 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.Umadelas verseh umatributopblicocomorespectivonome,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 ,seela nullouno), bastavocfazerum#ifusandoarefernciacomoargumento:


#if($livro) Existeumlivronocontextodovelocity #else Captulo19ApndiceBJakartaVelocityPgina187

Caelumhttp://www.caelum.com.brJava para desenvolvimento Web Noexisteumlivronocontextodovelocity #end

Sevoc querrealizarumifcomoesseapenaspara sabersedeve ounomostrar a varivel,ovelocityofereceumrecursointeressante,poissevocfizer:


$user.nome

Se no houver uma referncia associada a user ou ao nome do user, o Velocity renderizar otrechoacimaemostrar comoresultadooprprio$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,que oresponsvelpormanteresse template,noprecisaterconhecimentodequehclasses,coleesereflectionportrazdisso! OVelocitypodeiterardemaneiraidnticasobreumaarrayousobreumiterator.Sedentro doloopvoc precisarsaberemqueiteraovoc est,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)

Voc podeimportarurlsquaisquer.Adiferenaentreessatooleo#parse queaquia 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

20

Apndice C - Design Patterns


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

Podemosdaracessoaconstruodosobjetosdotipo PaginaWebapartirdeummtodo 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?
No aconselhadosairpora fazendocachedequalquertipodeobjetos.Objetospesadosso indicadosparaseremcacheadosouentoparaseremtiradosdeumpool. Objetospesadossoaquelesquenitidamenteconsomemmuitosrecursosdosistemaoperacional oudaplataforma,comoThreads,conexescombancodedadoseoutros. Isto ,sea PaginaWeb paraestaurlj foicriadaalgumdia,noh anecessidadede criarumnovoobjeto:podemospeglodeumcache.Senoexiste,iremoscriar,guardare retornar,paraquepossaserreutilizado. Emquemtodocolocamosessaimplementao?Seforemummtodoparaoobjeto,s poderemosacessaressemtodoj tendoumobjetoantes,oquenofazsentido.Precisamos deummtodoestticoparapoderseracessadopelaclasse.Almdisso,nopodemosusarum atributodeobjetodentrodeummtodoesttico,entoonossomapanopodeseracessado pelothis,poistratariasedeumatributodeobjeto.Nossomapadeveserumatributoesttico.
1. 2. 3. publicclassPaginaWeb{ privatestaticMap<String,PaginaWeb>paginasJaCriadas=new HashMap<String,PaginaWeb>(); privateStringurl; privatePaginaWeb(Stringurl){ this.url=url; }

4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. }

/** *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,voc podemudarasregrasdoseucachedanoiteprodia, seminterferirnobomfuncionamentodaaplicao. EsseDesignPatterntemonomedeFactory(Fbrica)eexistemdiversasvariaesdo mesmo.

Memriacheia?
Fazerocachedetodososobjetospodeconsumirmuitamemria.Vocpodeestarusandoumtipo demapaqueguardaapenasos ltimos50objetosinstanciadosouentoosmaisacessados,por exemplo.

Captulo20ApndiceCDesignPatternsPgina193

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

captulo

21

21

Apndice D - Servlets
BertoltBrecht

Do rio que tudo arrasta, diz-se que violento. Mas ningum chama violentas as margens que o comprimem.

Configuraodeumaservleteescopodeaplicao.

21.1 - Configurao de uma servlet


J vimosoarquivo web.xmlsendoutilizadoparaconfigurarumaponteentreasURLs acessadasatravsdeumnavegadoreasservletsaseremutilizadas. Agorairemosenfrentarumproblemacomumqueir utilizaressearquivocomopartede 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

Paraguardarobjetosqueseroutilizadosportodosasservletsutilizamoso escopo 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

22

Apndice E - Design Patterns


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. Isto muitocomumquandoaclasserepresentaumaentidade nicanosistema,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,aclasseaplicaodever utilizaromesmoobjetodotipo Logger nasduaschamadasaomtodolog,portantooresultadodaaplicaoser:


Captulo22ApndiceEDesignPatternsPgina198

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

PRIMEIRAMENSAGEMDELOG SEGUNDAMENSAGEMDELOG

Passo1:TorneoconstrutordeLoggerprivado Passo2:Crieumavriavelestticaloggerparaconterumareferncia nicaaoobjetode 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