Escolar Documentos
Profissional Documentos
Cultura Documentos
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
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
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
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
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
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
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
captulo
Comoomaterialestorganizadoedicasdecomoestudaremcasa.
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/
Captulo1ComoaprenderJavaPgina1
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.
Captulo1ComoaprenderJavaPgina2
Diversos screenshots, remodelamentos e melhorias nos textos foram realizados por GuilhermeMoreiraeJacquelineRodrigues. Agrecimentosatodasaspessoasquecostumamenviarerros,bugsesugestesparaa equipe.
Captulo1ComoaprenderJavaPgina3
captulo
JDBC java.sql
O medo o pai da moralidade
FriedrichWilhelmNietzsche
Captulo2JDBCjava.sqlPgina4
Captulo2JDBCjava.sqlPgina5
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
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
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
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.
//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();
2.8 - Exerccios
Captulo2JDBCjava.sqlPgina9
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();
Path. c) Rode novamente sua aplicao TestaConexao agora que colocamos o driver no classpath.
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:
Captulo2JDBCjava.sqlPgina11
//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; } }
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
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
PreparedStatementstmt=con.prepareStatement("insertintocontatos (nome,email,endereco)values(?,?,?)");
Porfim,umachamadaexecuteexecutaocomandoSQL.
stmt.execute();
Agora imaginetodo esse processo sendo escrito todavezque desejar inserir algono
Captulo2JDBCjava.sqlPgina13
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);
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
DESIGN PATTERNS
Abblia
OlivromaisconhecidodeDesignPatternsfoiescritoem1995etemtrechosdecdigoemC++e Smalltalk.Masoquerealmenteimportasoosconceitoseosdiagramasquefazemdesselivro independentedequalquerlinguagem.Almdetudo,olivrodeleituraagradvel. DesignPatterns,ErichGammaetal.
Captulo2JDBCjava.sqlPgina15
//mtodomuitomaiselegante bd.adiciona(contato);
Tentaremoschegaraocdigoanterior:seriamuitomelhoremaiselegantepoderchamar umnicomtodoresponsvelpelaincluso,certo?
packagebr.com.caelum.jdbc;
//importsaqui
publicclassTestaInsere{ publicstaticvoidmain(String[]args){ try{
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
//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{
//mtodoelegante dao.adiciona(contato);
System.out.println("Gravado!"); } }
2.17 - Pesquisando
Para pesquisar tambm utilizamos a interface PreparedStatement, de forma que o mtodoexecuteQueryretornatodososcontatosnoexemploaseguir.
RESULTSET
Pararetornarovalordeumacolunanobancodedadosbastachamarumdosmtodos getdoResultSet,dentreosquais,omaiscomum:getString.
//pegaaconexoeoStatement Connectioncon=ConnectionFactory.getConnection(); PreparedStatementstmt=con.prepareStatement("select*fromcontatos");
Captulo2JDBCjava.sqlPgina18
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()){
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
//adicionandooobjetolista contatos.add(contato);
} rs.close(); stmt.close(); returncontatos; }
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.
Captulo2JDBCjava.sqlPgina20
3)UseaclassedeDAOparaprocurareremovercontatosdobancodedados.
2.21 - Desafios
1)Faaconexesparaoutrostiposdebancodedadosdisponveis.
6. }
2)AdicioneomtodopararemovercontatonoseuContatoDAO.
publicvoidremove(Contatocontato)throwsSQLException{ PreparedStatementstmt=connection.prepareStatement("deletefromcontatos whereid=?"); stmt.setLong(1,contato.getId()); stmt.execute(); stmt.close();
}
Captulo2JDBCjava.sqlPgina21
Captulo2JDBCjava.sqlPgina22
captulo
O que o JEE?
Ensinar aprender duas vezes.
JosephJoubert
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
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).
BaixandoaJavaEE
http://java.sun.com/javaee Altimaversoa5.Cuidadoaofazerodownloadpoisexisteumaversoquetambmvemtodo
Captulo3OqueoJEE?Pgina24
oJavaStandardEdition.
3.5 - Apache?
OgrupoApachepossuiumservidorweb,umservletcontinereumservidordeaplicao, cuidadoparanochamartudodeApacheenosaberdequalestfalando. OservidorwebsechamaApacheHttpd,oservletcontinersechamaApacheTomcateo servidordeaplicaoApacheGeronimo.
Captulo3OqueoJEE?Pgina25
captulo
Servlet Continer
ClariceLispector
Oqueecomofuncionaumservletcontiner.
4.1 - Introduo
Nocomeo,aInterneteraumadziadepginasestticascontendositesdepesquisade diversasacademias. Danecessidadedegerarcontedodinmicocomoosprimeiroscontadores,umaidia bem simples hoje em dia, surgiram os primeiros programas de CGI (Common Gateway Interface). AtravsdelinguagenscomoC,C++,Perl,ASP,PHP, Cobol,Delphi,Shelletc,foi 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.
Ocontinerocomponenteresponsvelpordarsuporteparaasapisdeservletejsp.
Os3tiposmaiscomumdeinstalaodeservletcontinersewebserverssomostrados nogrfico.
Clientes
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.
Captulo4ServletContinerPgina27
5)Escolhaasuapastaprincipal:HomeeselecioneExtract.
6)Oresultadoumapastachamadaapachetomcat:otomcatjestinstalado.
Captulo4ServletContinerPgina28
Captulo4ServletContinerPgina29
captulo
Captulo5OeclipseeseuspluginsPgina30
EscolhaaopoDisablePreview. InfelizmenteaversodoFirefoxnoLinuxqueusamosno compatvelcomoplugindo grupoAmateraseportantonopermitequevisualizemososjsp'samedidaqueescrevemosele. Sendo assim, tanto no windows quanto em verses anteriores do Firefox no Linux, o plugincapazdemostrarumpreviewdojsp.
Captulo5OeclipseeseuspluginsPgina31
3)Apliqueasalteraes.
4)Cliquenobotodotomcatqueestnabarradeferramentas.
5)Abraoseubrowseretenteacessar:http://localhost:8080
Captulo5OeclipseeseuspluginsPgina32
Captulo5OeclipseeseuspluginsPgina34
captulo
Captulo6NovoprojetowebPgina35
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
Nossoprojetopossuiaseguinteestrutura:
Lembresequeoeclipsenomostraodiretriodesadadassuasclassesportantoo diretrioclasses,apesardeexistir,noaparecenoPackageExplorer.
Captulo6NovoprojetowebPgina37
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
Caso seu resultado final no mostre os arquivos jar do tomcat siga as seguintes instrues: 8)Cliquedadireitanoprojeto 9)EscolhaTomcat,addTomcatlibtoprojectbuildpath
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.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>
Captulo6NovoprojetowebPgina40
3)AssimcomonaconfiguraodoplugindoTomcat,escolhaodiretrio/webcomobase doseuprojetoweb.
<Contextpath="/jspteste"docBase="/home/usuario/workspace/jspteste/web/" reloadable="true"/>
Captulo6NovoprojetowebPgina41
Oarquivoxmldeconfiguraodotomcat
Emprocessosdebuildmaisdesenvolvidos,noexisteconfiguraoaserfeitanemmesmona mquinadedesenvolvimento,sendotudoautomatizadoporprocessosdebuildedeploy.
Captulo6NovoprojetowebPgina42
captulo
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
scriptlet
scriptletocdigoescritoentre<%e%>,essenomecompostodapalavrascript(linguagemde script)comosufixolet,queindicaalgopequeno. ASunpossuiessamaniadecolocarosufixoletemmuitascoisascomoosscriptlets,servlets, portletsetc. Podemosavanarmaisumpoucocomjspeutilizarumadasvariveisjimplicitasnojsp: todoarquivojspjpossuiumavarivelchamadaout(dotipoJspWriter)quepermiteimprimir objetosatravsdomtodoprintln:
<%out.println(nome);%>
Avariveloutumobjetomplicitonanossapginajspeexistemoutrasdeacordocoma
Captulo7JSPJavaServerPagesPgina43
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
Captulo7JSPJavaServerPagesPgina44
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
</ul></html> c)Testeaurlhttp://localhost:8080/jspteste/listascriptlet.jsp
Captulo7JSPJavaServerPagesPgina46
ConfiraoseuContatoDao,seelepossuiosseguintesproblemasdecompilao:
Captulo7JSPJavaServerPagesPgina47
PararemoverumpoucodocdigojavaqueficanapginajspaSundesenvolveuuma linguagemchamadaExpressionLanguagequeinterpretadapeloservletcontiner. Nossoprimeiroexemplocomessalinguagem utilizlaparamostrarparmetrosqueo clienteenviaatravsdesuarequisio. Por exemplo, se o cliente chama a pgina testaparam.jsp?idade=24 o programa deve
Captulo7JSPJavaServerPagesPgina48
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>
3)Testeosistemaacessandoapginahttp://localhost:8080/jspteste/testaidade.jsp.
welcomefilelist
Oarquivoweb.xmlabaixodizqueosarquivoschamadosbemvindo.jspdevemserchamados quandoumclientetentaacessarumdiretriowebqualquer. Ovalordessecampocostumaserindex.htmlemoutraslinguagensdeprogramao. Vocpodeindicarmaisdeumarquivoparaseroseuwelcomefile!
Captulo7JSPJavaServerPagesPgina49
b)Mostrandoosdoisparmetros:
<html> Testandoseusparametros:<br/> Onome${param.nome}<br/> Aidade${param.idade} </html>
c)Exemplodeumresultadofinal:
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
poisdiversasbibliotecasimportantesestobaseadasnele:Hibernate,Struts,JXPath,EJBetc.
Ateno
NaExpressionLanguage${contado.nome}chamarafunogetNomeporpadro.Paraqueisso semprefuncionedevemoscolocaroparmetroemletraminsculaouseja${contato.Nome}no funciona.
Captulo7JSPJavaServerPagesPgina52
captulo
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).
Captulo8JSTLJavaServerPagesTagLibraryPgina53
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.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
<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:
<% //... 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
forEachevarStatus
possvel criar um contador do tipo int dentro do seu lao forEach. Para isso basta definir o
Captulo8JSTLJavaServerPagesTagLibraryPgina55
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?
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.
<c:importurl="outrapagina.jsp"/> Captulo8JSTLJavaServerPagesTagLibraryPgina57
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.
Captulo8JSTLJavaServerPagesTagLibraryPgina58
1)Verifiqueseasuatagliburiestdigitadacorretamente.
<%@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
<br/> <fontcolor=blue>Contedodasuapginaaqui...</font>
</html>
3)Testeaurlhttp://localhost:8080/jspteste/testatitulo.jsp
AJSTLresolveesseproblema,supondoqueasuaaplicaosechamejspteste,ocdigo abaixogeraastring/jspteste/imagem/banner.jpg.
<c:urlvalue="/imagem/banner.jpg"/>
2)Testeasuapginaevejaoresultado(cdigofonteHTML).
8.17 - Exerccios
1)Crieumarquivojspweb/preenchenome.jsp:
<html> Digiteseunomeepressioneoboto:<br/>
Captulo8JSTLJavaServerPagesTagLibraryPgina61
b)Casoapessoanotenhapreenchido:
Captulo8JSTLJavaServerPagesTagLibraryPgina62
captulo
Controle de erro
RenDescartes
Divide as dificuldades que tenhas de examinar em tantas partes quantas for possvel, para uma melhor soluo.
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
mudasse?Teramosquemudartodasaspginas?
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.
Captulo9ControledeerroPgina64
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.
Agora precisamos configurar no arquivo web.xml qual tipo de exception vai para qual pginajsp.Esse ummapeamentosimples,bastaadicionaronomedaclassedaexception (exceptiontype)eonomedapginaalvo(location).
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
5)Testeaurlhttp://localhost:8080/jspteste/testaerro.jsp
</errorpage> Obs:OTomcat5.5.17temumbugfazendooexerccionofuncionar.
Captulo9ControledeerroPgina67
Pginadeerroerro.jspnocomeacomuma/,isto,eleestdizendoexatamenteoseu erro!
9.11 - Exerccios
1)Trateoerrotipo404nasuaaplicao.
Captulo9ControledeerroPgina68
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
Captulo9ControledeerroPgina70
captulo
10
10
Servlets
KonradAdenauer
Vivemos todos sob o mesmo cu, mas nem todos temos o mesmo horizonte.
Nestecaptulovociraprenderacriarpequenosobjetosquefuncionamcomoaplicaesweb.
10.1 - Servlet
SERVLET
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.
HTTP
Cliente Firefox
Cliente Opera
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
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{
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
nome
EagoracolocaronomeservletDeTesteparaaurl/oi:
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
a)EstendaHttpServlet.
publicclassOiMundoextendsHttpServlet{ }
d)Escrevaocdigodomtodoservice.
protectedvoidservice(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException,IOException{
Captulo10ServletsPgina74
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
Captulo10ServletsPgina75
2)Digitarerradoonomedopacotedasuaservlet:
<servletclass>br.caelum.servlet.OiMundo</servletclass>
3)Esquecerdecolocaronomedaclassenomapeamentodaservlet:
<servletclass>br.com.caelum.servlet</servletclass>
Captulo10ServletsPgina76
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
}
RecursoAvanado:loadonstartup
As servlets marcadas com nmeros menores sero inicializadas antes que as de nmeros maiores.Servletsmarcadascomomesmonmeronopossuemumaordemdeinicializaoque sejadefinidapelaespecificao.
PrintWriterwriter=response.getWriter(); OutputStreamstream=response.getOutputStream();
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
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{
OmtodogetParameterretornaumaString,portantotodotipodetratamentodeveser
Captulo10ServletsPgina79
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{
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
8)Testeaurlhttp://localhost:8080/jspteste/testapost.jsp
Captulo10ServletsPgina82
Todososparmetros
O mtodo request.getParameterNames() retorna uma Enumeration com todos os nomes de parmetrosenviados.
doGetresponsvelpelosmtodosGET
protectedvoiddoGet(HttpServletRequest,HttpServletResponse)throws ServletException, IOException;
DOPOST
doPostresponsvelpeloPOST
protectedvoiddoPost(HttpServletRequest,HttpServletResponse)throws ServletException, IOException;
Captulo10ServletsPgina83
init
destro
ServletContiner tempo
Uma das boas prticas de programao com servlets diz que devemos implementar sempreomtodoserviceenoumdosmtodoscomodoGet,doPost,doHeaderetc.
10.14 - Exerccios
1)CrieaclasseTestaConversaoParametrosnopacotecerto.
Captulo10ServletsPgina84
2)Escrevaocdigoquevimosanteriormente:
packagebr.com.caelum.servlet; //faaimportsaqui,useCTRL+SHIFT+O publicclassTestaConversaoParametrosextendsHttpServlet{ protectedvoidservice(HttpServletRequestrequest, HttpServletResponseresponse)throwsServletException, IOException{
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:
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?
10.17 - Exerccios
1)CrieaservletContadornopacotecorreto.EscolhaomenuFile,New,Class.
Captulo10ServletsPgina87
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
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
Servletseconcorrncia
SINGLETHREA DMODEL
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.
3.Segundavez
tempo
servlet
Vantagens
Obenefciomaisclaro nocolocarumasrieimensadecdigohtmldentrodeumaclasseem java,oquedificultamuitoaalteraodapginaporumdesigner.Compareocdigodalistagemdo OiMundocomoservlet.Muitomaissimplesdeeditarohtml:masodesignernocompreendeo cdigoJava. DuascoisasqueajudamacombateresseproblemasoosJavaBeansepadresdearquitetura variadosexistentesnomercado.
Captulo10ServletsPgina90
JSP:ficamaisfcilparaodesigneralterarocdigohtml Servlets:ficamaisfcildeprogramarorientadoaobjetoseemJava
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
4)Selecioneoseuarquivoteste.war,vnomenuEditeescolhaCut.
5) V para o diretrio apachetomcat, webapps. Certifiquese que seu tomcat est rodando.
Captulo10ServletsPgina92
6)Coleoseuarquivoaqui(Edit,Paste).Reparequeodiretriotestefoicriado.
Captulo10ServletsPgina93
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
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.26 - Exerccio
1)CrieumaservletchamadaAdicionaContatoServletnopacotebr.com.caelum.servlet
2)NoseesqueadeextenderaclasseHttpServlet.
publicclassAdicionaContatoServletextendsHttpServlet{
3)Coloqueomtodoservice.
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{
Captulo10ServletsPgina97
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>
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
Captulo10ServletsPgina99
captulo
11
11
Vivemos todos sob o mesmo cu, mas nem todos temos o mesmo horizonte.
NestecaptulovociraprenderautilizaroutrosrecursosavanadosdaAPIdeservlets.
Podemos,porexemplo,manteremumavarivelomomentodeinicializaodanossa aplicao:
Dateinicializacao=newDate();
ESCOPO DE APLICAO
SERVLETCONTE XT
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:
11.2 - Exerccios
1)Crieaclasse ControleDeAplicacao nopacotebr.com.caelum.servlet.Escolhao menuFile,New,Class.
a)ImplementeServletContextListener.
publicclassControleDeAplicacaoimplementsServletContextListener{ }
2)Abraoarquivoweb.xmlemapeieoseulistener.
<listener> <listenerclass>br.com.caelum.servlet.ControleDeAplicacao</listenerclass> </listener>
11.3 - getServletContext()
TodaservletpossuiummtodochamadogetServletContextqueretornaumareferncia
Captulo11ServleteJSPAPIPgina101
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
3)Testeaurlhttp://localhost:8080/jspteste/testaaplicacao.
Portantopodemosutilizalaatravsdescriptlet:
<%=application.getAttribute("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
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
captulo
12
12
Opadroarquiteturalfeijocomarrozeorequestdispatcher.
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>");
}
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
Agorapodemosfacilmenteexecutaralgicadenossaaplicaowebemumaservlete entoredirecionarparaumapginajsp,ondevocpossuiseucdigohtml.
Forwardeinclude
Omtodoforwardspodeserchamadoquandonadaforaescritoparaasada.Nomomentoque algoforescritoficaimpossvelredirecionarousuriopoisoprotocolohttpnopossuimeiosde voltaratrsnaquiloquejfoienviadoaocliente. ExisteoutromtododaclasseRequestDispatcherquerepresentaainclusodepginaenoo redirecionamento.Essemtodosechamaincludeepodeserchamadoaqualquerinstantepara acrescentaraoresultadodeumapginaosdadosdeoutra.
Captulo12ModelViewControllerPgina106
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
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); }
Maseagoracomoinstanciaressaclasse?
Objectobj=businessLogicClass.newInstance();
Ecomochamaromtodoexecute?Reparequeusamosomesmomtodoemtodasas lgicasdenegcio:issoumpadroquedefinimos.Quandoissoaparece,normalextrairuma
Captulo12ModelViewControllerPgina109
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.
JSP
BD
Captulo12ModelViewControllerPgina110
captulo
13
13
NoexistemistrioportrsdeumframeworkMVC.VamoscriaraquioSYPMVCFrameworkSimple YetPorwerfulMVCFramework.
13.2 - Exerccios
1)Crieasuainterfacenopacotebr.com.caelum.mvc:
publicinterfaceBusinessLogic{ voidexecute(HttpServletRequestreq,HttpServletResponseres)throwsException; }
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); } } }
Caelumhttp://www.caelum.com.brJava para desenvolvimento Web thrownewServletException(e); } try{ businessLogicObject.execute(request,response); } catch(Exceptione){ thrownew ServletException(Algicadenegcioscausouuma exceo,e); } } }
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
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
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..."); } }
3)Testeaurlhttp://localhost:8080/jspteste/testaadicionamvc.jsp
Captulo13ConstruindoumFrameworkMVCPgina116
Olheseuconsole:
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
BD
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
captulo
14
14
Jakarta Struts
A qualidade a quantidade de amanh
HenriBergson
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.3 - Exerccios
1)Descompacteoarquivoprojetostruts.zipnoseuworkspace: a)Abraofilebrowser b)Entrenapastacaelumedepois21.Escolhaoarquivoprojetostruts.zip
Captulo14JakartaStrutsPgina120
c)Cliquedadireitanoarquivoprojetostruts,escolhaExtractTo. d)Escolhaparamudarodiretorioalvo.
e)Escolhaseuworkspaceemandeextrair.
Captulo14JakartaStrutsPgina121
f)Oresultadopodeservistoaovoltaraoseuworkspace.
2)Crieumprojetochamadostrutsnoeclipse:
Captulo14JakartaStrutsPgina122
Captulo14JakartaStrutsPgina123
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
</webapp>
6)Inicializeotomcatetesteaurlhttp://localhost:8080/struts/
Captulo14JakartaStrutsPgina125
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
Deixe<paramvalue>false</paramvalue>casonoqueiraalistageme<param value>true</paramvalue>casocontrrio.
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:
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
<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
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>
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
Vocdevereescreveromtodoexecute,comonoexemploabaixo:
packagebr.com.caelum.struts.action; //imports.... publicclassTesteSimplesActionextendsAction{ publicActionForwardexecute(ActionMappingmap,ActionFormform, HttpServletRequestrequest,HttpServletResponseresponse) throwsException{ //... } }
Captulo14JakartaStrutsPgina130
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>
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
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
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
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?
Captulo14JakartaStrutsPgina134
4)Porltimo,oerrodosesquecidos.Sevocnocriaroarquivojspoucolocarumnome
Captulo14JakartaStrutsPgina135
invlidooerroojconhecido404:
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
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"); } }
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>
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
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
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
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.20 - Formulrio
NuncaeleganteficartrabalhandocomomtodogetParameterdorequest,sendoque muitomelhortrabalharcomclassesquensmesmosescrevemos.Portantovamosimaginarum cenriosimples:desejamosadicionaronome,emailedescricodocliente.
ACTIONFORM
Ateno:oformulriohtmldever teroscamposcomomesmonomequeasvariveis membrodoseuformulrio! Existe uma opo avanada de fazer o formulrio atravs de xml, no deixa de ser bastantecdigoeaindacomadesvantagemdenotererrosdecompilao.
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
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.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"); }
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
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?
Captulo14JakartaStrutsPgina145
name=ContatoFormnasuatagaction.
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; }
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; }
Captulo14JakartaStrutsPgina146
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
Escopodoformulrio
Existeumatributoopcionalnatagactionquandoutilizandoumformulrio:scope.Esseatributo utilizadoparalerosdadosdoformulriodorequestoudasesso. Utilizamos o escopo de sesso (padro) quando desejamos que os dados se mantenham atreladosaqueleclientepormaisdeumrequest,enquantoqueoescopoderequestatrelaos dadossomenteatoterminodarequisio.
Captulo14JakartaStrutsPgina148
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.
Captulo14JakartaStrutsPgina149
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.
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
Captulo14JakartaStrutsPgina150
i)Escolhaolinkparaingls:
OdiagramaaseguirrepresentaoqueaconteceaoalteraroLocale:
Captulo14JakartaStrutsPgina151
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
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
Valelembrarqueoprpriogrupoquedesenvolveostrutsjrecomendaousodastaglibs dajstlemvezdaproprietriadostruts.
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
captulo
15
15
Jakarta Struts
Conf cio
Eagoravamosatagdeformulrionostrutsconfig.xml:
<formbeans> Captulo15JakartaStrutsPgina154
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
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
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.
erro.jsp
<html> Ocorreualgumerroaotentarselogar! </html>
15.8 - Exerccios
1)CriesuaaodeLogin:
packagebr.com.caelum.struts.action;
Captulo15JakartaStrutsPgina157
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
ou
b)Asuaestruturadeclassesestparecidacomaseguir?
15.11 - Cookies
Oprotocolohttputilizadoat agoraparaoacesso pginas limitadopornomanter detalhescomoquemquementreumaconexoeoutra,portantofoiinventadoumsistemapara
Captulo15JakartaStrutsPgina159
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
Obs:Segundoaespecificaoessaconfiguraodeveriafuncionar,masnaverso 5.5.12dotomcat,existeumbug.
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
15.15 - Exerccios
1)Aologarumusuriocomsucesso,adicioneesseusuriosesso: a)Trabalhedentrodaaodeloginantesdeirparaapginadeok b)Acesseasesso:
HttpSessionsession=request.getSession();
c)Adicioneousuriosesso:
session.setAttribute(funcionario,funcionario);
c)Testeacessarapginadetestesemselogar
d)Testeacessarapginadetesteapsselogar
Captulo15JakartaStrutsPgina162
Logandonovamente
Reparequeaoacessarapginadeloginapsterselogado,seuusuriopermanecenasesso. Sendoassim,sevocerrarousurio/senha,voccontinualogado! ParafazerologoutvocpodeusaromtodoremoveAttributedaclasseHttpServletRequest.
Captulo15JakartaStrutsPgina163
captulo
16
16
Hibernate 3.2
BarondeMontesquieu
uma experincia eterna de que todos os homens com poder so tentados a abusar.
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.
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
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;
Captulo16Hibernate3.2Pgina165
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;
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:
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
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);
16.10 - Exerccios
1)CrieaclasseGeraTabelas.
packagebr.com.caelum.hibernate; publicclassGeraTabelas{ publicstaticvoidmain(String[]args){
2)Criesuastabelasexecutandoocdigoanterior.
Captulo16Hibernate3.2Pgina167
OHibernatedevereclamarquenoconfiguramosnenhumarquivodelogparaele(dois warnings)emostrarocdigoSQLqueeleexecutounobanco.
16.11 - Sesses
Agoraj podemospegarumafbricadesessesdotipo SessionFactory,paraisso bastachamaromtodobuildSessionFactorydoobjetocfg.
packagebr.com.caelum.hibernate; publicclassTesteDeConfiguracao{ publicstaticvoidmain(String[]args){
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){
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
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.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
Possivelsaida:
AtravsdesseDAO,podemossalvar,remover,atualizareprocurarProdutos.
16.19 - Exerccios
1)FaaumaclassechamadaProdutoDAOdentrodopacotebr.com.caelum.hibernate.dao
packagebr.com.caelum.hibernate.dao; //importsaquiCTRL+SHIFT+O Captulo16Hibernate3.2Pgina171
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?
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(); }
Usando o Criteria, como no listaTudo anteriormente, isso bastante simples. Nosso mtodopginaficaassim:
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
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());
Captulo16Hibernate3.2Pgina174
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
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
captulo
18
18
Apndice A - VRaptor
MicheldeMontaigne
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
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
18.3 - Vraptor 2
Tudooquefaremosnestecaptuloest baseadonoframeworkconhecidocomovraptor (http://vraptor2.sourceforge.net).
Passo4:Crieumarquivochamadovraptor.xmldentrodoseudiretriosrc.
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();
Esesurgiranecessidadedecriarummtodoatualiza?Poderamosreutilizaramesma classeparaosdoismtodos:
@Component(contato) publicclassContatoLogic{
//meucontato @Read(create=true)
@Out privateContatocontato;
Oprprioframeworkchamaosmtodos:
contato.setNome(request.getParameter("contato.nome")); contato.setEmail(request.getParameter("contato.email")); contato.setDescricao(request.getParameter("contato.descricao"));
Tudoissoautomaticamente!
Captulo18ApndiceAVRaptorPgina179
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.9 - Exerccios
1)Crieumsistemadeinclusodecontatos a)CrieaclasseContatoLogicnopacotebr.com.caelum.vraptor
@Component(contato) publicclassContatoLogic{
//meucontato @Read(create=true)
@Out privateContatocontato;
b)Crieoarquivoweb/vraptorformulario.jsp
<html> <formaction="contato.adiciona.logic"> Nome:<inputname="contato.nome"/><br/> Email:<inputname="contato.email"/><br/> Captulo18ApndiceAVRaptorPgina180
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>
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
Captulo18ApndiceAVRaptorPgina182
captulo
19
19
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
19.2 - Vantagens
Ogrupojakartaenumeraalgumasvantagensdovelocity,quandocomparadoaojsp: 1. 2. 3. 4. 5. ajudaaforarumaseparaolimpaentreacamadadevisualizaodascamadasde controleedemodelo,colaborandotantocomprogramadoresquantocomdesigners avelocitytemplatelanguage(vtl)tempoucasdiretivasesimplesdeaprendar. velocitytemplatesnosolimitadosahtml,podendogerarfacilmentecdigoxml, sql, ascii,postscriptetc. velocitypermiteacessardadosdeumamaneiraqueowebdesignerentendeoqueest acontecendoo ovelocityfazousodecacheparamelhoraraperformancedesuaspginas
Captulo19ApndiceBJakartaVelocityPgina184
Passo3:Crieoarquivotoolbox.xmldentrododiretrioWEBINF.
<?xmlversion="1.0"?> <toolbox> <tool> <key>text</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.MessageTool</class> </tool> </toolbox>
19.5 - Exerccios
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
Ol$nome!
context.put(nome,Caelum);
VelocityEngine (mergeourender)
OlCaelum!
19.7 - Exerccios
1)Crieumarquivochamadooi.vmecoloqueelenodiretriotarget.Escrevaocdigodo seuprimeirotemplate. 2)Reinicieoseucontextoeacesseapginaoi.vm.
19.9 - Exerccios
1)Crieumarquivochamadostruts.vmecoloqueelenodiretriotarget. a)Escrevaocdigodaseoanterior. b)Adicionetituloedescricaocomochavesnoseuarquivodemensagens c)Acesseapginastruts.vm
Captulo19ApndiceBJakartaVelocityPgina186
//...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
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
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
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
aquivaionossocorpo
#parse(footer.vm)
Existeumaoutradiretiva:a#include.Elafazomesmotrabalhoquea#parsepormo templateinseridonoserinterpretado,isso,nohaveromerge.
19.15 - Comentrios
Parafazerumcomentriodeumalinha:
##essalinhanoserinterpretada
Umcomentriodotipobloco:
#* Esseumcomentriodotipobloco,nadadissoserinterpretado *#
19.17 - ImportTool
IMPORTTOOL
Eparaimportaraurlhttp://www.caelum.com.brnanossapginabastausar:
$import.read(http://www.caelum.com.br)
19.18 - CookieTool
COOKIETOOL
ACookieToolumaferramentaquefacilitamuitootrabalhocomcookies. Definimoselacom:
Captulo19ApndiceBJakartaVelocityPgina189
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
Captulo19ApndiceBJakartaVelocityPgina190
captulo
20
20
Nestecaptulo,vociraprendercomoutilizaroFactoryparacriarumcachedeobjetos.
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
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
Memriacheia?
Fazerocachedetodososobjetospodeconsumirmuitamemria.Vocpodeestarusandoumtipo demapaqueguardaapenasos ltimos50objetosinstanciadosouentoosmaisacessados,por exemplo.
Captulo20ApndiceCDesignPatternsPgina193
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.
<!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
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.
Captulo21ApndiceDServletsPgina195
Captulo21ApndiceDServletsPgina196
captulo
22
22
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
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
PRIMEIRAMENSAGEMDELOG SEGUNDAMENSAGEMDELOG
Captulo22ApndiceEDesignPatternsPgina199
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