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.Seusprofissionaispublicaramjdiversos
artigos nas revistas brasileiras de Java, assim como artigos em eventos acadmicos, e so
presenaconstantenoseventosdatecnologia.
Em 2004 a Caelum criou uma gama de cursos que rapidamente ganharam grande
reconhecimentonomercado.OscursosforamelaboradosporexinstrutoresdaSunquequeriam
trazer mais dinamismoeaplicaras ferramentas e bibliotecasutilizadasno mercado, taiscomo
Eclipse,Hibernate,Struts,eoutrastecnlogiasopensourcequenosoabordadaspelaSun.O
materialutilizadofoiinicialmentedesenvolvidoenquantoeramministradososcursosdeverode
javadaUniversidadedeSoPauloemjaneirode2004pelosinstrutoresdaCaelum.
Em2006aempresafocaseusprojetosemtrsgrandesreas:sistemasdegerenciamento
decontedoparaportais,desenvolvimentodesoluesdeintegraofinanceiraetreinamentocom
intuitodeformao.
Sobre a apostila
EstaaapostiladaCaelumquetemcomointuitoensinarJavadeumamaneiraelegante,
mostrandoapenasoquenecessrionomomentocorretoepoupandooleitordeassuntosque
nocostumamserdeseuinteresseemdeterminadasfasesdoaprendizado.
ACaelumesperaquevocaproveiteessematerial,equeelepossaserdegrandevaliapara
autodidataseestudantes.Todososcomentrios,crticasesugestesseromuitobemvindos.
Omaterialaquicontidopodeserpublicamentedistribudodesdequenosejaalteradoe
seuscrditossejammantidos.Elenopodeserusadoparaministrarqualquercurso,pormpode
serrefernciaematerialdeapoio.Casovocestejainteressadoemuslofinscomerciais,entre
emcontatocomaempresa.
Ateno: Voc pode verificar a data de ltima atualizao da apostila no fim do ndice.
Nuncaimprimaaapostilaquevocreceberdeumamigooupegarporemail,poisatualizamos
constantementeessematerial,quasequemensalmente.Vatonossositeefaaodownloadda
ltimaverso!
www.caelum.com.br
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
iii
iv
vi
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
Captulo1ComoaprenderJavaPgina2
Captulo1ComoaprenderJavaPgina3
captulo
JDBC java.sql
Aotrminodessecaptulo,vocsercapazde:
conectarseaumbancodedadosqualqueratravsdaapijava.sql;
criarumafbricadeconexesusandoodesignpatternFactory;
pesquisardadosatravsdequeries;
executarcomandosnobancodedados;
DAODataAccessObject.
Captulo2JDBCjava.sqlPgina4
Captulo2JDBCjava.sqlPgina5
2)CliqueemFinish.
2.3 - O banco
BANCO DE
DADOS
mysqluroot
Bancodedados
Paraaquelesquenoconhecemumbancodedados,recomendadolermaissobreomesmoe
SQLparacomearausaraapiJDBC.
O processo de armazenagem e captura de dados em um banco chamado de
Captulo2JDBCjava.sqlPgina6
persistncia.AbibliotecapadrodepersistnciaembancodedadosemJavaaJDBCmas
jexistemdiversosprojetosdotipo ORM (ObjectRelationalMapping)quesolucionammuitos
problemasqueaestruturadaapidoJDBC(eODBC)gerou.
ImplementaoJDBC.Qual?
DRIVERMANAG
ER
DriverManager.getConnection("jdbc:mysql://localhost/teste");
Cliente
jdbc:mysql://ip/banco
Devemos substituir ip pelo ip da
mquinae banco pelonomedobancoa
serutilizado.
Seguindooexemplodalinhaacima
e tudo que foi dito at agora, possvel
rodar o exemplo abaixo e receber uma
InterfaceJDBC
ImplementaoJDBC.MySQL
DriverManagerprocura
poralgumdeseus
Driversqueaceiteessa
URLcomoparmetro.
MySQL
Captulo2JDBCjava.sqlPgina7
conexoparaumbancomysqlnaprpriamquina....
packagebr.com.caelum.jdbc;
//importsaqui(ctrl+shift+o)
publicclassJDBCExemplo{
publicstaticvoidmain(String[]args){
try{
Connectioncon=
DriverManager.getConnection("jdbc:mysql://localhost/teste");
System.out.println("Conectado!");
con.close();
}catch(SQLExceptione){
e.printStackTrace();
}
}
}
Masaotestarocdigoacima,nadafunciona.Aconexonopodeseraberta.Porque?
O sistema ainda no consegue
descobrir qual implementao do JDBC
deveserusadoparaaURLmencionada.
O primeiro passo adicionar a
implementao ao classpath: o arquivo
jarcontendoaimplementaodomysql
(mysql
connector) precisa ser
colocado em um lugar visvel ou
adicionado varivel de ambiente
classpath.
AvisandooDriverManagersobre
aexistnciadeumDriverparaoMySQL
Driversconhecidos
SQLServer
DriverManager
Oracle
MySQL
Class.forName("com.mysql.jdbc.Driver");
Aindafaltaregistrarodriverdomysqlnosistema.Paraissobastacarregareleatravsdo
mtodo Class.forName(). Esse mtodo abre uma classe que se registra com o
DriverManager.getConnection().
packagebr.com.caelum.jdbc;
//importsaqui(ctrl+shift+o)
publicclassJDBCExemplo{
publicstaticvoidmain(String[]args){
try{
Class.forName("com.mysql.jdbc.Driver");
Connectioncon=
DriverManager.getConnection("jdbc:mysql://localhost/teste",root,);
System.out.println("Conectado!");
con.close();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}catch(SQLExceptione){
e.printStackTrace();
}
}
}
Alterandoobancodedados
Captulo2JDBCjava.sqlPgina8
TeoricamentebastaalterarasduasStringsqueescrevemosparamudardeumbancoparaoutro.
Pormnotudotosimplesassim,ocdigosqlqueveremosaseguirpodefuncionaremum
bancomasnoemoutro.Dependedequalpadrosqlobancosuporta.
Issoscausadordecabeaeexistemcertosarcabouosqueresolvemissofacilmente,comoo
casodoHibernate(www.hibernate.org)edoPrevayler.
Listadedrivers
Osdriverspodemserbaixadosnormalmentenositedovendedordobancodedados.
Alguns casos, como no MSSQL, existem outros grupos que desenvolvem o driver em
jtds.sourceforge.net
Enquanto isso, voc pode achar o driver do MYSQL (chamado de mysql connector) no site
www.mysql.org.
//importsaqui(ctrl+shift+o)
publicclassConnectionFactory{
publicstaticConnectiongetConnection()throwsSQLException{
try{
Class.forName("jdbc:mysql://localhost/teste");
returnDriverManager.getConnection("com.mysql.jdbc.Driver",
"root","");
}catch(ClassNotFoundExceptione){
thrownewSQLException(e.getMessage());
}
}
}
Poderamoscolocarumavisonanossaaplicao,notificandotodososprogramadoresa
adquirirumaconexo:
Connectioncon=ConnectionFactory.getConnection();
PodemosperceberqueomtodoabreConexaoumafbricadeconexes,isto,ele
fabricaconexesparans,noimportandodeondeelasvieram.Portanto,nadamaisnaturaldo
quechamaraclassedeConnectionFactoryeomtododegetConnection.
2.8 - Exerccios
Captulo2JDBCjava.sqlPgina9
1)Copieodriverdomysqlparaoseuprojeto.
a)entrenoFileBrowser;
b)procureodiretriocaelum;
c)cliquedadireitanodriverdomysql,escolhaCopy;
d)volteparaodiretrioanterior;
e)entrenodiretrioworkspace,jdbc;
f)cliquedadireitaeescolhaPaste:vocacabadecolocaroarquivo.jarnoseuprojeto.
2)CrieumaclassechamadaConnectionFactoryquefabricaconexes.
a)crieanopacotebr.com.caelum.jdbc
b)crieomtodoestticogetConnectionqueretornaumanovaconexo:
publicstaticConnectiongetConnection()throwsSQLException{
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println(Conectandoaobanco);
returnDriverManager.getConnection("jdbc:mysql://localhost/teste",
"root","");
}catch(ClassNotFoundExceptione){
thrownewSQLException(e.getMessage());
}
}
3)CrieumaclassechamadaTestaConexaonopacotebr.com.caelum.jdbc.teste
a)coloqueomtodomain
publicstaticvoidmain(String[]args){...
b)fabriqueumaconexo:
Connectioncon=ConnectionFactory.getConnection();
c)fecheaconexo
con.close();
d)Trateoserroscomthrows.(Use:Ctrl+1eescolhaaddthrowsdeclaration).
4)RodeasuaclasseTestaConexao
a)CliquedadireitanasuaclasseTestaConexao
b)EscolhaRunas,JavaApplication
5)Parecequesuaaplicaonofuncionapoisodrivernofoiencontrado?Esquecemos
decolocarojarnoclasspath!(buildpathnoeclipse)
a)Cliquenoseuprojeto,pressioneF5paraexecutarumRefresh.
b)Selecioneoseudriverdomysql,cliquedadireitaeescolhaBuildPath,AddtoBuild
Captulo2JDBCjava.sqlPgina10
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
facilmenteumavezqueamaiorconfusofeitaaforaentre JavabeanseEnterpriseJava
Beans(EJB).
JAVABEANS
umaclassecommtodosdotipogetesetparacadaumdeseusparmetros,querepresenta
algumobjeto
umaclassecomconstrutorsemargumentosquerepresentaumacoleodeobjetos
Aseguir,vocvumexemplodeumaclassejavabeanqueseriaequivalenteaonosso
modelodeentidadedobancodedados:
packagebr.com.caelum.jdbc.modelo;
publicclassContato{
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;
}
}
Atecnologiajavabeansmuitograndeemaisinformaessobreessavastareaquea
basedoscomponentesescritosemjavapodeserencontradaem:
http://java.sun.com/products/javabeans
SevocquersabermaissobreEnterpriseJavaBeans(EJB),aCaelumofereceocurso
FJ31,noosconfundacomJavaBeans!
2.11 - Exerccios
1)CrieaclassedeContato.
a)Nopacotebr.com.caelum.jdbc.modelo,crieumaclassechamadaContato.
packagebr.com.caelum.jdbc.modelo;
publicclassContato{
privateLongid;
privateStringnome;
privateStringemail;
privateStringendereco;
}
b)VnomenuSource,Generategettersesetterseselecionetodososgettersesetters.
Captulo2JDBCjava.sqlPgina12
Stringsql="insertintocontatos(nome,email,endereco)values('"+nome+
"','"+email+"','"+endereco+"')";
Oexemploacimapossuidoispontosnegativosquesoimportantssimos.Oprimeiro
queoprogramadorquenoescreveuocdigooriginalnoconseguebateroolhoeentendero
queestescrito.Oqueocdigoacimafaz?Lendorapidamenteficadifcil.Maisdifcilainda
sabersefaltouumavrgula,umfechaparntesestalvez?
OutroproblemaoclssicopreconceitocontraJoanad'arc,formalmentechamadode
SQLInjection.Oqueacontecequandoocontatoaseradicionadopossuinonomeumaaspas
simples?Ocdigosqlsequebratodoepradefuncionarou,piorainda,ousuriofinalcapaz
dealterarseucdigosqlparaexecutaraquiloqueeledeseja(sqlinjection)...tudoissoporque
escolhemosaquelalinhadecdigoenofizemosoescapedecaracteresespeciais.
Poressesdoismotivosnoiremosusarcdigosqlcomomostradoanteriormente...vamos
imaginaralgomaisgenricoeumpoucomaisinteressante:
Stringsql="insertintocontatos(nome,email,endereco)values(?,?,?)";
ExisteumamaneiraemJavadeescreverocdigosqlcomonoprimeiroexemplodessa
seo(comcocatenaesdestrings).Essamaneiranoserensinadaduranteocursopois
umapssimaprticaquedificultaamanutenodoseuprojeto.
Perceba que no colocamos os pontos de interrogao de brincadeira, e sim porque
realmente no sabemos oque desejamos inserir. Estamos interessados emexecutar aquele
cdigomasnosabemosaindaquaissoosparmetrosqueiremosutilizarnessecdigosql
queserexecutado,chamadodestatement.
PREPARED
STATEMENT
PreparedStatementstmt=con.prepareStatement("insertintocontatos
(nome,email,endereco)values(?,?,?)");
Logoemseguida,chamamosomtodosetStringdoPreparedStatementparapreencher
osvalores,passandoaposio(comeandoem1)dainterrogaonoSQLeovalorquedeve
sercolocado.
//preencheosvalores
stmt.setString(1,Caelum);
stmt.setString(2,contato@caelum.com.br);
stmt.setString(3,R.Vergueiro3185cj57);
Porfim,umachamadaexecuteexecutaocomandoSQL.
stmt.execute();
Agora imaginetodo esse processo sendo escrito todavezque desejar inserir algono
Captulo2JDBCjava.sqlPgina13
banco?Aindanoconseguevisualizaroquodestrutivoissopodeser?
Vejaoexemploabaixo,queabreumaconexoeinsereumcontatonobanco:
packagebr.com.caelum.jdbc;
//importsaqui
publicclassJDBCInsere{
publicstaticvoidmain(String[]args){
try{
//conectando
Connectioncon=ConnectionFactory.getConnection();
//criaumpreparedStatement
PreparedStatementstmt=con.prepareStatement("insertintocontatos
(nome,email,endereco)values(?,?,?)");
//preencheosvalores
stmt.setString(1,Caelum);
stmt.setString(2,contato@caelum.com.br);
stmt.setString(3,R.Vergueiro3185cj57);
//executa
stmt.execute();
stmt.close();
System.out.println("Gravado!");
con.close();
}catch(SQLExceptione){
e.printStackTrace();
}
}
}
Fechandoaconexo
Nocomumutilizarjdbchojeemdia.OmaispraticadoousodealgumaapideORMcomoo
HibernateouEJB,pormaquelesqueaindainsistemnousodeJDBCdevemprestaratenono
momentodefecharaconexo.
Oexemplodadoacimanofechaamesmacasoalgumerroocorranomomentodeinseriralgum
dadonobancodedados.
Ocomumfecharaconexoemumblocofinally.
Mprtica:Statement
Ao invs de usar o PreparedStatement, voc pode usar uma interface mais simples chamada
Statement,quesimplesmenteexecutaumaclusulaSQLnomtodoexecute:
Statementstmt=con.createStatement();
stmt.execute(insert into contatos (nome,email,endereco) values
('Nome','Email','Endereco'));
stmt.close();
MasprefiraaclassePreparedStatementquemaisrpidaqueStatementedeixaseucdigomuito
maislimpo.
Captulo2JDBCjava.sqlPgina14
Geralmente,seuscomandosSQLconterovaloresvindosdevariveisdoprogramaJava;usando
Statements,vocterquefazermuitasconcatenaes,masusandoPreparedStatements,issofica
maislimpoefcil.
DESIGN
PATTERNS
Algunsdessespequenosproblemasaparecemcomtamanhafreqnciaqueaspessoas
desenvolvem uma soluo padro para o mesmo. Com isso, ao nos defrontarmos com um
desses problemas clssicos, podemos rapidamente implementar essa soluo genrica com
umaououtramodificao.Essasoluopadrotemonomede Design Pattern (padro
de projeto).
A melhor maneira para aprender o que um Design Pattern vendo como surgiu a
necessidadedomesmo.
Abblia
OlivromaisconhecidodeDesignPatternsfoiescritoem1995etemtrechosdecdigoemC++e
Smalltalk.Masoquerealmenteimportasoosconceitoseosdiagramasquefazemdesselivro
independentedequalquerlinguagem.Almdetudo,olivrodeleituraagradvel.
DesignPatterns,ErichGammaetal.
Mas...JavaorientadoaStrings?Vamostentarnovamente:emoutraspalavrasquero
queocdigoaseguirfuncione:
//adicionaumcontatonobanco
Misteriobd=newMisterio();
Captulo2JDBCjava.sqlPgina15
//mtodomuitomaiselegante
bd.adiciona(contato);
Tentaremoschegaraocdigoanterior:seriamuitomelhoremaiselegantepoderchamar
umnicomtodoresponsvelpelaincluso,certo?
packagebr.com.caelum.jdbc;
//importsaqui
publicclassTestaInsere{
publicstaticvoidmain(String[]args){
try{
//prontoparagravar
Contatocontato=newContato();
contato.setNome(Caelum);
contato.setEmail(contato@caelum.com.br);
contato.setEndereco(R.Vergueiro3185cj57);
//gravenessaconexo!!!
Misteriobd=newMisterio();
//mtodoelegante
bd.adiciona(contato);
System.out.println("Gravado!");
}catch(SQLExceptione){
e.printStackTrace();
}
}
}
Ocdigoanteriorjmostraopoderqueiremosalcanar:atravsdeumanicaclasse
seremoscapazesdeacessarobancodedadose,maisainda,somenteatravsdessaclasse
serpossvelacessarosdados.
Estaidia,inocenteaprimeiravista,capazdeisolartodooacessoabancoemclasses
bem simples, cuja instncia um objeto responsvel por acessar os dados. Da
responsabilidadedesteobjetosurgiuonomedeDataAccessObjectousimplesmenteDAO,um
dosmaisfamosospadresdedesenvolvimento.
DAO
OquefaltaparaocdigoacimafuncionarumaclassechamadaContatoDAOcomum
mtodochamadoadiciona.Vamoscriarumaqueseconectaaobancoaoserconstrudauma
instnciadamesma:
publicclassContatoDAO{
//aconexocomobancodedados
privateConnectionconnection;
publicContatoDAO()throwsSQLException{
this.connection=ConnectionFactory.getConnection();
}
}
AgoraquetodoContatoDAOpossuiumaconexocomobancopodemosfocarnomtodo
adiciona, que recebe um Contato como argumento e responsvel por adicionar o mesmo
atravsdecdigosql.
Captulo2JDBCjava.sqlPgina16
//preparedstatementparainsero
PreparedStatementstmt=this.connection.prepareStatement("insertinto
contatos(nome,email,endereco)values(?,?,?)");
//setaosvalores
stmt.setString(1,contato.getNome());
stmt.setString(2,contato.getEmail());
stmt.setString(3,contato.getEndereco());
//executa
stmt.execute();
stmt.close();
}
2.15 - Exerccios
1)Crieaclassebr.com.caelum.jdbc.dao.ContatoDAO
packagebr.com.caelum.jdbc.dao;
//importsaqui(CTRL+SHIFT+O)
publicclassContatoDAO{
//aconexocomobancodedados
privateConnectionconnection;
publicContatoDAO()throwsSQLException{
this.connection=ConnectionFactory.getConnection();
}
publicvoidadiciona(Contatocontato)throwsSQLException{
//preparedstatementparainsero
PreparedStatementstmt=this.connection.prepareStatement("insertinto
contatos(nome,email,endereco)values(?,?,?)");
//setaosvalores
stmt.setString(1,contato.getNome());
stmt.setString(2,contato.getEmail());
stmt.setString(3,contato.getEndereco());
//executa
stmt.execute();
stmt.close();
}
}
2)CrieumaclassechamadaTestaInserecomummtodomain:
packagebr.com.caelum.jdbc;
//importsaqui(CTRL+SHIFT+O)
publicclassTestaInsere{
publicstaticvoidmain(String[]args)throwsSQLEXception{
//prontoparagravar
Contatocontato=newContato();
contato.setNome(Caelum);
contato.setEmail(contato@caelum.com.br);
contato.setEndereco(R.Vergueiro3185cj57);
//gravenessaconexo!!!
ContatoDAOdao=newContatoDAO();
Captulo2JDBCjava.sqlPgina17
//mtodoelegante
dao.adiciona(contato);
System.out.println("Gravado!");
}
}
3)Testeseuprograma.
4)Verifiqueseocontatofoiadicionado.
mysqlhlocalhosturoot
useteste;
select*fromcontatos;
2.17 - Pesquisando
Para pesquisar tambm utilizamos a interface PreparedStatement, de forma que o
mtodoexecuteQueryretornatodososcontatosnoexemploaseguir.
RESULTSET
OobjetoretornadodotipoResultSetquepermitenavegarporseusregistrosatravs
domtodonext.Essemtodoirretornarfalsequandochegaraofimdapesquisa,portantoele
normalmenteutilizadoparafazerumloopnosregistroscomonoexemploaseguir:
//pegaaconexoeoStatement
Connectioncon=ConnectionFactory.getConnection();
PreparedStatementstmt=con.prepareStatement("select*fromcontatos");
//executaumselect
ResultSetrs=stmt.executeQuery();
//iteranoResultSet
while(rs.next()){
}
rs.close();
stmt.close();
con.close();
Pararetornarovalordeumacolunanobancodedadosbastachamarumdosmtodos
getdoResultSet,dentreosquais,omaiscomum:getString.
//pegaaconexoeoStatement
Connectioncon=ConnectionFactory.getConnection();
PreparedStatementstmt=con.prepareStatement("select*fromcontatos");
Captulo2JDBCjava.sqlPgina18
//executaumselect
ResultSetrs=stmt.executeQuery();
//iteranoResultSet
while(rs.next()){
System.out.println(
rs.getString("nome")+"::"+rs.getString("email")
);
}
stmt.close();
con.close();
RecursoAvanado:Ocursor
Assim como o cursor do banco de dados, s possvel mover para o prximo registro. Para
permitirumprocessodeleituraparatrsnecessrioespecificarnaaberturadoResultSetquetal
cursordeveserutilizado.
Mas,novamente,podemosaplicarasidiasdeDAOecriarummtodogetLista()no
nossoContatoDAO:
PreparedStatementstmt=
this.connection.prepareStatement("select*fromcontatos");
ResultSetrs=stmt.executeQuery();
List<Contato>contatos=newArrayList<Contato>();
while(rs.next()){
//criandooobjetoContato
Contatocontato=newContato();
contato.setNome(rs.getString(nome));
contato.setEmail(rs.getString(email));
contato.setEndereco(rs.getString(endereco));
//adicionandooobjetolista
contatos.add(contato);
}
rs.close();
stmt.close();
returncontatos;
2.18 - Exerccios
1)CrieomtodogetListanaclasseContatoDAO.
publicList<Contato>getLista()throwsSQLException{
PreparedStatementstmt=
this.connection.prepareStatement("select*fromcontatos");
ResultSetrs=stmt.executeQuery();
List<Contato>contatos=newArrayList<Contato>();
while(rs.next()){
//criandooobjetoContato
Contatocontato=newContato();
contato.setNome(rs.getString(nome));
contato.setEmail(rs.getString(email));
contato.setEndereco(rs.getString(endereco));
Captulo2JDBCjava.sqlPgina19
//adicionandooobjetolista
contatos.add(contato);
}
rs.close();
stmt.close();
returncontatos;
}
2)VamosusaromtodogetListaagoraparalistartodososcontatosdonossobancode
dados.
3)CrieumaclassechamadaTestaListaDAOcomummtodomain:
a)CrieumContatoDAO:
ContatoDAOdao=newContatoDAO();
b)ListeoscontatoscomoDAO:
List<Contato>contatos=dao.getLista();
c)Iterenessalistaeimprimaasinformaesdoscontatos:
for(Contatocontato:contatos){
System.out.println(Nome:+contato.getNome());
System.out.println(Email:+contato.getEmail());
System.out.println(Endereo:+contato.getEndereco()+\n);
}
4)Rodeoprogramaanteriorclicandodadireitanomesmo,Run,RunasJavaApplication.
Captulo2JDBCjava.sqlPgina20
3)UseaclassedeDAOparaprocurareremovercontatosdobancodedados.
2.21 - Desafios
1)Faaconexesparaoutrostiposdebancodedadosdisponveis.
publicvoidaltera(Contatocontato)throwsSQLException{
PreparedStatementstmt=connection.prepareStatement("updatecontatosset
nome=?,email=?,endereco=?whereid=?");
stmt.setString(1,contato.getNome());
stmt.setString(2,contato.getEmail());
stmt.setString(3,contato.getEndereco());
stmt.setLong(4,contato.getId());
stmt.execute();
stmt.close();
}
Noexistenadadenovonaslinhasacima.Umaexecuodequery!Simples,no?
Agoraocdigopararemoo:comeacomumaquerybaseadaemumcontato,masusa
somenteoiddeleparaexecutaraquerydotipodelete:
1. publicvoidremove(Contatocontato)throwsSQLException{
2.
PreparedStatementstmt=connection.prepareStatement("deletefrom
contatoswhereid=?");
3.
stmt.setLong(1,contato.getId());
4.
stmt.execute();
5.
stmt.close();
6. }
2)AdicioneomtodopararemovercontatonoseuContatoDAO.
publicvoidremove(Contatocontato)throwsSQLException{
PreparedStatementstmt=connection.prepareStatement("deletefromcontatos
whereid=?");
stmt.setLong(1,contato.getId());
stmt.execute();
stmt.close();
}
Captulo2JDBCjava.sqlPgina21
3)Useosmtodoscriadosanteriormenteparafazertestescomoseubancodedados:
atualizeeremovaumcontato.
4)CrieumaclassechamadaFuncionariocomoscamposid(Long), nome,usuarioe
senha(String).
5)Crieumatabelanobancodedados.
6)CrieumaclassedotipoDAO.
7)Useaparainstanciarnovosfuncionriosecoloclosnoseubanco.
Captulo2JDBCjava.sqlPgina22
captulo
O que o JEE?
OqueoJavaEnterpriseEdition?
Servidordeaplicao
ServletContiner
Implementaodereferncia
3.1 - As especificaes
OJEE(JavaEnterpriseEditionouJavaEE)nopassadeumasriedeespecificaes
bemdetalhadas,dandoumareceitadecomodeveserimplementadoumsoftwarequefazum
determinadoservio.
Veremosnocursoosvriosserviosqueumsoftwaredeveimplementarparaseguiras
especificaes do JEE. Veremos tambm conceitos muito importantes, para depois firmar
jargescomoservidor de aplicaoecontiners.
Essesserviosvariamdesdeenviodeemails,atcomplexosserviosdetransao.
PorqueaSunfazisso?Aidiaquevocpossacriarumaaplicaoqueutilizeesses
servios.Comoessesserviossobemcomplicados,vocnoperdertempoimplementando
essapartedosistema,pormterdecomprardealgum(existemimplementaesgratuitasde
excelentequalidade).
Algum dia, voc poder querer trocar essa implementao atual por uma que mais
rpidaemdeterminadospontos(econseqentementemaiscara).Pormcontinuarutilizandoa
mesmainterface,isto,comovocchamaaquelasfuncionalidadesdoJavaEE.Oquemudaa
implementao da especificao,voctemessaliberdade,no est preso a umcdigo ea
especificaogarantequesuaaplicaofuncionarcomaimplementaodeoutraempresa.
Ondeencontrarasespecificaes.
OgruporesponsvelporgerirasespecificaesusaositedoJavaCommunityProcess:
http://www.jcp.org/
Lvocpodeencontrartudosobreas JavaSpecificationRequests,isto,osnovospedidosde
bibliotecaseespecificaesparaoJava,tantoparaJSE,quantoEEeoutros.
SobreoJEE,vocpodeencontrarem:
http://java.sun.com/javaee/
3.2 - APIs
Captulo3OqueoJEE?Pgina23
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).
prpriaSundesenvolveumaimplementaoquevemjuntocomoJavaEE,apenasparatestes
dosusurios.
VocpodeusaraRInoseuambientedetrabalho,masvaleapenalembrarqueelano
rpida,enemtemfacilidadesdeusonahoradainstalao,criaodeumanovaaplicaoe
outros.
OutrautilidadedaRIparaqueasempresasquedesejamvenderseuprprioproduto,
possamtirardvidasdecasosemqueaespecificaonotenhasidomuitoclara,testandoesse
casonaRI.
BaixandoaJavaEE
http://java.sun.com/javaee
Altimaversoa5.Cuidadoaofazerodownloadpoisexisteumaversoquetambmvemtodo
Captulo3OqueoJEE?Pgina24
oJavaStandardEdition.
Apache,ApacheGeronimo,gratuito
3.
BEA,BEAWeblogicServer
4.
IBM,IBMWebsphereApplicationServer
5.
Jboss,JbossApplicationServer,gratuito
6.
Objectweb,ObjectwebJonas,gratuito
7.
Oracle,OracleApplicationServer
8.
Sun,SunJavaSystemApplicationServerPlatform
3.5 - Apache?
OgrupoApachepossuiumservidorweb,umservletcontinereumservidordeaplicao,
cuidadoparanochamartudodeApacheenosaberdequalestfalando.
OservidorwebsechamaApacheHttpd,oservletcontinersechamaApacheTomcateo
servidordeaplicaoApacheGeronimo.
Captulo3OqueoJEE?Pgina25
captulo
Servlet Continer
Oqueecomofuncionaumservletcontiner.
4.1 - Introduo
Nocomeo,aInterneteraumadziadepginasestticascontendositesdepesquisade
diversasacademias.
Danecessidadedegerarcontedodinmicocomoosprimeiroscontadores,umaidia
bem simples hoje em dia, surgiram os primeiros programas de CGI (Common Gateway
Interface).
AtravsdelinguagenscomoC,C++,Perl,ASP,PHP, Cobol,Delphi,Shelletc,foi
possvelgerarcontedoquepermiteaousurioacessodiversasfuncionalidadesatravsde
pginasHTML,comoquandovocdesejacomprarprodutosemumalojavirtual.
Paramelhorarodesempenhodoltimo,inventaramoqueviriaaserumaservlet,uma
nova forma de trabalhar com requisies de clientes via web que economiza o tempo de
processamentodeumachamadaeamemriaqueseriagastaparatalprocesso,almdeserem
Javaepossuirtodasasvantagensefacilidadesdeorientaoaobjeto.
Almdomais,servletssoportveistantoquantoqualquerprogramaescritoemJava,e
aqueles que programam servlets no precisam mais se preocupar com a funcionalidade do
servidor,quejfoiescritaparansenoprecisaseralterada.
HTML
EstecursotemcomoprrequisitooconhecimentodeHTML:saberutilizarastagsprincipaispara
aconstruodepginasdinmicas(html,body,form,input,textareaeselect).
CasonoestejaacostumadocompginasHTML,recomendasequetenteleralgumtutorialpara
quenoapareamdificuldadesduranteocurso.
Embreveestudaremosasservlets,masantesveremosoJSP(JavaServerPages),que
comoescrevemosamaiorpartedenossaspginasdinmicasemJava.
Ocontinerocomponenteresponsvelpordarsuporteparaasapisdeservletejsp.
Os3tiposmaiscomumdeinstalaodeservletcontinersewebserverssomostrados
nogrfico.
Clientes
Webserver+
Servlet
Continerjuntos
Tipo1
Webserver
ServletContiner
Tipo2
Webserver
ServletContiner
Tipo3
Noprimeiro,todasasrequisiesvodiretoparaowebserver,quetambmocontiner.
No tipo dois, o webserver usa o continer como um plugin e envia as requisies
pertinentes ao mesmo, enquanto, no tipo trs, as requisies so feitas diretamente ao
webserverouaocontiner.
OJEE5compostopelasseguintesespecificaesligadasaumaaplicaoweb:
JSP
Servlets
JSTL
JSF
Tomcat
Baixeotomcatemhttp://tomcat.apache.orgnolinkdedownloadbinaries.
OTomcatvirouimplementaopadroerefernciadenovasapisdeservlets,isto,quandouma
novaespecificaosurge,otomcatcostumaseroprimeiroservletcontineraimplementaranova
api.
Captulo4ServletContinerPgina27
5)Escolhaasuapastaprincipal:HomeeselecioneExtract.
6)Oresultadoumapastachamadaapachetomcat:otomcatjestinstalado.
Captulo4ServletContinerPgina28
Captulo4ServletContinerPgina29
captulo
Nestecaptulovociraprendera:
instalaropluginparajspdogrupoAmateras
instalaropluginparaotomcatdaSysdeo
configurarosdoispluginsparasuainstalao
Captulo5OeclipseeseuspluginsPgina30
EscolhaaopoDisablePreview.
InfelizmenteaversodoFirefoxnoLinuxqueusamosnocompatvelcomoplugindo
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
Nessecaptulo,vocaprender:
acriarumnovoprojetowebnoeclipse;
quaissoosdiretriosimportantesdeumaaplicaoweb;
quaissoosarquivosimportantesdeumaaplicaoweb;
ondecolocarsuaspginasearquivosestticos;
iniciarotomcatatravsdoplugindoeclipse;
configurarseuprojetoparausaroplugindehtml,jspexml;
configurarseuprojetoparausaroplugindoAmateras.
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.Istose
escolhermos o nome /web como subdiretrio raiz teremos que ao acessar a url
http://localhost:8080
/jspteste
/bemvindo.html
SfaltacriarmosumdiretriolibemWEBINF:
7)CliquedadireitanodiretrioWEBINFecrieumnovochamadolib.
Captulo6NovoprojetowebPgina38
Caso seu resultado final no mostre os arquivos jar do tomcat siga as seguintes
instrues:
8)Cliquedadireitanoprojeto
9)EscolhaTomcat,addTomcatlibtoprojectbuildpath
emProject,Properties,JavaBuildPathquetodososarquivosquesocompiladosvoparar
nessediretrio!Essesarquivosestonoclasspathdesuaaplicaowebautomaticamente.
web/WEBINF/lib: aquiestoasbibliotecas(arquivos.jar)queseronecessriaspara
nossaaplicaoweb.Essasbibliotecasestonoclasspathdesuaaplicaoautomaticamente.
WEBINF/lib
OdiretriolibdentrodoWEBINFpodecontertodasasbibliotecasnecessriasparaaaplicao
web,evitandoassimqueoclasspathdamquinaquerodaaaplicaopreciseseralterado.
Alm do mais, cada aplicao web poder usar suas prprias bibliotecas com suas verses
especficas!Vocvaiencontrarprojetosopensourcequesomentefornecemsuporteerespondem
perguntas aqueles usurios que utilizam tal diretrio para suas bibliotecas, portanto evite ao
mximoousodoclasspathglobal.
6.6 - web.xml
Precisamosagoracriarumarquivoimportanteparatodaaplicaoweb:
web/WEBINF/web.xml:essearquivorepresentaaestruturadanossaaplicaoweb,o
bsicoparatodaaplicaoweb:
<?xmlversion="1.0"encoding="ISO88591"?>
<webappxmlns="http://java.sun.com/xml/ns/j2ee"version="2.4">
<displayname>Aplicacaowebsimples</displayname>
</webapp>
AgoraquejinstalamosoTomcat,podemosnospreocuparnacriaodenossaprimeira
aplicaoweb,queserbaseadanatecnologiachamadaJSP,Java Server Pages,pginas
dinmicasquenormalmentegeramcontedohtmlparaservidoresweb.
Apesardoarquivoweb.xmlseropcionaleleserextremamenteimportantemaisparaa
frenteemnossaaplicao.
Captulo6NovoprojetowebPgina40
3)AssimcomonaconfiguraodoplugindoTomcat,escolhaodiretrio/webcomobase
doseuprojetoweb.
<Contextpath="/jspteste"docBase="/home/usuario/workspace/jspteste/web/"
reloadable="true"/>
Captulo6NovoprojetowebPgina41
Oarquivoxmldeconfiguraodotomcat
Emprocessosdebuildmaisdesenvolvidos,noexisteconfiguraoaserfeitanemmesmona
mquinadedesenvolvimento,sendotudoautomatizadoporprocessosdebuildedeploy.
Captulo6NovoprojetowebPgina42
captulo
Nessecaptulo:
vocaprenderoqueJSP;
suasvantagensedesvantagens.
O primeiro arquivo jsp que vamos criar chamado bemvindo.jsp. Esse arquivo
poderiacontersimplesmentecdigohtml,comoocdigoaseguir:
<html>Bemvindo</html>
AfinalJSP uma pgina html comum que contem tambm cdigo Java
epossuiextensojsp,claro.
Assim fica claro que uma pgina jsp nada mais que um arquivo baseado em html.
Sejamos elegantes aoponto deescrever umcdigo java na nossaprimeirapgina. Que tal
declararumavariveldotipoString:
<%
Stringmensagem=Bemvindo!;
%>
SCRIPTLET
Simples!Paraescrevercdigojavanasuapginabastaescrevloentreastags<%e%>.
Essecdigochamadodescriptlet.
Essaidiadecolocarcdigodeumalinguagemdeprogramaojuntocomhtmlnoto
nova.ANetscapepossuiaoSSJS(ServerSideJavascript)porexemplo,usandocdigobaseado
emjavascript.
scriptlet
scriptletocdigoescritoentre<%e%>,essenomecompostodapalavrascript(linguagemde
script)comosufixolet,queindicaalgopequeno.
ASunpossuiessamaniadecolocarosufixoletemmuitascoisascomoosscriptlets,servlets,
portletsetc.
Podemosavanarmaisumpoucocomjspeutilizarumadasvariveisjimplicitasnojsp:
todoarquivojspjpossuiumavarivelchamadaout(dotipoJspWriter)quepermiteimprimir
objetosatravsdomtodoprintln:
<%out.println(nome);%>
Avariveloutumobjetomplicitonanossapginajspeexistemoutrasdeacordocoma
Captulo7JSPJavaServerPagesPgina43
especificaodomesmo.
Existemaindaoutraspossibilidadesparaimprimirocontedodanossavarivel:podemos
utilizarumatalho(muitoparecido,ouigual,aoutraslinguagensdescriptparaaweb):
<%=nome%><br>
Agorajestamosaptosaescreveronossoprimeirojsp.
Comentrios
Oscomentriosemumapginajspdevemserfeitoscomooexemploaseguir:
<%comentrioemjsp%>
7.2 - Exerccios
1)Crieoarquivoweb/bemvindo.jsp.
<html>
<%comentrioemjspaqui:nossaprimeirapginajsp%>
<%
Stringmensagem="Bemvindo!";
%>
Duasversesdiferentesnahoradeimprimiralgo:<br>
<%out.println(mensagem);%><br>
<%=mensagem%><br>
<%
System.out.println("Tudofoiexecutado!");
%>
</html>
2)Testeaurlhttp://localhost:8080/jspteste/bemvindo.jsp
3)OndeapareceuamensagemTudofoiexecutado!?
Lembresequeocdigojavainterpretadonoservidor,portantoapareceunoconsoledo
seuTomcat.
Captulo7JSPJavaServerPagesPgina44
Aindafaltaimportarasclassesdospacotescorretos.
Nojspusamosatag<%@pageimport=%>paraimportaraquiloqueserusadono
nosso cdigo scriptlet. O atributo import permite que seja especificado qual o pacote a ser
importado.Esseatributoonicoquepodeaparecervriasvezes.Nessecasoiremosimportar
diversospacotesseparandoosmesmoscomvrgula.
7.4 - Exerccios
1)Importeosarquivosdonossoprojetoanteriorparaesse.Vnoterminaledigite:
cdworkspace
unzip/caelum/zips/21/jspteste.zip
Captulo7JSPJavaServerPagesPgina45
2)EscolhaonomedoprojetoeaperteateclaF5
3)Crieoarquivoweb/listascriptlet.jsp.
a)Importeospacotesnecessrios.
<%@ page
import="java.util.*,br.com.caelum.jdbc.*,br.com.caelum.jdbc.dao.*,br.com.caelum.jdbc.mode
lo.*" %>
b)Coloqueocdigoparafazeralistagem.
<html><ul>
<%
ContatoDAOdao=newContatoDAO();
Listcontatos=dao.getLista();
for(inti=0;i<contatos.size();i++){
Contatocontato=(Contato)contatos.get(i);
%>
<li><%=contato.getNome()%>,<%=contato.getEmail()%>:
<%=contato.getEndereco()%></li>
<%
}
%>
</ul></html>
c)Testeaurlhttp://localhost:8080/jspteste/listascriptlet.jsp
Captulo7JSPJavaServerPagesPgina46
ConfiraoseuContatoDao,seelepossuiosseguintesproblemasdecompilao:
Captulo7JSPJavaServerPagesPgina47
IssoocorreupoisseuprojetoestconfiguradoparaoJava1.4,entodevemosalterartal
configuraoparaJava5.0:
a)Vnopacotebr.caelum.jdbc.dao,naclasseContatoDao
Useoquickfixdoeclipseparasolucionarseuproblema:
b)Cliquenalmpadacomumxnabarraesquerdadoeclipse
c)EscolhachangeworkspacecomplianceandJREto5.0
PararemoverumpoucodocdigojavaqueficanapginajspaSundesenvolveuuma
linguagemchamadaExpressionLanguagequeinterpretadapeloservletcontiner.
Nossoprimeiroexemplocomessalinguagemutilizlaparamostrarparmetrosqueo
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
<welcomefilelist>
<welcomefile>bemvindo.jsp</welcomefile>
</welcomefilelist>
EacesseaURL:
http://localhost:8080/jspteste/
Verifiquenoseuarquivotestaidade.jspnoactiondentrodoformulrioseonomedapgina
paraaqualdeveriaserredirecionadaestdigitadocorretamente.
2)Aidadenoapareceuesuatelaficouassim?
b)Mostrandoosdoisparmetros:
<html>
Testandoseusparametros:<br/>
Onome${param.nome}<br/>
Aidade${param.idade}
</html>
c)Exemplodeumresultadofinal:
Comojfoicomentadoanteriormente,osJavabeansdevempossuiroconstrutorpblico
semargumentos(umtpicoPlainOldJavaObject:POJO),gettersesetters.
Sedesejarmosinstanciarumobjetodessetipoemnossapginajsppodemosfazeruso
dissoatravsdeumatagsimples.
Isso mesmo! Umatag. A Sunpercebeu queosprogramadores estavam abusandodo
cdigoJavanojspetentoucriaralgomaisnatural(umpontoumtantoquantoquestionvelda
maneira que foi apresentada no incio), sugerindo o uso de tags para substituir trechos de
cdigo.
Oresultadofinalumconjuntodetags(umataglibrary,outaglib)padro,quepossui,
entreoutrastags,afuncionalidadedeinstanciarobjetosatravsdoconstrutorsemargumentos.
JSP:USEBEAN
Issonotodifcil.Dumaolhadanatagaseguir:
poisdiversasbibliotecasimportantesestobaseadasnele:Hibernate,Struts,JXPath,EJBetc.
Ateno
NaExpressionLanguage${contado.nome}chamarafunogetNomeporpadro.Paraqueisso
semprefuncionedevemoscolocaroparmetroemletraminsculaouseja${contato.Nome}no
funciona.
Captulo7JSPJavaServerPagesPgina52
captulo
Nessecaptulo,vocaprender:
oqueJSTL;
taglibcore;
tagc:forEach
tagc:import
diretivainclude
tagc:if
tagc:url
8.1 - JSTL
Seguindoaidiademelhorarocdigojavaqueprecisadeumamaneiraououtraser
escritonapginajsp,aSunsugeriuousodaJavaServerPagesStandardTagLibrary....aJSTL.
Observao: Antes de 2005 JSTL significava JavaServer Pages Standard Template
Library.
JSTL
A JSTL a api que encapsulou em tags simples toda a funcionalidade que diversas
pginas web precisam, como controle de laos (fors), controle de fluxo do tipo if else,
manipulaodedadosxmleainternacionalizaodesuaaplicao.
Antigamente diversas bibliotecas foram criadas por vrios grupos com funcionalidades
similares ao JSTL (principalmente ao Core), culminando com a apario da mesma, numa
tentativadaSundepadronizaralgoqueomercadovcomotil.
ExistemaindaoutraspartesdaJSTL,porexemploaquelaqueacessabancodedadose
permiteescrevercdigossqlnanossapgina,masseodesignernocompreendejavaoque
diremos de SQL??? O uso de tal parte da JSTL desencorajado exceto em casos muito
especiais.
A JSTL foi a forma encontrada de padronizar o trabalho de milhares de
programadores de pginas JSP.
Antes disso muita gente programava como nos exemplos que vimos
anteriormente, somente com JSPs e Javabeans, o chamado Modelo 1, que na poca
fazia parte dos Blueprints de J2EE da Sun (boas prticas).
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?Aindanotoelegantequantoqueramos,certo?Ocdigodentrodoatributo
value chamado de Expression Language (EL), e parte de uma linguagem que
utilizaremosduranteessecurso.
Agora que temos a varivel dao na mo desejamos chamar o mtodo getLista e
podemosfazerissoatravsdaEL:
${dao.lista}
Eagoradesejamosexecutarumloopparacadacontatodentrodacoleoretornadapor
essemtodo:
arrayoucoleo:dao.lista
variveltemporria:contato
NonossoexemplocomscriptletsoquefaltaachamadadomtodogetListaeaiterao:
<%
//...
Listcontatos=dao.getLista();
for(inti=0;i<contatos.size();i++){
Contatocontato=(Contato)contatos.get(i);
%>
<li><%=contato.getNome()%>,<%=contato.getEmail()%>:
<%=contato.getEndereco()%></li>
<%
}
%>
C:FOREACH
AJSTLcoredisponibilizaumatagchamadac:forEachcapazdeiterarporumacoleo,
exatamenteoqueprecisamos.Oexemploaseguirmostraousodeexpressionlanguagedeuma
maneiramuitomaiselegante.
forEachevarStatus
possvel criar um contador do tipo int dentro do seu lao forEach. Para isso basta definir o
Captulo8JSTLJavaServerPagesTagLibraryPgina55
atributochamadovarStatusparaavariveldesejadaeutilizarapropriedadecountdessavarivel.
<c:forEachvar="contato"items="${dao.lista}"varStatus="id">
<li>${id.count}${contato.nome}</li>
</c:forEach>
8.6 - Exerccios
1)ListeoscontatosdeContatoDAOusandojsp:useBeanejstl.
a)Crieoarquivolistaelegante.jsp
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<html>
</html>
b)ColoqueouseBean
<!criaalista>
<jsp:useBean id="dao" class="br.com.caelum.jdbc.dao.ContatoDAO"/>
c) FaaoforEach
<!for>
Reparequeapscriarumanovapginajspnoprecisamosreiniciaronossocontainer!
3)scriptletssouJSTL.Qualdosdoismaisfcilparaodesignerentender?
Teste,porexemplo:
<c:setvar="nome"value="${contato.nome}"/>
<c:outvalue="${nome}"/>
Comovocpodepercebermuitosimplesaprenderautilizarumataglib,bastaleroque
elafaz,passarosargumentoscorretosepronto.
SugerimosaleituracompletadaespecificaodaJSTLnositedasun:
http://java.sun.com/products/jsp/jstl/
http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/index.html
Noprecisadecorartudo,bastalerporcimaesaberoqueexisteeoquenoexiste.
Quandosurgiranecessidadedousodeumadessastagsvoctereladisponvelem
suasmos.
blocodotipotry/catch
blocodotiposwitch
for
foremtokens(ex:a,b,cseparadosporvrgula)
if
import
defaultdoswitch
sada
parmetro
redirecionamento
remoodevarivel
criaodevarivel
vejaadiante
testeparaoswitch
Umaperguntaquesempreaparecenavidadosprogramadoresadecomoexecutaro
cdigodeoutro arquivojspdentrodeumprimeiroarquivojsp,isto,vocquercolocarum
cabealho?Umrodap?
ExisteumatagdaJSTLcorequefazissoparavoc:
<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.
ExisteumamaneiraemumarquivoJSPdeincluirumoutroarquivoestaticamente.Istofaz
comqueoarquivoaserincludosejaliteralmentecopiadoecoladodentrodoseuarquivoantes
daprimeirainterpretao(compilao)doseujsp.
Avantagemquecomoainclusofeitaumanicavezantesdoarquivosercompilado,
essainclusoextremamenterpida,pormvalelembrarqueoarquivoncluidopodeouno
funcionarseparadamente.
<%@includefile=outra_pagina.jsp%>
8.13 - Exerccios
1) Crie uma pgina chamada titulo.jsp. Esse arquivo ir mostrar o contedo da
variveltitulo:
<h1><%=titulo%></h1>
2)Crieumapginachamadatestatitulo.jsp.Essejspvaidefinirumavarivelchamada
tituloeincluiroarquivotituloestaticamente:
<html>
Captulo8JSTLJavaServerPagesTagLibraryPgina59
<%
Stringtitulo=Testedetitulo;
%>
<%@includefile=titulo.jsp%>
<br/>
<fontcolor=blue>Contedodasuapginaaqui...</font>
</html>
3)Testeaurlhttp://localhost:8080/jspteste/testatitulo.jsp
4)Testeaurlhttp://localhost:8080/jspteste/titulo.jsp.Porqueelanofunciona?Talvezno
fizessesentidoessearquivotitulo.jspficarnodiretrioweb.Quetalmovereleparaodiretrio
WEBINF?
5)Altereseuarquivolistascriptlets.jspeincluaapginatitulo.jsp:
<%
Stringtitulo=Listadecontatosviascriptlets;
%>
<%@includefile=titulo.jsp%>
Asvezesnosimplestrabalharcomlinkspoistemosquepensarnaurlqueocliente
acessaaovisualizaranossapgina.
Captulo8JSTLJavaServerPagesTagLibraryPgina60
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
<c:iftest="${emptyparam.nome}">
Vocenaopreencheuocamponome.
</c:if>
<c:iftest="${notemptyparam.nome}">
Vocepreencheu${param.nome}.
</c:if>
</html>
a)Exemplocasoapessoatenhapreenchido:
b)Casoapessoanotenhapreenchido:
Captulo8JSTLJavaServerPagesTagLibraryPgina62
captulo
Controle de erro
Desvantagensnautilizaodeblocostry/catchemumarquivojsp;
Desvantagensnautilizaodatagc:catchemumarquivojsp;
Vantagensnocontroledeerrosatravsdeconfiguraodeclarativa;
Controledeerrosatravsdeexceptions;
Controledeerrosatravsdeerrorcodes.
9.1 - Exceptions
Oqueacontecequandodiversospontosdanossaaplicaoprecisamtratarseuserros?
Oqueacontecequandoumtipodeerroqueocorreemdiversospontosdeveseralterado?
Devemospassarportodosasservletsparatratarisso?Portodososarquivosjsp?
Uma idia bem simples seria colocar em toda pgina jsp um cdigo imenso do tipo
try/catchcomonoexemploaseguirdonossojconhecidolistascriptlet.jsp:
<%@ page
import="java.util.*,br.com.caelum.jdbc.*,br.com.caelum.jdbc.dao.*,br.com.caelum.jdbc.mode
lo.*" %>
<html><ul>
<%
try{
ContatoDAOdao=newContatoDAO();
Listcontatos=dao.getLista();
for(inti=0;i<contatos.size();i++){
Contatocontato=(Contato)contatos.get(i);
%>
<li><%=contato.getNome()%>,<%=contato.getEmail()%>:
<%=contato.getEndereco()%></li>
<%
}
}catch(SQLExceptionex){
%>
Ocorreualgumerroaoacessarobancodedados.
<%
}
%>
</ul></html>
Bastaolharocdigoacimaparaperceberquenoomelhorcaminho.Imaginacomo
seria tratar os erros dessa maneira em toda sua aplicao? E se a mensagem de erro
Captulo9ControledeerroPgina63
mudasse?Teramosquemudartodasaspginas?
<c:catchvar=error>
<jsp:useBean id="dao" class="br.com.caelum.jdbc.dao.ContatoDAO"/>
<c:forEach var="contato" items="${dao.lista}">
<li>
nome: ${contato.nome},
email ${contato.email},
endereo ${contato.endereco}
</li>
</c:forEach>
</c:catch>
<c:iftest=${notemptyerror}>
Ocorreualgumerroaoacessarobancodedados.
</c:if>
ReparequeaprpriaJSTLnosapresentaumasoluoquenosemostraboaparaesse
tipodeerroquequeremostratar.importantedeixarclaroquedesejamostratarotipodeerro
que no tem volta, devemos mostrar uma mensagem de erro para o cliente e pronto, por
exemploquandoaconexocomobancocaiouquandoocorrealgumerronoservidor.
Essessoerrosdoservidor(oudoprogramador)enoerrosdocliente,comoproblemas
devalidaodecampo,quetrataremosnocaptulodostruts.
<li>
nome: ${contato.nome},
email ${contato.email},
endereo ${contato.endereco}
</li>
</c:forEach>
</c:catch>
<c:iftest=${notemptyerror}>
Ocorreualgumerroaoacessarobancodedados.
</c:if>
</html>
Captulo9ControledeerroPgina64
Jsp 1
Jsp 2
web.xml
AgorapodemosmostraramensagemdeerrousandoEL.Lembresequeavarivela
seguirssercriadaseoerroforumaexception!
${pageContext.errorData.throwable}
Portantoapginachamadaerro.jspacabasendoocabealhocomamensagemdeerro:
<%@pageisErrorPage="true"%>
<html>
Umerroocorreu.<br/>
${pageContext.errorData.throwable}
</html>
Agora precisamos configurar no arquivo web.xml qual tipo de exception vai para qual
pginajsp.Esseummapeamentosimples,bastaadicionaronomedaclassedaexception
(exceptiontype)eonomedapginaalvo(location).
<errorpage>
<exceptiontype>classe</exceptiontype>
<location>/pgina.jsp</location>
</errorpage>
muitosimplescontrolarerrosempginasjsp.Imagineapginaaseguirquesimulaum
errodeconexoaobancodedados:
<html>
<%
java.sql.DriverManager.getConnection("jdbc:teste:invalido","usuario","senha");
%>
</html>
Agoraquejconfiguramos,quandoocorrerumaSQLException,apginaerro.jspser
mostradasenadaforfeitopeloprogramador: noprecisamosfazerNADAnapginajspque
podegerarumerro.Simplesno?
Quem trata o erro oservlet conteiner, que lo arquivo web.xml eenvia ofluxo da
requisioparaapginadeerroindicadanaquelearquivo.
9.8 - Exerccios
1)Crieoarquivotestaerro.jsp(reparequenaprticavocnoircriaressearquivo)
<html>
<%
java.sql.DriverManager.getConnection("jdbc:teste:invalido");
%>
</html>
a)Testeaurlhttp://localhost:8080/jspteste/testaerro.jsp
2)Crieoarquivoerro.jsp.
<%@pageisErrorPage="true"%>
<html>
<h1>Umerroocorreu.</h1><br/>
${pageContext.errorData.throwable}
</html>
Captulo9ControledeerroPgina66
3)Altereoarquivoweb.xmleadicioneumaerrorpage:
a)exceptiontype:java.sql.SQLException
b)location:/erro.jsp
<errorpage>
<exceptiontype>java.sql.SQLException</exceptiontype>
<location>/erro.jsp</location>
</errorpage>
5)Testeaurlhttp://localhost:8080/jspteste/testaerro.jsp
</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
Mesmodepoisquevocmapeousuaspginasdeerroparecequeoweb.xmlno
existe,nohouveredirecionamentonenhum?
1)Reinicieotomcat
Captulo9ControledeerroPgina70
10
captulo
Servlets
10
Nestecaptulovociraprenderacriarpequenosobjetosquefuncionamcomoaplicaesweb.
10.1 - Servlet
SERVLET
Umaservletfuncionacomoumpequenoservidor(servidorzinhoemingls)querecebe
chamadasdediversosclientes.
Umaprimeiraidiadaservletseriaquecadaumadelasresponsvelporumapgina,
sendoqueelaldadosdarequisiodoclienteerespondecomoutrosdados(html,gifetc).
ComonoJavatentamossemprequepossveltrabalharorientadoaobjetos,nadamaisnatural
queumaservletsejarepresentadacomoumobjeto.
REQUEST
RESPONSE
CGI
HTTP
Resumindo,cadaservletumobjetojavaquerecebetaisrequisies(request)eretorna
algo(response),comoporexemploumapginahtmlouumaimagemdoformatojpeg.
Diversas requisies podem ser
feitasumamesmaservletaomesmo
tempo em um nico servidor, por isso
elamaisrpidaqueumprogramaCGI
comum.Aespecificaodaservletcita
algumasvantagensdamesmasobreo
antigoCGI.
O diagramaao lado mostra trs
clientes acessando o mesmo servidor
web/continer de servlets atravs do
protocolohttp.
A pgina a ser retornada pela
servlet pode ser um jpeg, um gif, um
arquivo html etc: arquivos de texto ou
simplesmentebinrios.
HTTPSERVLET
SERVLET
ClienteIE
ServidorWeb
Cliente
Firefox
Cliente
Opera
Servlet
Continer
recebe
requisiesvia
http
O comportamento das servlets que iremos ver neste captulo foi definido na classe
HttpServletdopacotejavax.servlet.Elesseaplicamsservletsquetrabalhamatravsdo
protocoloHttp.
Ainterface Servlet aquedefineexatamentecomoumaservletfunciona,masno
necessariamente o que vamos utilizar neste captulo uma vez que ela possibilita o uso de
qualquerprotocolobaseadoemrequisieserespostas.
Captulo10ServletsPgina71
importantefrisarqueamesmainstnciadeumaservlet(omesmoobjeto)podeser
chamadamaisdeumavezparadiferentesrequisiesaomesmotempo,justamenteparaobter
asvantagensmencionadasanteriormentecontraousodeCGI.
Ofuncionamentobsicodeumaservletcompreende:
ainicializaodamesma(veremoscommais
detalhesmaisadiante)
SERVICE
//recebeowriter
PrintWriterout=response.getWriter();
//escreveotexto
out.println("<html>");
out.println("Caelumexplica");
out.println("</html>");
}
ServletxCGI
ficanamemriaentrerequisies,noprecisaserreinstanciado
onveldeseguranaepermissodeacessopodesercontrolado
emCGI,cadaclienterepresentadoporumprocesso,enquantoquecomServlets,cadacliente
representadoporumalinhadeexecuo
Esse captulo est focado na HttpServlet, um tipo que gera aplicaes web baseadas no
protocoloHTTP,masvalelembrarqueaapinofoicriadasomenteparaesteprotocolo,podendo
serfacilmenteextendidaparaoutros.
Captulo10ServletsPgina72
nome
EagoracolocaronomeservletDeTesteparaaurl/oi:
<servletmapping>
<servletname>servletDeTeste</servletname>
<urlpattern>/oi</urlpattern>
</servletmapping>
url
Portantosonecessriosdoispassosparamapearumaservletparaumaurl:
1)Definironomeeclassedaservlet
2)Usandoonomedaservlet,definiraurl
Agoraaservletpodeseracessadaatravsdasseguintesurls:
http://localhost:8080/jspteste/oi
Assim que o arquivo web.xml e a classe de servlet de exemplo forem colocados nos
diretrioscorretosbastaconfigurarotomcatparautilizarodiretriodebasecomopadropara
umaaplicaoweb.
10.4 - Exerccios
1)CrieaservletOiMundonopacotecorreto.EscolhaomenuFile,New,Class.
Captulo10ServletsPgina73
a)EstendaHttpServlet.
publicclassOiMundoextendsHttpServlet{
}
b)UtilizeoCTRL+SHIFT+OparaimportarHttpServlet.
c)Escrevaaestruturadomtodoservice.Muitocuidadocomonomedosargumentosetc.
Aanotao@Overrideserveparanotificarocompiladorqueestamossobrescrevendoo
mtodoservicedaclassepai,seporalgumacasoerrarmosonomedomtodooutrocarmosa
ordemdosparmetros,ocompiladorirreclamarevocvaiperceberoerroaindaemtempode
compilao.
@Override
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
}
d)Escrevaocdigodomtodoservice.
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException{
Captulo10ServletsPgina74
//recebeowriter
PrintWriterout=response.getWriter();
//escreveotexto
out.println("<html>");
out.println("Caelumexplica");
out.println("</html>");
}
2)Abraoarquivoweb.xmlemapeieaurl/oiparaaservletOiMundo.
<servlet>
<servletname>servletDeTeste</servletname>
<servletclass>br.com.caelum.servlet.OiMundo</servletclass>
</servlet>
<servletmapping>
<servletname>servletDeTeste</servletname>
<urlpattern>/oi</urlpattern>
</servletmapping>
3)Testeaurlhttp://localhost:8080/jspteste/oi
Captulo10ServletsPgina75
2)Digitarerradoonomedopacotedasuaservlet:
<servletclass>br.caelum.servlet.OiMundo</servletclass>
3)Esquecerdecolocaronomedaclassenomapeamentodaservlet:
<servletclass>br.com.caelum.servlet</servletclass>
Captulo10ServletsPgina76
INIT
voidinit(ServletConfigconfig);
DESTROY
Nafinalizao,quandoosrecursosdevemserliberados:
voiddestroy();
Omtodoinitedestroy,quandoreescritos,soobrigadosachamarosuper.init()e
super.destroy() respectivamente. Isso acontece pois um mtodo diferente de um
construtor, quando estendemos uma classe e criamos o nosso prprio construtor da
classe filha, ela chama o construtor da classe pai sem argumentos, preservando a
garantiadachamadadeumconstrutor.
Supondoqueomtodoinit(oudestroy)executaalgumatarefafundamentalemsuaclasse
pai,sevocesquecerdechamarosuperterproblemas.
Oexemploaseguirmostraumaservletimplementandoosmtododeinicializaoe
finalizao.
Osmtodosinitedestroypodemserbemsimples(lembresequesoopcionais):
Captulo10ServletsPgina77
//mtodoserviceaqui
}
Outraopoqueoweb.xmlnosdademarcaraservletparainicializaojuntocoma
aplicaoweb.Paraistobastausarumatagchamada load-on-startup eatribuirumvalor
nonegativo.
<servlet>
<servletname>servletDeTeste</servletname>
<servletclass>br.com.caelum.servlet.OiMundo</servletclass>
<loadonstartup>1</loadonstartup>
</servlet>
RecursoAvanado:loadonstartup
As servlets marcadas com nmeros menores sero inicializadas antes que as de nmeros
maiores.Servletsmarcadascomomesmonmeronopossuemumaordemdeinicializaoque
sejadefinidapelaespecificao.
Pararetornaralgoaocliente,podemosusaraOutputStreamouoPrintWriterque
retornadoatravsdoobjetoresponse.
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.
Internethttp
cliente
ServletContiner
1.GET
2.Formemensagens
3.POST
Servlet
Novamensagem
4.Formemensagens
tempo
No mtodo get comum ter uma url que termine com ?parametro=valor
enquantonomtodopostpodemosenviartodososparmetrosatravsdeumformulrioou
simplesmenteescondidosdaurl.
Independentedomtodochamado,osvaloresdosparmetrospodemserlidoscomo
seguintecdigo,quelovalordaidade:
request.getParameter("idade");
Sendoassim,aservletaseguirrecebeumparmetrochamadoidadeeoimprimecomo
resposta:
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
//recebeowriter
PrintWriterwriter=response.getWriter();
//escreveotexto
writer.println("<html>");
writer.println("Caelumexplicaoparametro:"+
request.getParameter(idade));
writer.println("</html>");
}
OmtodogetParameterretornaumaString,portantotodotipodetratamentodeveser
Captulo10ServletsPgina79
feito manualmente. Caso o parmetro no tenha sido passado pela requisio esse mtodo
retornanull.
Paraenviartaisdadospodemosutilizarumlinkcomparmetroatravsdeumarequisio
dotipoget,ouumformulriocomcamposdetexto(mtodogetoupost).
Reparequeemumarquivojsp,asvariveisrequesteresponsetambmexistem,portanto
vocpodeescreveromesmocdigodorequest.getParameterdentrodeumjsp.Fazsentido
fazerisso?Scriptlet?Lerparmetroemjsp?Cdigojavanomeiodocdigohtml?
10.10 - Exerccios
1)CrieaservletTestaParametrosnomesmopacote.
2)EstendaHttpServlet.UtilizeoCTRL+SHIFT+OparaimportarHttpServlet.
3)Escrevaocdigodomtodoservice.
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException{
//recebeowriter
PrintWriterwriter=response.getWriter();
//escreveotexto
Captulo10ServletsPgina80
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
service
init
doGet
doPost
doPut
doDelete
destro
ServletContiner
tempo
Uma das boas prticas de programao com servlets diz que devemos implementar
sempreomtodoserviceenoumdosmtodoscomodoGet,doPost,doHeaderetc.
//recebeowriter
PrintWriterwriter=response.getWriter();
//escreveotexto
writer.println("<html>");
intidade=Integer.parseInt(request.getParameter(idade));
writer.println("Caelumexplicaoparametro:"+
idade);
writer.println("</html>");
}
}
10.14 - Exerccios
1)CrieaclasseTestaConversaoParametrosnopacotecerto.
Captulo10ServletsPgina84
2)Escrevaocdigoquevimosanteriormente:
packagebr.com.caelum.servlet;
//faaimportsaqui,useCTRL+SHIFT+O
publicclassTestaConversaoParametrosextendsHttpServlet{
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException{
//recebeowriter
PrintWriterwriter=response.getWriter();
//escreveotexto
writer.println("<html>");
intidade=Integer.parseInt(request.getParameter(idade));
writer.println("Caelumexplicaoparametro:"+
idade);
writer.println("</html>");
}
}
<servlet>
<servletname>conversor</servletname>
<servletclass>br.com.caelum.servlet.TestaConversaoParametros
</servletclass>
</servlet>
<servletmapping>
<servletname>conversor</servletname>
<urlpattern>/conversoridade</urlpattern>
</servletmapping>
4)Crieumarquivochamadoconverteidade.jsp
<html><body>
<formaction="/jspteste/conversoridade"method="POST">
<inputtype="text"name="idade"value="32"/>
<inputtype="submit"value="Enviar"/>
</form>
</body></html>
5)Testeaurlhttp://localhost:8080/jspteste/converteidade.jsp
6)Oqueaconteceaopassarumnmeroinvlido?
a)Umexemplodenmeroinvlido:
membrodeumaservlet.
Damaneiraqueestamostrabalhando,aespecificaodaservletgarantequesexistir
umainstnciadessaservletpormquina,portantosomenteumainstncianototalanoserque
vocrodesuaaplicaoemumcluster.
Baseadonessefatovamoscriar umavarivelmembrochamadacontadorparafixara
idiadequesomenteumainstnciadessaservletexistirnamemriaequeelasobrevivea
requisies:suasvariveismembronosolimpadasapsotrminodasrequisies.
Escolhendoumavariveldotipointparanossocontador,nossaservletdeve:
a)estenderHttpServlet
b)conterumavarivelmembrodotipoint,chamadacontador
c)acadarequisiosomarumnocontadoreimprimironmerodovisitante
E,apartirdostrspontosacima,devemostestarasnossasurlsdiversasvezes,fecharo
browseretentarnovamenteetc.
Baseandosenonossoprimeiroexemplovejamosomtodoservice:
protectedvoidservice(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException{
contador++;//algumproblemaaqui?
//recebeowriter
PrintWriterout=response.getWriter();
//escreveotexto
out.println("<html>");
out.println("Caelumexplica:"+contador+visita.");
out.println("</html>");
}
10.17 - Exerccios
1)CrieaservletContadornopacotecorreto.EscolhaomenuFile,New,Class.
Captulo10ServletsPgina87
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
//escreveotexto
out.println("<html>");
out.println("Caelumexplica:"+contador+visita.");
out.println("</html>");
}
2)Abraoarquivoweb.xmlemapeieaurl/contaparaaservletContador.
<servlet>
<servletname>nossoContador</servletname>
<servletclass>br.com.caelum.servlet.Contador</servletclass>
</servlet>
<servletmapping>
<servletname>nossoContador</servletname>
<urlpattern>/conta</urlpattern>
</servletmapping>
3)Testeaurlaseguirduasvezeshttp://localhost:8080/jspteste/conta
4)Passadoalgumtempo,fecheobrowser.Abranovamente.Lembresequeobrowser
oclientequenomandouemnenhummomentooserverexecutarumdestroyemsuaservlet...
portantoaservletaindaestlviva:acesseamesmaurl.Qualoresultado?
Servletseconcorrncia
SINGLETHREA
DMODEL
Muitosprogramadoresquecomeamausarservletsacabamesquecendodosproblemasquea
concorrnciagera....membrosdeumaclassequerepresenteumaservletdevemsertratadoscom
muitocuidadoparaevitarsituaesondeaperdadedadosirocorrer.
ImplementarainterfaceSingleThreadModelnaservletumasadaaltamentedesaconselhada,
Captulo10ServletsPgina89
uma vez que poder perder a grande vantagem das servlets de processarem mais de uma
requisioaomesmotempo.
Apartirdaverso2.4daapideservlets,ainterfaceSingleThreadModelfoidepreciada,isto,
nodeveserutilizada.
Portanto, jamais utilize variveis membros em uma servlet, use argumentos de mtodos para
passarvaloresentreosmesmos.
Internethttp
cliente
ServletContiner
1.Primeiravez
Jsp
Compiler
3.Segundavez
tempo
Cria
umaservlet
servlet
Vantagens
Obenefciomaisclaronocolocarumasrieimensadecdigohtmldentrodeumaclasseem
java,oquedificultamuitoaalteraodapginaporumdesigner.Compareocdigodalistagemdo
OiMundocomoservlet.Muitomaissimplesdeeditarohtml:masodesignernocompreendeo
cdigoJava.
DuascoisasqueajudamacombateresseproblemasoosJavaBeansepadresdearquitetura
variadosexistentesnomercado.
Captulo10ServletsPgina90
JSP:ficamaisfcilparaodesigneralterarocdigohtml
Servlets:ficamaisfcildeprogramarorientadoaobjetoseemJava
Oprocessopadrodedeploy(envio,submisso)deumaaplicaowebodecriarum
arquivodeextensowar,queumarquivozipcomodiretriobasedaaplicaosendoaraiz
dozip.
Nonossoexemplo,todoocontedododiretriowebdeveriaserincludoemumarquivo
teste.war. Aps compactar o diretrio web com esse nome, iremos efetuar o deploy.
No tomcat, basta copiar o arquivo .war no diretrio TOMCAT/webapps/ e ele ser
descompactado,porfimonovocontextochamadotesteestardisponvel.
10.21 - Exerccios
1)Entrenofilebrowser.
2)Entrenodiretrioworkspace,jspteste,web.
Captulo10ServletsPgina91
4)Selecioneoseuarquivoteste.war,vnomenuEditeescolhaCut.
Captulo10ServletsPgina92
6)Coleoseuarquivoaqui(Edit,Paste).Reparequeodiretriotestefoicriado.
Captulo10ServletsPgina93
ServletException
SQLException
OqueacontecequandooservletcontinerpegaumaServletException?
Primeiroeleverificaseexistiualgumacausa(rootcause)paraessaexception,sesim,ele
usaessacausaparaprocuraromapeamentonoweb.xml.Senoexistirnenhumacausaele
procuraServletExceptionnoarquivoweb.xml.
Portantonocasoquedefinimosacima,oservletcontinerprocuraromapeamentode
SQLExceptione,repare,jfizemosissonoexemplodojsp!
Nofinalocontroledeerrocentralizadonoservletcontinerajudamuitopoisbastamapear
umaoumaispginasdeerronoweb.xmlepronto,todoerrodessetipo,sejaemjspsouservlets,
serredirecionadoparanossapginadeerro.
10.24 - Exerccios
1)Crieumaservletparatestarocontroledeexceptions:
a)Pacote:br.com.caelum.servlet,classeTestaErro
b)EstendaHttpServlet
Captulo10ServletsPgina95
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.
muitoimportanteapartirdeagora queoalunopercebasercapazdeadicionarum
contatonobancodedadosutilizandotudooquevimosatomomento.
Imagineummtodoservicequerecebetrsparmetros:nome,emaileendereo.
Sendoextremamentelgicosbasta:
lerosparmetrosepreencherumobjetodotipoContato
instanciarContatoDAOeadicionartalobjetonobanco
mostrarumamensagemdeokparaocliente
Portantovamosaoexerccio...
10.26 - Exerccio
1)CrieumaservletchamadaAdicionaContatoServletnopacotebr.com.caelum.servlet
2)NoseesqueadeextenderaclasseHttpServlet.
publicclassAdicionaContatoServletextendsHttpServlet{
3)Coloqueomtodoservice.
protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
Captulo10ServletsPgina97
4)UseCTRL+SHIFT+Oparafazerosimportsnecessrios.
5)CrieumobjetodotipoContato,chameodecontato.
Contatocontato=newContato();
6)Atravsdavarivelrequestleiaoparmetronomeeuseseuvalorparachamaro
setterdocontato.Faaomesmoparaoscamposemaileendereo.
Stringnome=request.getParameter(nome);
Stringendereco=request.getParameter(endereco);
Stringemail=request.getParameter(email);
contato.setNome(nome);
contato.setEndereco(endereco);
contato.setEmail(email);
7)CrieumobjetodotipoContatoDao,chameodedaoeutilizeasvariveiscontatoedao
paraadicionarocontatoaobancodedados.
try{
ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);
}catch(SQLExceptione){
thrownewServletException(e);
}
9)Atravsdoresponse.getWriter()mostreumamensagemdeokparaocliente.
PrintWriterwriter=response.getWriter();
writer.println("<html>");
writer.println("ContatoAdicionado");
writer.println("</html>");
10)MapeieaclasseAdicionaContatoServletnoweb.xml.
<servlet>
<servletname>adicionaContato</servletname>
<servletclass>br.com.caelum.servlet.AdicionaContatoServlet</servletclass>
</servlet>
<servletmapping>
<servletname>adicionaContato</servletname>
<urlpattern>/testaadiciona</urlpattern>
</servletmapping>
11)Faaumarquivotestaadicionacontato.jsp.
<html><body>
Digiteseusdadosepressioneoboto:<br/>
<formaction="testaadiciona"method="POST">
Nome: <inputtype="text"name="nome"/><br/>
Email:
<inputtype="text"name="email"/><br/>
Endereo:
<inputtype="text"name="endereco"/><br/>
<inputtype="submit"value="Enviar"/>
</form>
</body></html>
<html>
12)Testeaurlhttp://localhost:8080/jspteste/testaadicionacontato.jsp
Captulo10ServletsPgina98
Captulo10ServletsPgina99
captulo
11
11
NestecaptulovociraprenderautilizaroutrosrecursosavanadosdaAPIdeservlets.
AapideservletsdisponibilizaumainterfacechamadaServletContextListenercapazde
recebernotificaesdessesdoiseventos.
Aoimplementartalinterface,precisamosescreverdoismtodos,umparainicializaoe
outroparaadestruiodenossaaplicao(quetambmserchamadoservletcontext,contexto
deservletsouainda,escopodeaplicao).
publicvoidcontextDestroyed(ServletContextEventevent){
//...
}
publicvoidcontextInitialized(ServletContextEventevent){
//...
}
Podemos,porexemplo,manteremumavarivelomomentodeinicializaodanossa
aplicao:
Dateinicializacao=newDate();
ESCOPO DE
APLICAO
Mascomoveresseresultadoatravsdeumaservlet?Precisamoscolocaresseobjetoem
algumescopoquesejaomesmoparatodososusuriosetodasasservlets,issoexiste?Sim:o
escopodeaplicao.
SERVLETCONTE
XT
ServletContextcontext=event.getServletContext();
Utilizamostalescopocomoummapa(apalavramapadosfsicos,querdizerquepara
cadachavetemumvalorassociado,nsusamosnormalmenteapalavradicionrio,mascomo
emjavausaapalavramaptraduzimosparamapa)portantodefinimosumachavequalquerpara
nossoobjeto,porexemplo:br.com.caelum.inicializacaoeutilizamosomtodosetAttributepara
atribuiroobjetoreferenciadopelavarivelinicializaoparatalchave:
Dateinicializacao=newDate();
ServletContextcontext=event.getServletContext();
context.setAttribute("inicializacao",inicializacao);
Captulo11ServleteJSPAPIPgina100
LISTENER
Falta ainda configurar nossa aplicao para procurar por tal Listener e registralo
devidamente. Como isso na realidade uma configurao, iremos cadastrar um listener no
nossoweb.xml:
<listener>
<listenerclass>br.com.caelum.servlet.ControleDeAplicacao</listenerclass>
</listener>
11.2 - Exerccios
1)Crieaclasse ControleDeAplicacao nopacotebr.com.caelum.servlet.Escolhao
menuFile,New,Class.
a)ImplementeServletContextListener.
publicclassControleDeAplicacaoimplementsServletContextListener{
}
b)UtilizeoCTRL+SHIFT+O
c)ResolvaosproblemasqueocompiladorreclamautilizandooCTRL+1nalinhadoerro:
implementeosdoismetodos:.
publicvoidcontextDestroyed(ServletContextEventevent){
}
publicvoidcontextInitialized(ServletContextEventevent){
Dateinicializacao=newDate();
ServletContextcontext=event.getServletContext();
context.setAttribute("inicializacao",inicializacao);
}
2)Abraoarquivoweb.xmlemapeieoseulistener.
<listener>
<listenerclass>br.com.caelum.servlet.ControleDeAplicacao</listenerclass>
</listener>
11.3 - getServletContext()
TodaservletpossuiummtodochamadogetServletContextqueretornaumareferncia
Captulo11ServleteJSPAPIPgina101
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/>
Comojvimosanteriormente, ocdigodotiposcriptletpodesermalficoparanossa
aplicao,sendoassimvamosutilizarexpressionlanguageparaacessarumatributodoescopo
aplicao:
AcessandocomEL:${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.
OidealentoqueaServletfaaotrabalhosujoerduo,eoJSPapenasapresente
essesresultados.AServlet possui a lgica de negcios(ouregrasdenegcio)eoJSP
tem a lgica de apresentao.
ImagineocdigodomtododaservletAdicionaContatoServlet:
protectedvoidservice(
HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
//log
System.out.println("Tentandocriarumnovocontato...");
//acessaobean
Contatocontato=newContato();
//chamaossetters
...
//adicionaaobancodedados
ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);
//ok....visualizao
request.getWriter().println("<html>Ok</html>");
}
Reparequenofinaldonossomtodomisturamosocdigohtml,portantooquequeremos
extrairdocdigoacimajustamenteessaltimalinha.
Seriamuitomaisinteressanteparaoprogramadoreparaodesignerterumarquivojsp
chamadocontatoadicionado.jspcomohtml:
<html>
Captulo12ModelViewControllerPgina105
Aferramentaquebuscamosumredirecionadorderequisies,capazdeenviaruma
requisioparaumnovorecursodoservidor:umjsp,umaservlet,umaimagemetc.
REQUEST
DISPATCHER
Podemos usar o recurso de dispatch das requisies para que o JSP s seja
chamadodepoisdequesuasregrasforamexecutadas.
Cliente
servlet
JSP
servlet
JSP
BD
Pega um
(select)
usurio
Agorapodemosfacilmenteexecutaralgicadenossaaplicaowebemumaservlete
entoredirecionarparaumapginajsp,ondevocpossuiseucdigohtml.
Forwardeinclude
Omtodoforwardspodeserchamadoquandonadaforaescritoparaasada.Nomomentoque
algoforescritoficaimpossvelredirecionarousuriopoisoprotocolohttpnopossuimeiosde
voltaratrsnaquiloquejfoienviadoaocliente.
ExisteoutromtododaclasseRequestDispatcherquerepresentaainclusodepginaenoo
redirecionamento.Essemtodosechamaincludeepodeserchamadoaqualquerinstantepara
acrescentaraoresultadodeumapginaosdadosdeoutra.
Captulo12ModelViewControllerPgina106
Apesardosdoismtodospareceremteiselesnocostumamserusadosanosernapartede
controladordeumaaplicaowebutilizandoopadromvc.
12.3 - Exerccio
1) Altere sua servlet AdicionaContatoServlet para que aps a execuo da lgica de
negcios,ofluxodarequisiosejaredirecionadoparaumjspchamadocontatoadicionado.jsp:
a)Substituaaslinhas:
PrintWriterwriter=response.getWriter();
writer.println("<html>");
writer.println("ContatoAdicionado");
writer.println("</html>");
por:
RequestDispatcherrd=request.getRequestDispatcher(/contatoadicionado.jsp);
rd.forward(request,response);
return;
b)Faaoarquivocontatoadicionado.jsp.
<html>
ContatoAdicionado
</html>
2)Testeaurl:http://localhost:8080/jspteste/testaadicionacontato.jsp
12.4 - Resultado
Percebaquejatingimosumresultadoquenoerapossvelanteriormente.
MuitosprojetosantigosqueforamescritosemJava,utilizavamsomentejspouservletseo
resultadoeraassustador.Comocontedomostradoatessemomento,possvelescreverum
cdigocommuitomaisqualidadedoqueessesprojetos.
Captulo12ModelViewControllerPgina107
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
}
Paracadaaoteramosumif/elseif,ficariagiganteno?
Podemosmelhorarfazendorefactoringdeextrairmtodos.Mascontinuariagigante.
Seria melhor colocar cada regra de negcio (como inserir aluno, remover aluno, fazer
relatriodeumaluno,etc...)emumaclasseseparada.Cadaao(regradenegcio)emnossa
aplicaoestariaemumaclasse.
Entovamosextrairclasses:
if(businessLogic.equals("AdicionaContato")){
newAdicionaContato().execute(request,response);
}elseif(businessLogic.equals("ListaContato")){
newListaContatos().execute(request,response);
}
Pormacadalgicanova,lgicaremovida,alteraoetc,temosquealteraressaservlet.
Issotrabalhosoemuitopropensoaerroshumanos.
Reparequeocdigoacimaumswitch!EswitchemJavatoruimquesubstitumos
porpolimorfismo,comoveremosaseguir.
Vamostentargeneralizarento,queremosexecutaroseguintecdigo:
Stringbusiness=request.getParameter(business);
newbusiness().execute(request,response);
Entretantonopodemos,poisbusinessonomedeumavarivel.Onossoproblema
quessabemosoquevamosinstanciaremtempodeexecuoenoemtempodecompilao.
Temoscomofazerisso?Sim.
StringbusinessLogicClassName=br.com.caelum.mvc.+
request.getParameter("business");
ClassbusinessLogicClass=Class.forName(businessLogicClassName);
Maseagoracomoinstanciaressaclasse?
Objectobj=businessLogicClass.newInstance();
Ecomochamaromtodoexecute?Reparequeusamosomesmomtodoemtodasas
lgicasdenegcio:issoumpadroquedefinimos.Quandoissoaparece,normalextrairuma
Captulo12ModelViewControllerPgina109
interfacecomumatodasessasclasses:BusinessLogic.
BusinessLogicbusinessLogicObject=
(BusinessLogic)businessLogicClass.newInstance();
businessLogicObject.execute(request,response);
Algumprecisacontrolarentoqueaoserexecutadaparacadarequisio,equeJSP
ser utilizado. Podemos usar uma servlet para isso, e ento ela passa a ser a servlet
controladoradanossaaplicao,chamandoaaocorretaefazendoodispatchparaoJSP
desejado.
Reparenafiguraaseguirque,apesardosJSPsnoestaremacessandoapartedasua
modelagem,isto,asclassesquediretaouindiretamentemexemnobancodedados,eletem
uma referncia a um Usurio, para poder colocar suas informaes na pgina resultante.
Chamamosissodepushdasinformaes.
Cliente
controladora
JSP
JSP
Usurio
Referncia ao us
urio X
BD
JSP
Ao de pegar info
de um usurio
Formulrio
para
ver info do usurio
Captulo12ModelViewControllerPgina110
captulo
13
13
NoexistemistrioportrsdeumframeworkMVC.VamoscriaraquioSYPMVCFrameworkSimple
YetPorwerfulMVCFramework.
Pareceumaservletcerto?Aprimeiravistasim,maspercebaquenotemnadacomuma
servlet.EstendeServlet?Possuimtodochamadoservice?No.
Vamoscriarumalgicadenegciodeexemploparatestlaembreve:
publicclassTestaMVCimplementsBusinessLogic{
publicvoidexecute(HttpServletRequestreq,HttpServletResponseres)
throwsException{
System.out.println(Executandoalogicaeredirecionando...);
RequestDispatcherrd=req.getRequestDispatcher("/testamvc.jsp");
rd.forward(req,res);
}
}
13.2 - Exerccios
1)Crieasuainterfacenopacotebr.com.caelum.mvc:
publicinterfaceBusinessLogic{
voidexecute(HttpServletRequestreq,HttpServletResponseres)throwsException;
}
publicvoidexecute(HttpServletRequestreq,HttpServletResponseres)
throwsException{
System.out.println(Executandoalogicaeredirecionando...);
RequestDispatcherrd=req.getRequestDispatcher("/testamvc.jsp");
rd.forward(req,res);
}
}
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);
}
Captulo13ConstruindoumFrameworkMVCPgina112
Eassimterminaonossocontrolador,queagoradelegouaresponsabilidadedeexecuo
paraanossalgicadenegcios.
Ocdigocompletocomtodootratamentodeerroficabemgrande,porissousaremos
algosimplificadonoexerccio.
publicclassControllerServletextendsHttpServlet{
publicvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
StringbusinessLogicClassName=request.getParameter("business");
ClassbusinessLogicClass=null;
try{
businessLogicClass=Class.forName(businessLogicClassName);
}catch(ClassNotFoundExceptione){
thrownewServletException("Noencontroaclasse"+
businessLogicClassName);
}
if(!BusinessLogic.class.isAssignableFrom(businessLogicClass)){
thrownewServletException("classenoimplementaainterface:"
+businessLogicClassName);
}
BusinessLogicbusinessLogicObject=null;
try{
businessLogicObject=(BusinessLogic)businessLogicClass.newInstance();
}
catch(InstantiationExceptione){
thrownewServletException(e);
}
catch(IllegalAccessExceptione){
Captulo13ConstruindoumFrameworkMVCPgina113
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
<servlet>
<servletname>syp</servletname>
<servletclass>br.com.caelum.mvc.ControllerServlet</servletclass>
</servlet>
<servletmapping>
<servletname>syp</servletname>
<urlpattern>/mvc</urlpattern>
</servletmapping>
3)Faaumarquivojspchamadomvcok.jsp
<html>
<h1>MVCOK</h1>
</html>
4)Testeaurlhttp://localhost:8080/jspteste/mvc?business=TestaMVC
13.6 - Exerccios
Captulo13ConstruindoumFrameworkMVCPgina115
//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.Quemresponsvelporapresentarosresultadosnapginawebchamadode
Apresentao(View).
CONTROLLER
Aservlet(eauxiliares)quefazosdispatchsparaquemdeveexecutardeterminadatarefa
chamadadeControladora(Controller).
MODEL
Asclassesquerepresentamsuasentidades,easqueteajudamaarmazenarebuscaros
dados,sochamadasdeModelo(Model)
MVC
Captulo13ConstruindoumFrameworkMVCPgina117
Cliente
View
Controller
JSP
JSP
Model
JSP
BD
umpoucosobrecadaumadelas:
1.JSP:comojvimosoJavaServerPages,temosumaboaidiadoqueele,suas
vantagensedesvantagens.Ousodetaglibs(aJSTLporexemplo)eexpressionlanguage
muitoimportantesevocescolherJSPparaoseuprojeto.aescolhadomercadohojeemdia.
2.Velocity:umprojetoantigo,noqualaELdojspsebaseou,capazdefazertudooque
vocprecisaparaasuapginadeumamaneiraextremamentecompacta.IndicadopelaCaelum
paraconhecerumpoucomaissobreoutrasopesparacamadadevisualizao.
3. Freemarker: similar ao Velocity e com idias do JSP como suporte a taglibs o
freemarkervemsendocadavezmaisutilizado.
4.Sitemesh:noumaaltenativaparaasferramentasanterioresmassimumamaneira
de criar templates para seu site, com uma idia muito parecida com o struts tiles, porm
genrica:funcionainclusivecomoutraslinguagenscomophpetc.
Empequenasequipesimportanteumaconversaparamostrarexemplosdecadauma
dastecnologiasacimaparaodesigner,afinalquemirtrabalharcomaspginasele.Aqueele
preferirvocusa,afinaltodaselasfazemamesmacoisademaneirasdiferentes.Comoemum
projetocomumterpoucosdesigneremuitosprogramadores,talvezsejaproveitosofacilitarum
poucootrabalhoparaeles.
13.11 - MVC 2
ProntoparaaprenderoqueoMVC2?Preparese...
O MVC 2 nada mais que uma genial confuso generalizada. O Model1 o antigo
padroqueosblueprints(boasprticas)dojeedasunindicavaparaousodejsp'sejavabeans.
DepoissurgiuoMVC(idiaemprestadadoSmalltalk),quefoilogochamadodemodelo2...
MVC,Modelo2,Modelo2,MVC,algumaspessoasacabamfalandoMVC2.
Noseengane,MVC2,MVCeModelo2tudoamesmacoisa:Model,View,Controller.
Captulo13ConstruindoumFrameworkMVCPgina119
captulo
14
14
Jakarta Struts
A qualidade a quantidade de amanh
HenriBergson
Aotrminodessecaptulo,vocsercapazde:
utilizarostrutsparacontrolarsualgicadenegcios
criaratalhosparasuacamadadevisualizao
criareconfigurarmapeamentosdeaesetemplates
utilizarformbeansparafacilitaraleituradeformulrios
validarseuformulriodeformasimples
controlaroserrosdevalidaodomesmo
14.1 - Struts
STRUTS
MVC
StrutsumframeworkdogrupoJakartaqueservecomoocontroller de uma
arquitetura MVC.ApesardetersuporteparaqualquertipodeServlets,focadonouso
deHttpServlets.
Naverso1.2,oStrutssuportanosJSP,pormsuaintegraocomframeworkscomo
oVelocityrequerplugins(comooVelocityToolsporexemplo).
Suadocumentaoe.jarpodemserencontradosem:
http://struts.apache.org
Paraleressecaptulo,importantequevocjtenhalidoocaptulosobreModelView
Controller.
14.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
</webapp>
4) Cliquedadireitanonomedoseuprojeto,escolhaTomcat,Updatecontextdefinition
paraqueeleatualizeotomcat.
5)Cliquedadireitanonomedoseuprojeto,escolhaproperties.NaabaAmateras,altere
odiretriopara/web,conformefizemosnoprojetodetestedejsps.
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
seusistemanoestconfiguradoparaquelisteosarquivosdosdiretrios.Senoseucasofoi
porquenoestconfiguradoalistagemumbomsinal,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.
MESSAGE
RESOURCES
Esseoprocessoondecentralizamostodasasmensagensdosistemaemum(oumais)
arquivosdeconfiguraoquesobaseadosnaantigaidiadechavevalor,umdicionriode
mensagens.Porexemplo:
menu.nome=Menuprincipal
menu.arquivo=Arquivo
menu.editar=Editar
menu.sair=Sair
site.titulo=SistemadetestedoStruts
Paraconfigurarostrutseusarumtipodearquivocomoesse,comeamosindicandoqual
o arquivo de configurao que usaremos. O nome mais comum
MessageResources.properties.Essearquivodevesercriadononossodiretriosrc.
ParaoStrutslertalarquivobastaconfigurlonostrutsconfig.xml,localizadonodiretrio
WEBINF:
<strutsconfig>
<!ArquivodeMensagens>
<messageresourcesparameter="MessageResources"/>
</strutsconfig>
Para utilizar tal arquivo bem simples, basta no nosso jsp usar uma taglib do struts
chamadabean:
<%@tagliburi="http://struts.apache.org/tagsbean"prefix="bean"%>
BEAN:MESSA
GE
<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>
4)Reinicieotomcat.Sersemprenecessriofazerissoaoalterarseuarquivostruts
config.xml.
5)Testeaurlhttp://localhost:8080/struts/testamensagens.jsp
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:
Captulo14JakartaStrutsPgina129
Vocdevereescreveromtodoexecute,comonoexemploabaixo:
packagebr.com.caelum.struts.action;
//imports....
publicclassTesteSimplesActionextendsAction{
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
//...
}
}
Porenquantotemosquatroparmetros,doisquejconhecemos,eumretorno.Essestrs
itensseroexplicadosembreve,passoapassoparaevitarcomplicaesumavezquenesse
pontoqueosprogramadoressentemumacertadificuldadeinicialcomoStruts.
Primeiro,precisamosdevolverumobjetodotipoActionForward,queindicaparaondeo
usuriodeveserredirecionadoaotrminodaexecuodaquelaao.Podeserparaoutraao,
ou,normalmente,paraum.jsp.
Captulo14JakartaStrutsPgina130
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
Asvezesinteressantecriarumapelidoparaumapginajsp.Paraisso,umadasalternativas
criarumaaoqueemvezdepossuirumtype,possuiumatributochamadoforward:
<actionpath=/apelidoforward=/minha_pagina.jsp/>
Noexemploacima,comumnomercado,aurlqueterminacom/apelido.doserredirecionadapara
apginajspdentrododiretrioWEBINF/jsp.
GlobalForwards
O Struts permite configurar no strutsconfig.xml uma lista de forwards globais que podem ser
utilizadosportodasasaes.Paraisso,bastaadicionaratagglobalforwardsantesdosaction
mappings.
<globalforwards>
<forwardname=exceptionpath=/error.jsp/>
</globalforwards>
Sevoc quisercontrolaroserrosatravsdesse forward,bastausaralgosimilaraocdigoa
seguir:
catch(Exceptione){
returnmap.findForward(exception);
}
14.9 - Exerccios
1)CriesuaprimeiraaodoStruts.
a)CrieumaclassechamadaTesteSimplesActionnopacotebr.com.caelum.struts.action.
Captulo14JakartaStrutsPgina132
b)FaasuaclasseestenderAction(doStruts!).
c)UtilizeCTRL+SHIFT+Oparaimportaraclasse.
d)Escrevaomtodoexecuteeimplementeomesmo,retornandooresultadoexemplo.
@Override
publicActionForwardexecute(ActionMappingmap,ActionFormform,HttpServletRequest
request,HttpServletResponseresponse)throwsException{
System.out.println("Executandoocdigodalgicadenegcios...");
returnmap.findForward(ok);
}
2)Crieseuarquivoexemplo.jspdentrododiretrioweb.
<html>
MinhaprimeirapginausandooStruts!
</html>
4)ReinicieoTomcat.
5)TesteaURLhttp://localhost:8080/struts/teste.do
Captulo14JakartaStrutsPgina133
Reloadautomticodostrutsconfig.xml
OStrutsnofazoreloadautomticodoarquivostrutsconfig.xml.
Umtruqueparafazerissofuncionar(questilduranteodesenvolvimentodasuaaplicao)
colocaressearquivonoseudiretriosrc,portantoserjogadonodiretrioclasses,oclasspath.
Jnoseuarquivoweb.xmlconfigureostrutscomumparmetrodeinicializaodeservletparaler
oarquivodentrododiretrioclasses(/WEBINF/classes/strutsconfig.xml):
<initparam>
<paramname>config</paramname>
<paramvalue>/WEBINF/classes/strutsconfig.xml</paramvalue>
</initparam>
Agoratodavezqueoarquivoforalterado,oTomcatpercebeumamudananoclasspathdoprojeto
ereiniciaasuaaplicaoweb.
Cuidado pois essa funcionalidade de reinicializao de contextos nem sempre pode funcionar
como voc espera. Um caso simples iniciar threads separadas e deixlas rodando no
background,oqueacontece?
Captulo14JakartaStrutsPgina134
2)Outroerrocomumesquecerdecolocarabarraantesdonomedoredirecionamento.
Todopathdeforwarddevecomearcomumabarra.Sevoccolocarsomenteexemplo.jspo
errodizclaramentequefaltouumabarra:
3)comumerraronomedaclassedesuaaction,comoporexemploesquecero.come
digitarbr.caelum.struts.action.TesteSimplesAction.NessecasooStrutsnoconsegueinstanciar
suaaction:
4)Porltimo,oerrodosesquecidos.Sevocnocriaroarquivojspoucolocarumnome
Captulo14JakartaStrutsPgina135
invlidooerroojconhecido404:
14.12 - Criando a ao
Paracriaraaodelistagembastautilizarmosaidiadecriarumnovoobjetodotipo
DAOechamaromtodolista:
//pesquisanobancodedadosalistacompleta
List<Contato>lista=newContatoDAO().getLista();
Masespereumpouco,esseoexemploquevimosnocomeodaapostila?Ataqui,
semnovidades.Aquestoqueficacomoenviarocontedoreferenciadopelavarivellista
paraapginajspqueseracessadaembreve.
Precisamos de um escopo de varivel que sobreviva ao mtodo execute e continue
duranteoforwarddarequisioatoarquivojsp.Reparequeafraseanteriorentregaasoluo:
oescopodarequisio.
Iremosatrelaro valorreferenciadopelavarivellistaparaumnomequalquerligadaa
requisiodocliente.Essevalorsficarlatotrminodarequisio,temposuficientepara
mostrlonoarquivojsp.
Podemosadicionlacomoatributonorequest,paraquenossapginajsppossareceber
talobjeto.Suponhaquedesejamoschamarnossalistadecontatos:
request.setAttribute("contatos",lista);
Captulo14JakartaStrutsPgina136
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>
Nessemomentovocsepergunta:masojspnodeclarouavarivelcontatos?!Sim,ele
nodeclarou.Aexpressionlanguageirbuscarovalordetalchavenorequest(eemoutros
lugares,queveremosadiantenocurso)eutilizlaparaaiterao,ousejaelenotemligao
diretacomodao,elesabequevemumavarivelcontatos,masnosabedeonde.
Captulo14JakartaStrutsPgina137
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>
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.
type="br.com.caelum.struts.action.ListaContatosAction">
<forwardname="lista"path="/lista.jsp"/>
<forwardname="vazia"path="/listavazia.jsp"/>
</action>
</actionmappings>
<!ArquivodeMensagens>
<messageresourcesparameter="MessageResources"/>
</strutsconfig>
3)Criaromappingdalgicaparaavisualizao
Edepoisospassosopcionais:
4)Criaravalidaodoformulrionalgicadenegcios
5)Criarocontroledeerronavisualizao
14.20 - Formulrio
NuncaeleganteficartrabalhandocomomtodogetParameterdorequest,sendoque
muitomelhortrabalharcomclassesquensmesmosescrevemos.Portantovamosimaginarum
cenriosimples:desejamosadicionaronome,emailedescricodocliente.
ACTIONFORM
OStrutspossuiumaclassechamadaActionFormqueaoserestendidapermiteleros
parmetrosdorequestsemnospreocuparmoscomomesmo!
Sendoassim,noStruts,paracadaformulriohtmlqueexistenonossositecriamosuma
classeemJavapararepresentaroscamposdomesmo.
Nonossocasoprecisamosdoscamposnome,emailedescrio,masopa,issoum
Contato!Resultado:
packagebr.com.caelum.struts.form;
importorg.apache.struts.action.*;
publicclassContatoFormextendsActionForm{
privateContatocontato=newContato();
publicContatogetContato(){
returnthis.contato;
}
}
Ateno:oformulriohtmldeverteroscamposcomomesmonomequeasvariveis
membrodoseuformulrio!
Existe uma opo avanada de fazer o formulrio atravs de xml, no deixa de ser
bastantecdigoeaindacomadesvantagemdenotererrosdecompilao.
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>
//adicionaaobancodedados
Captulo14JakartaStrutsPgina143
14.24 - Exerccio
1)VamoscriaraclasseAdicionaContatoAction
a)CrieaclasseAdicionaContatoActionembr.com.caelum.struts.action
b)FaacomquesuaclasseestendaActiondoStruts.
c)Digiteexecute,CTRL+ESPAOedenter:implementeomtodoexecutelembrando
dealterarosnomesdeseusargumentos:
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
//log
System.out.println("Tentandocriarumnovocontato...");
//formulriodecliente
ContatoFormformulario=((ContatoForm)form);
//acessaobean
Contatocontato=formulario.getContato();
//adicionaaobancodedados
ContatoDAOdao=newContatoDAO();
dao.adiciona(contato);
//ok....visualizao
returnmap.findForward("ok");
}
2)Vamosconfigurarsuaao
a)Definesuaao/novoContatonoarquivostrutsconfig.xmlapontandoparaaclasse
AdicionaContatoAction.
<actionpath="/novoContato"name="ContatoForm"
type="br.com.caelum.struts.action.AdicionaContatoAction">
</action>
b)Emcasodesucesso(ok),redirecioneparao/listaContatos.do(istomesmo,estamos
encadeandoduasaes).
<forwardname="ok"path="/listaContatos.do"/>
3)Crieseuarquivonovo.jsp
<%@tagliburi="http://struts.apache.org/tagshtml"prefix="html"%>
<html:html>
<head><title>SistemadeTestedoStruts</title></head>
<html:errors/>
<html:formaction="/novoContato"focus="contato.nome">
Captulo14JakartaStrutsPgina144
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;
}
Omtododevalidaodoformulrioomtodovalidate.Casoocorraalgumerrode
validao,devemosadicionaroserrosaoobjetoActionErrors.Porexemplo:
publicActionErrorsvalidate(ActionMappingmap,HttpServletRequestreq){
ActionErrorserros=newActionErrors();
if(stringVazia(nome)){
erros.add("nome",newActionMessage("erro.campoNome"));
}
returnerros;
}
Nessecaso,iremosusarapalavraerro.campoNomecomochaveparaamensagemde
erro!Issomesmo,ficamuitomaisfcilcontrolaroquevaiserapresentadoaoseuusuriocomo
mensagemdeerropoisiremosconfigurlonoarquivoMessageResources.properties.
Acrescentando as verificaes dos outros campos, temos o cdigo final do mtodo
validate:
publicActionErrorsvalidate(ActionMappingmap,HttpServletRequestreq){
ActionErrorserros=newActionErrors();
//verificaonome
if(stringVazia(contato.getNome())){
erros.add("nome",newActionMessage("erro.campoNome"));
}
//verificaoemail
if(stringVazia(contato.getEmail())){
erros.add("email",newActionMessage("erro.campoEmail"));
}
//verificaoendereci
if(stringVazia(contato.getEndereco())){
erros.add("endereco",newActionMessage("erro.campoEndereco"));
}
returnerros;
}
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
Portantovocpodecolocarnoseuaction:
scope=session
scope=request
comumutilizaroescopodesessoparamanterosdadosdeumformulrioatravsdediversas
requisies.
14.30 - Exerccios
1)AltereseuContatoFormparautilizaromtodoreseteatagscope:
a)coloqueomtodoresetnoseuContatoForm:
@Override
publicvoidreset(ActionMappingmap,HttpServletRequestreq){
this.contato=newContato();
}
b)configureoescopodoseuformulriopararequest:
<actionpath="/novoContato"name="ContatoForm"input="/novo.jsp"
type="br.com.caelum.struts.action.AdicionaContatoAction"scope=request>
<forwardname="ok"path="/listaContatos.do"/>
</action>
14.31 - Exerccios
1)CrieumformulriochamadoRemoveContatoFormemapeieelenostrutsconfig.xml.
2)CrieumaaochamadaRemoveContatoAction
a)ElarecebeumformulriodotipoRemoveContatoForm
b)Elaremovedobanco(usandooContatoDAO)ocontatocomidigualaodocontatodo
formulario.Algocomo:
Contatocontato=((RemoveContatoForm)form).getContato();
newContatoDAO().remove(contato);
c) Mapeie uma ao no strutsconfig.xml chamada removeContato para sua classe
RemoveContatoAction
d)Redirecionepara/listaContatos.doapsremoverumcontato
e)Nasualista,altereocdigoparaincluirumlinkpararemoo:
<c:forEachvar="contato"items="${contatos}">
${contato.id}${contato.nome}
(<ahref="removeContato.do?contato.id=${contato.id}">remover</a>)<br/>
</c:forEach>
f)Testeasualistagemedepoisremovaalgumcontato.
Captulo14JakartaStrutsPgina149
c)Mapeieessaactionparaopath/mudaLingua.
<actionpath="/mudaLingua"
type="br.com.caelum.struts.action.MudaLinguaAction">
<forwardname="ok"path="/testamensagens.jsp"/>
</action>
d)Altereseuarquivotestamensagens.jspparaadicionardoislinksparaaaodealterar
alngua:
<ahref="mudaLingua.do?lingua=en">EN</a>|
<ahref="mudaLingua.do?lingua=pt">PT</a><br/>
e)CrieoarquivoMessageResources_en.propertiesnoseudiretriosrc.
site.titulo=StrutsTest
pergunta.usuario=Whatisyourusername?
pergunta.senha=Whatisyourpassword?
pergunta.enviar=Senddata
#comentariodeumarquivo.properties
menu.nome=Menuname
menu.arquivo=Choosefile
menu.editar=Editfile
menu.sair=Quit
f)ReinicieoTomcat.
g)Testeaurlhttp://localhost:8080/struts/testamensagens.jsp:
Ositeapareceporpadronalnguaqueoseubrowserpediu,quealnguaconfigurada
noseussistemaoperacional.
h)Escolhaolinkparaportugus:
Captulo14JakartaStrutsPgina150
i)Escolhaolinkparaingls:
OdiagramaaseguirrepresentaoqueaconteceaoalteraroLocale:
Captulo14JakartaStrutsPgina151
2)Vamosmostraragoraosdetalhesdeumcontato.
a)CrieaclasseMostraContatoFormsimilaraoContatoForm.
b)CrieumaaochamadaMostraContatoAction
c)Elachamaomtodoprocura:
Contatocontato=((MostraContatoForm)form).getContato();
Contatoencontrado=newContatoDAO().procura(contato.getId());
request.setAttribute("contato",encontrado);
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
UmdospatternsmaissimplesefamososqueoStrutsconstruiuoAlwaysLinkToActions.Voc
sempredevesereferenciarasaesdoStrutsenuncaassuaspginasjspdiretamente.Sevoc
jescondesuaspginasjspnodiretrioWEBINF,estseobrigandoautilizartalprocedimento.
Qualavantagem?
Seemalgumdiasuapginajspprecisaexecutarumalgicaantesdeserchamadaouseeladeve
ser renomeada, basta alterar o arquivo strutsconfig.xml, caso contrrio voc deveria procurar
todososlinksemsuaaplicao!
Captulo14JakartaStrutsPgina153
captulo
15
Jakarta Struts
15
Aotrminodessecaptulo,vocsercapazde:
utilizarsessesemservlets;
desenvolverumsistemadelogin.
this.funcionario=newFuncionario();
}
}
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?Jvimosqueissomuitochatoeexisteuma
grandechancedeerro.
PodemosentousarnossoFormBeanechamarapenasgetterselegantemente,usandoo
conceitoqueaprendemosnoltimocaptulo.
packagebr.com.caelum.struts.action;
//importsaquiCRTL+SHIFT+O
/**
*@authorCaelum
*/
publicclassLoginActionextendsAction{
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
System.out.println("Algumusurioesttentandoselogar...");
//1.ondeestoasvariveis?Olhaqueelegncia
LoginFormformulario=(LoginForm)form;
Funcionariofuncionario=formulario.getFuncionario();
//2.testasesovlidas
if(!ehValido(funcionario)){
//nosovlidas(oops)
returnmap.findForward(erro);
}
//ok....paraondeiragora?
returnmap.findForward(ok);
}
privatebooleanehValido(Funcionariofunc){
returnfunc.getUsuario().equals("admin")&&
func.getSenha().equals("admin");
}
}
Captulo15JakartaStrutsPgina156
15.6 - A ao no struts-config.xml
Agoravamosconfigurarnossaaonostrutsconfig.xml.
Iremos adicionar uma nova action, chamada de '/efetuaLogin' e ela ser ligada a
classe br.com.caelum.struts.action.LoginAction. Introduzimos um novo atributo,
chamado name,quetemovalordonossoformulrio, aquelequeirreceberosdadosdo
requestefacilitaraleituradomesmo!
<?xmlversion="1.0"encoding="ISO88591"?>
<!DOCTYPEstrutsconfigPUBLIC
"//ApacheSoftwareFoundation//DTDStrutsConfiguration1.2//EN"
"http://struts.apache.org/dtds/strutsconfig_1_2.dtd">
<strutsconfig>
<formbeans>
<formbeanname="LoginForm"type="br.com.caelum.struts.form.LoginForm"/>
</formbeans>
<actionmappings>
<actionpath="/efetuaLogin"name="LoginForm"
type="br.com.caelum.struts.action.LoginAction">
<!ForwardsquechamamosnanossaactionLogin!>
<forwardname="erro"path="/erro.jsp"/>
<forwardname="ok"path="/ok.jsp"/>
</action>
</actionmappings>
</strutsconfig>
Oweb.xmleostrutsconfig.xml...
Vocreparouquenoalteramosmaisoweb.xml?
Deagoraemdiante,semprequevocutilizaroStruts,noprecisaralterarosdadosdoweb.xml,
vocirsomenteadicionarnovasaesnoseustrutsconfig.xml.
Sevocachatrabalhosoeditarostrutsconfig.xml,vocpodeutilizarferramentascomooStruts
Consoleparaalterarparaumaediogrficadomesmo.
erro.jsp
<html>
Ocorreualgumerroaotentarselogar!
</html>
15.8 - Exerccios
1)CriesuaaodeLogin:
packagebr.com.caelum.struts.action;
Captulo15JakartaStrutsPgina157
//importsaquiCTRL+SHIFT+O
/**
*@authorCaelum
*/
publicclassLoginActionextendsAction{
publicActionForwardexecute(ActionMappingmap,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
throwsException{
System.out.println("Algumusurioesttentandoselogar...");
//1.ondeestoasvariveis?Olhaqueelegncia
LoginFormformulario=(LoginForm)form;
Funcionariofuncionario=formulario.getFuncionario();
//2.testasesovlidas
if(!ehValido(funcionario)){
//nosovlidas(oops)
returnmap.findForward(erro);
}
//ok....paraondeiragora?
returnmap.findForward(ok);
}
privatebooleanehValido(Funcionariofunc){
returnfunc.getUsuario().equals("admin")&&
func.getSenha().equals("admin");
}
}
2)Mapeiesuaaonostrutsconfig.xml:
<actionpath="/efetuaLogin"name="LoginForm"
type="br.com.caelum.struts.action.LoginAction">
<!ForwardsquechamamosnanossaactionLogin!>
<forwardname="erro"path="/erro.jsp"/>
<forwardname="ok"path="/ok.jsp"/>
</action>
3)Crieseuarquivook.jsp
<html>
Vocselogoucomsucesso!
</html>
4)Crieseuarquivoerro.jsp
<html>
Ocorreualgumerroaotentarselogar!
</html>
5) Agora para testar a sua pgina de login, basta reiniciar o Tomcat e acessar
http://localhost:8080/struts/formularioLogin.jsp!
a)Testenossoformulriocolocandovaloreseenviandoosdados;deveraparecera
mensagem de sucesso. Agora clique em enviar deixando os campos em branco; dever
apareceramensagemdeerro.
Captulo15JakartaStrutsPgina158
ou
b)Asuaestruturadeclassesestparecidacomaseguir?
15.11 - Cookies
Oprotocolohttputilizadoatagoraparaoacessopginaslimitadopornomanter
detalhescomoquemquementreumaconexoeoutra,portantofoiinventadoumsistemapara
Captulo15JakartaStrutsPgina159
facilitaravidadosprogramadores.
COOKIE
Umcookienormalmenteumpardestringsguardadonocliente,assimcomoummapa
destrings.Essepardestringspossuidiversaslimitaesquevariamdeacordocomocliente
utilizado,oquetornaatcnicadeutilizlosalgodoqualnosedevaconfiarmuito.Jqueas
informaes do cookie so armazenadas no cliente, o mesmo pode alterla de alguma
maneira...sendoinvivel,porexemplo,guardaronomedousuriologado...
Quandoumcookiesalvonocliente,eleenviadodevoltaaoservidortodavezqueo
clienteefetuarumanovarequisio.Destaforma,oservidorconsegueidentificaraquelecliente
semprecomosdadosqueocookieenviar.
Umexemplodebomusodecookiesnatarefadelembraronomedeusurionaprxima
vezqueelequiserselogar,paraquenotenhaqueredigitaromesmo.
Cada cookie s armazenado para um website. Cada website possui seus prprios
cookieseestesnosovistosemoutrapgina.
Cookies:facilidadeesegurana
arriscadotrabalharcomcookiesemsessesquenecessitamdesegurana.Omaisindicado
sempreusarsesses,queserodiscutidaslogoemseguida.
Almdisso,muitopenosoterqueiterarportodososcookiesparaacharumcookieespecfico.A
estruturademapasdeumaSessionfacilitaemmuitootrabalhodevaloresatreladosaumusurio.
Adicionandocookies:comportamentoestranho
Naprimeiravezqueadicionamosumcookienaresposta,elenoestdisponvelparaaleitura
atravsdarequisio.Ahn?
Pararesolveresseproblemacostumamosusarumatributodomtodorequest:request.setAttribute
erequest.getAttribute.Jpodemosperceberquetrabalharcomcookiespodesertrabalhoso.
15.12 - Sesso
Usar Cookies parece facilitar muito a vida....
exceto que atravs de um cookie no possvel
marcar um cliente com um objeto, somente com
Strings. Imagine gravar os dados do usurio logado
atravsdecookies.Serianecessrioumcookiepara
cadaatributo:usuario,senha,id,datadeinscrioetc.
Semcontarafaltadesegurana.
O Cookie tambm pode estar desabilitado no
cliente,sendoquenoserpossvellembrarnadaque
ousuriofez...
SESSO
devemosrecorrerparaumatcnica(trabalhosa)chamadaurl-rewriting.
Asessonadamaisqueumtempoqueousuriopermaneceativonosistema.Acada
pginavisitada,otempodesessozerado.Quandootempoultrapassaumlimitedemarcado
noarquivoweb.xml,oclienteperdesuasesso.
Obs:Segundoaespecificaoessaconfiguraodeveriafuncionar,masnaverso
5.5.12dotomcat,existeumbug.
Comumasessoemmospodemosutilizarseusmtodosmaisbsicos:
Objectsession.getAttribute(String)
Enumerationsession.getAttributeNames()
session.setAttribute(String,Object)
session.removeAttribute(String)
session.invalidate()
booleansession.isNew()
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
qualquerobjetoJavapodeserutilizadocomovalorsalvonaseo,noselimitandoapenasa
strings
Desvantagens:
oservidorperdeodadoseonavegadorforfechado
umaseonoobrigatoriamenteamesmaemdiferentesinstnciasdomesmonavegadorno
mesmoclienteacessandoamesmaaplicaoweb,oservidornocontrolaocliente!Vocno
sabecomoeleirfuncionar!
15.15 - Exerccios
1)Aologarumusuriocomsucesso,adicioneesseusuriosesso:
a)Trabalhedentrodaaodeloginantesdeirparaapginadeok
b)Acesseasesso:
HttpSessionsession=request.getSession();
c)Adicioneousuriosesso:
session.setAttribute(funcionario,funcionario);
2)CrieumapginatestaLogin.jsp
a)Adicioneocabealhoparaousodajstlcore.
b)Seobeanusuariofornull,issosignificaqueousuario noestavalogado,sefor
diferentequenullpodemosimprimirseunome!
<c:choose>
<c:whentest=${emptyfuncionario}>
Vocnoestlogado!
</c:when>
<c:otherwise>
Vocestlogadocomo${funcionario.usuario}esenha${funcionario.senha}
</c:otherwise>
</c:choose>
c)Testeacessarapginadetestesemselogar
d)Testeacessarapginadetesteapsselogar
Captulo15JakartaStrutsPgina162
3)Faaumanovaclassedeformulriocomnmerosinteirosefloats.
Utilizeesseformulrioemumapginaeumaao.
NoprecisafazercastingoutraduodeStringparaoutrotipo!OStrutsjfazissopara
voc!
Logandonovamente
Reparequeaoacessarapginadeloginapsterselogado,seuusuriopermanecenasesso.
Sendoassim,sevocerrarousurio/senha,voccontinualogado!
ParafazerologoutvocpodeusaromtodoremoveAttributedaclasseHttpServletRequest.
//preparedstatementparaselect
PreparedStatementstmt=this.connection.prepareStatement("select*
fromfuncionarioswherenome=?andsenha=?");
//setaosvalores
stmt.setString(1,usuario);
stmt.setString(2,senha);
ResultSetrs=stmt.executeQuery();
booleanvalido=rs.next();
if(valido&&rs.next()){
//existemaisdeum
valido=false;
}
rs.close();
stmt.close();
returnvalido;
}
Captulo15JakartaStrutsPgina163
captulo
16
16
Hibernate 3.2
Nestecaptulo,vociraprendera:
usaraferramentadeORMHibernate
gerarastabelasemumbancodedadosqualquerapartirdesuasclassesdemodelo
automatizarosistemadeadicionar,listar,removereprocurarobjetosnobanco
utilizaranotaesparafacilitaromapeamentodeclassesparatabelas
criarclassesdedaobemsimplesutilizandoohibernate
16.1 - Vantagens
AutilizaodecdigoSQLdentrodeumaaplicaoagravaoproblemadaindependncia
de plataforma de banco de dados e complica, em muito, o trabalho de mapeamento entre
classesebancodedadosrelacional.
HIBERNATE
O Hibernate abstraiocdigoSQLdanossaaplicaoepermiteescolherotipode
bancodedadosenquantooprogramaestrodando,permitindomudarsuabasesemalterar
nadanoseucdigoJava.
Almdisso,elepermitecriarsuastabelasdobancodedadosdeumjeitobemsimples,
nosefazendonecessriotodoumdesigndetabelasantesdedesenvolverseuprojetoque
podesermuitobemutilizadoemprojetospequenos.
JprojetosgrandesondeoplanodeaopadrotomadopeloHibernatenosatisfazas
necessidadesdaempresa(comoousodeselect*,joinsetc),elepossuidezenasdeotimizaes
quepodemserfeitasparaatingirtalobjetivo.
AindafaltabaixarasclassescorrespondentesaoHibernateAnnotations,queiremos
utilizar para gerar o mapeamento entre as classes Java e o banco de dados. Eles so
encontradostambmnositedohibernateecontemoutrosjarsquedevemoscolocarnonosso
projeto.
Antigamente(ataverso2dohibernate)omapeamentoerafeitosomenteatravsde
Captulo16Hibernate3.2Pgina164
arquivosxml,queerabemchato,eutilizvamosdeumaferramentachamdaXdocletquecriava
taisxmls.HojeemdiaoXdocletfoisubstituidopelasAnnotations.
Bancodedados
O Hibernate traduz suas necessidades em cdigo SQL para qualquer banco de dados.
ContinuaremosutilizandooMySqlemnossosexemplos,portantonoesqueadecopiaroarquivo
.jarcorrespondenteaodriverparaodiretriolibdesuaaplicao.
16.3 - Modelo
Iremosutilizarumaclassequemodelaumprodutoparaestecaptulo:
packagebr.com.caelum.hibernate;
/**
*Classedemodeloparaumproduto
*/
publicclassProduto{
privateLongid;
privateStringnome;
privateStringdescricao;
privateDoublepreco;
//adicioneseusgettersesettersaqui!
}
@Entity
publicclassProduto{
@Column(name=descricao,nullable=true,length=50)
privateStringdescricao;
@Id@GeneratedValue
privateLongid;
privateDoublepreco;
privateStringnome;
AespecificaodoEJB3definetaisanotaesepossuidiversasopesquepodemos
utilizaremnossoprojeto.Semprequepossuiralgumaduvidaemrelaoasanotaeslembre
sedeleratalespecificao.
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;
hibernate.dialectorg.hibernate.dialect.MySQLDialect
hibernate.connection.driver_classcom.mysql.jdbc.Driver
hibernate.connection.urljdbc:mysql://localhost/teste
hibernate.connection.usernameroot
hibernate.connection.password
16.7 - Exerccios
1)Crieoarquivohibernate.propertiesnoseudiretoriosrc.
hibernate.dialectorg.hibernate.dialect.MySQLDialect
hibernate.connection.driver_classcom.mysql.jdbc.Driver
hibernate.connection.urljdbc:mysql://localhost/teste
hibernate.connection.usernameroot
Captulo16Hibernate3.2Pgina166
16.8 - Configurando
Nosso primeiro passo configurar o hibernate, portanto iniciamos instanciando uma
org.hibernate.cfg.AnnotationConfiguration.
//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
Apartirdapodemosadicionarquantasclassesdesejarmosanossaconfigurao.
//AdicionaaclasseProduto
cfg.addAnnotatedClass(Produto.class);
NonossocasoiremosadicionarsomenteanossaclasseProduto,gerandooseguinte
resultadoparaconfiguraroHibernate:
//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
//AdicionaaclasseProduto
cfg.addAnnotatedClass(Produto.class);
SissonosuficienteparaqueoHibernateestejaconfiguradocomaclasseProduto.
OHibernaterequerquedescrevamoscomoaclasseserelacionacomastabelasnobancode
dadosefizemosissoatravsdasanotaesdoHibernate.
Essaconfiguraopoderiaserfeitaatravsdeumarquivoxmlchamadohibernate.cfg.xml.
16.10 - Exerccios
1)CrieaclasseGeraTabelas.
packagebr.com.caelum.hibernate;
publicclassGeraTabelas{
publicstaticvoidmain(String[]args){
//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
newSchemaExport(cfg).create(true,true);
}
}
2)Criesuastabelasexecutandoocdigoanterior.
Captulo16Hibernate3.2Pgina167
OHibernatedevereclamarquenoconfiguramosnenhumarquivodelogparaele(dois
warnings)emostrarocdigoSQLqueeleexecutounobanco.
16.11 - Sesses
Agorajpodemospegarumafbricadesessesdotipo SessionFactory,paraisso
bastachamaromtodobuildSessionFactorydoobjetocfg.
packagebr.com.caelum.hibernate;
publicclassTesteDeConfiguracao{
publicstaticvoidmain(String[]args){
//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
SessionFactoryfactory=cfg.buildSessionFactory();
factory.close();
}
}
OHibernategerasessesatravsdessafactory.Essassessessoresponsveisporse
conectaraobancodedadosepersistirebuscarobjetosnomesmo.
Amaneiramaissimplesdebuscarumanovasessoefecharamesma:
packagebr.com.caelum.hibernate;
publicclassTesteDeConfiguracao{
publicstaticvoidmain(String[]args){
//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
SessionFactoryfactory=cfg.buildSessionFactory();
//criaasesso
Sessionsession=factory.openSession();
//fechaasesso
session.close();
factory.close();
}
}
Captulo16Hibernate3.2Pgina168
16.12 - Exerccios
1) Faa uma classe chamada TesteDeConfiguracao dentro do pacote
br.com.caelum.hibernate.NomomentodeimportarSessionlembresequenoaclassic!
packagebr.com.caelum.hibernate;
//faaimportsaquiCTRL+SHIFT+O
publicclassTesteDeConfiguracao{
publicstaticvoidmain(String[]args){
//CriaumaconfiguraoparaaclasseProduto
AnnotationConfigurationcfg=newAnnotationConfiguration();
cfg.addAnnotatedClass(Produto.class);
SessionFactoryfactory=cfg.buildSessionFactory();
//criaasesso
Sessionsession=factory.openSession();
//fechaasesso
session.close();
factory.close();
}
}
16.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();
}
}
SAVE
Sessionsession=newHibernateFactory().getSession();
Produtop=newProduto();
p.setNome("Nomeaqui");
p.setDescricao("Descrioaqui");
p.setPreco(100.50);
session.save(p);
System.out.println("IDdoproduto:"+p.getId());
session.close();
16.16 - Exerccios
1)CrieumaclassechamadaAdicionaProdutonopacotebr.com.caelum.hibernate.
packagebr.com.caelum.hibernate;
//ImportsaquiCTRL+SHIFT+O
publicclassAdicionaProduto{
publicstaticvoidmain(String[]args){
Sessionsession=newHibernateFactory().getSession();
Produtop=newProduto();
p.setNome("Nomeaqui");
p.setDescricao("Descrioaqui");
p.setPreco(100.50);
session.save(p);
System.out.println("IDdoproduto:"+p.getId());
session.close();
}
}
2)Adicionecercade5produtosnobanco.
Captulo16Hibernate3.2Pgina170
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);
}
}
publicList<Produto>listaTudo(){
returnthis.session.createCriteria(Produto.class).list();
}
Masomtodoacimadevolvealistacomtodososprodutosnobancodedados.Emum
sistemacomlistagenslongas,normalmenteapresentamosalistaporpginas.Paraimplementar
paginao,precisamosdeterminarquealistagemdevecomearemumdeterminadopontoeser
deumdeterminadotamanho.
FIRSTRESULT
MAXRESULTS
publicList<Produto>pagina(intinicio,intquantia){
returnthis.session.createCriteria(Produto.class).
setMaxResults(quantia).setFirstResult(inicio).list();
}
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());
OHibernateretornaumobjetocujotipoestendeProduto:elenodeixadeserumProduto
masnosomenteumProduto.
OmtodogetNomefoisobrescritonessaclasseparafazerabuscanaprimeiravezque
chamado,economizandotempodeprocessamento.
claroqueparafazerofinetuningdoHibernateinteressanteconhecermuitomaisa
fundooqueoHibernatefazecomoelefazisso.
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,ovRaptorumexemplodecontroladorsimplesebomparainiciantes.O
Hibernateumtimopasso,assimcomooprevayler,parapersistncia/prevalnciadeobjetos.
Domesmojeitoqueessesarcabouossurgemecrescemrepentinamente,elespodem
perderforaparaoutrosquetenhamnovidadescriativas.Eocicloserepete.
17.3 - Revistas
Diversasrevistas,noBrasilenoexterior,estudamomundojavacomoningumepodem
ajudaroinicianteaconhecermuitodoqueestacontecendolforanasaplicaescomerciais.
GrupodeUsurios
Diversosprogramadorescomomnimooumximodeconhecimentoserenemonline
paraatrocadedvidas,informaeseidiassobreprojetos,bibliotecasemuitomais.Umdos
maisimportantesefamososnoBrasiloGUJwww.guj.com.br
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
Apndice A - VRaptor
18
Nestecaptulo,vociraprender:
oqueInversodeControle,InjeodeDependnciaseConventionoverConfiguration
comoutilizarumframeworkMVCbaseadoemtaisidias
comoabstrairacamadadehttpdesualgicadenegcios
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,InjeodeDependncias(DependencyInjection),Inverso
de Controle (Inversion
DEPENDENCI
of
Control
IoC)
e
Prefira
convenes
em
vez
de
customizao
(Convention over
AS
INVERSAO DE
CONTROLE
Configuration CoC).
18.2 - Vantagens
18.3 - Vraptor 2
Tudooquefaremosnestecaptuloestbaseadonoframeworkconhecidocomovraptor
(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();
//aao
publicvoidadiciona()throwsException{
newContatoDAO().adiciona(contato);
}
}
Pronto!assimqueficaumaaodeadicionarcontatoutilizandoessecontrolador(e
podemosmelhorarmaisainda!).Vamosagoraconfigurarovraptor.xml:
<vraptor>
<component>br.com.caelum.vraptor.AdicionaContato</component>
</vraptor>
Esesurgiranecessidadedecriarummtodoatualiza?Poderamosreutilizaramesma
classeparaosdoismtodos:
@Component(contato)
publicclassContatoLogic{
//meucontato
@Read(create=true)
@Out
privateContatocontato;
//aaoadiciona
publicvoidadiciona()throwsException{
newContatoDAO().adiciona(contato);
}
//aaoatualiza
publicvoidatualiza()throwsException{
newContatoDAO().altera(contato);
}
}
Oprprioframeworkchamaosmtodos:
contato.setNome(request.getParameter("contato.nome"));
contato.setEmail(request.getParameter("contato.email"));
contato.setDescricao(request.getParameter("contato.descricao"));
Tudoissoautomaticamente!
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;
//aaoadiciona
publicvoidadiciona()throwsException{
newContatoDAO().adiciona(contato);
}
//aaoatualiza
publicvoidatualiza()throwsException{
newContatoDAO().altera(contato);
}
}
b)Crieoarquivoweb/vraptorformulario.jsp
<html>
<formaction="contato.adiciona.logic">
Nome:<inputname="contato.nome"/><br/>
Email:<inputname="contato.email"/><br/>
Captulo18ApndiceAVRaptorPgina180
c)Crieodiretrioweb/contato
d)Crieoarquivoadiciona.ok.jspnodiretrioweb/contato
<html>
Seucontatofoiadicionadocomsucesso!<br/>
<ahref="mailto:${contato.email}">${contato.nome}</a>,${contato.endereco}<br/>
</html>
e)Configureovraptor.xml
<vraptor>
<component>br.com.caelum.vraptor.ContatoLogic</component>
</vraptor>
f)Vocimportoualgumaclassedopacotejavax.servlet?
g)Testeoseuformulrio:http://localhost:8080/struts/vraptorformulario.jsp
2)Crieumsistemadelistagemdecontatos
a)CrieaclasseListaContatonopacotebr.com.caelum.vraptor
b)Crieoarquivoweb/contato/lista.ok.jsp
c)Configureovraptor.xml
d)Vocimportoualgumaclassedopacotejavax.servlet?
3)Tentevalidarprogramticamenteocontatoantesdeseradicionado.Comovoc
podefazerissodeumjeitobemsimples?Aprendamaisnositedovraptor.
18.10 - Log
Sevocdesejaverasinformaesdelogqueovraptor(eoutrasbibliotecasqueutlizamo
log4j)mostra,configureoarquivolog4j.xmlnodiretoriosrc:
<?xmlversion="1.0"encoding="UTF8"?>
<!DOCTYPElog4j:configurationSYSTEM"log4j.dtd">
<log4j:configurationxmlns:log4j="http://jakarta.apache.org/log4j/">
<appendername="stdout"class="org.apache.log4j.ConsoleAppender">
<layoutclass="org.apache.log4j.PatternLayout">
<paramname="ConversionPattern"
value="%d{HH:mm:ss,SSS}%5p[%20c{1}]%m%n"/>
</layout>
</appender>
<categoryname="org.vraptor">
<priorityvalue="ERROR"/>
<appenderrefref="stdout"/>
</category>
</log4j:configuration>
Captulo18ApndiceAVRaptorPgina181
Captulo18ApndiceAVRaptorPgina182
captulo
19
19
Nestecaptulo,vociraprender:
umanovacamadadevisualizao
maissimplesquejsp
comoutilizlajuntoaoStruts
menospoderosa,comumfocodiferentedomesmo
19.1 - Velocity
VELOCITY
TEMPLATES
coloclaemsuasaesouregradenegcios.Sempre.
Adocumentao,arquivos,bibliotecaetcdoVelocitypodemserencontradosem:
http://jakarta.apache.org/velocity
19.2 - Vantagens
Ogrupojakartaenumeraalgumasvantagensdovelocity,quandocomparadoaojsp:
1.
2.
3.
4.
5.
ajudaaforarumaseparaolimpaentreacamadadevisualizaodascamadasde
controleedemodelo,colaborandotantocomprogramadoresquantocomdesigners
avelocitytemplatelanguage(vtl)tempoucasdiretivasesimplesdeaprendar.
velocitytemplatesnosolimitadosahtml,podendogerarfacilmentecdigoxml, sql,
ascii,postscriptetc.
velocitypermiteacessardadosdeumamaneiraqueowebdesignerentendeoqueest
acontecendoo
ovelocityfazousodecacheparamelhoraraperformancedesuaspginas
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>
Esteltimopassoconfiguraaferramentatextqueirajudaratrabalharcomosarquivos
deinternacionalizaodostruts.
19.5 - Exerccios
ExecuteospassosdaltimaseonoseuprojetodostrutsparaconfiguraroVelocitye
oVelocityTools.Sigaospassosdaseoanterior:
Passo1:Copieos.jarparaoWEBINF/lib
Passo2:Atualizeoweb.xml
Passo3:Crieoarquivotoolbox.xml
Ocdigoacimanotemmuitagraa,eleintroduzumcomandodecriaodevarivelde
simplescompreenso:#set($nome=valor),porm,issonotudoqueoVelocitycapazde
fazer.Entovamostrabalharcomidiasmaisinteressantesemumaaplicao.
PodemospedirparaqueaenginedoVelocityprocesseessetemplate.Nessemomento
elavaiprocurarporumarefernciaaumobjetoqueestejaassociadaastringnome.
Essasassociaessofeitasemumobjetoparecidocomummapadascoleesdojava:
ocontexto.Ocontextodovelocitypodeserinstanciadopornsmesmosouentoreceberele
comoparmetro.
RepareasintaxemuitomaissimplesqueadoJSP,facilitandootrabalhododesigner.
Velocity muito usado na web como substituto de JSP, mas ele pode ser usado em
qualqueraplicao,comoporexemplopararenderizarrelatriosougerarcdigojava.
Afiguraaseguirilustraoprocessodemerge/renderizao:
Captulo19ApndiceBJakartaVelocityPgina185
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
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
Parasaberseumarefernciaexisteounonocontexto(isto,seelanullouno),
bastavocfazerum#ifusandoarefernciacomoargumento:
#if($livro)
Existeumlivronocontextodovelocity
#else
Captulo19ApndiceBJakartaVelocityPgina187
19.13 - FOREACH
TendoumaCollection,sejaelaqualfor,vocpodefacilmenteiterarsobreela.
Considereoseguintecontexto:
ArrayListlista=newArrayList();
Livrolivro1=newLivro();
livro1.setTitulo(MemriasPstumasdeBrsCubas);
lista.add(livro1);
Livrolivro2=newLivro();
livro2.setTitulo(OsSertes);
lista.add(livro2);
Livrolivro3=newLivro();
livro3.setTitulo(VidasSecas);
lista.add(livro3);
Numexemplomaisreal,essaCollectionviriadeumDAO,puxadadobancodedados.
Noseutemplate:
#foreach($livroin$lista)
Livronalista:$livro.titulo
#end
Repareasimplicidadedessecdigo:odesigner,queoresponsvelpormanteresse
template,noprecisaterconhecimentodequehclasses,coleesereflectionportrazdisso!
OVelocitypodeiterardemaneiraidnticasobreumaarrayousobreumiterator.Sedentro
doloopvocprecisarsaberemqueiteraovocest,existeavarivel$velocityCountpara
isso.
19.14 - PARSE
Emmuitoscasosdividimosnossapginawebemvriospedaos,comocabealho,corpo
e rodap. Podemos distribuir isso em arquivos diferentes no Velocity, e pedir para que ele
renderizeoutrostemplatesdentrodeumdeterminadotemplate:
#parse(header.vm)
Captulo19ApndiceBJakartaVelocityPgina188
aquivaionossocorpo
#parse(footer.vm)
Existeumaoutradiretiva:a#include.Elafazomesmotrabalhoquea#parsepormo
templateinseridonoserinterpretado,isso,nohaveromerge.
19.15 - Comentrios
Parafazerumcomentriodeumalinha:
##essalinhanoserinterpretada
Umcomentriodotipobloco:
#*
Esseumcomentriodotipobloco,nadadissoserinterpretado
*#
19.17 - ImportTool
IMPORTTOOL
AImportToolumaferramentausadaparaimportarcdigohtmldeoutrasurls,estejam
elaslocalizadasnoseuservidorouemqualqueroutrolugarqueoservidortenhaacesso.
Definimoselacom:
<tool>
<key>import</key>
<scope>request</scope>
<class>org.apache.velocity.tools.view.tools.ImportTool</class>
</tool>
Eparaimportaraurlhttp://www.caelum.com.brnanossapginabastausar:
$import.read(http://www.caelum.com.br)
Vocpodeimportarurlsquaisquer.Adiferenaentreessatooleo#parsequeaquia
novapgina(seforumtemplatedovelocity)terumcontextodiferentedocontextoatual.
Maisinformaesem:http://jakarta.apache.org/velocity/tools/view/ImportTool.html
19.18 - CookieTool
COOKIETOOL
ACookieToolumaferramentaquefacilitamuitootrabalhocomcookies.
Definimoselacom:
<tool>
<key>cookie</key>
<scope>request</scope>
<class>org.apache.velocity.tools.view.tools.CookieTool</class>
</tool>
Captulo19ApndiceBJakartaVelocityPgina189
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
PodemosdaracessoaconstruodosobjetosdotipoPaginaWebapartirdeummtodo
dentrodaclasse.Essemtododitariaasregrasdafabricaodenovosobjetos,ouemvezde
fabricarumnovo,devolverumjexistente.
Imagineagoramanterumobjeto dotipo HashMap chamado paginasJaCriadas que
seriaonossocache.Ocdigoaseguirmostracomousloparaevitaracriaodeobjetos
cacheados:
PaginaWebpagina;
if(this.paginasJaCriadas.get(url)!=null){
pagina=this.paginasJaCriadas.get(url);
}else{
pagina=newPaginaWeb(url);
this.paginasJaCriadas.put(url,pagina);
}
returnpagina;
Cachedeque?
Noaconselhadosairporafazendocachedequalquertipodeobjetos.Objetospesadosso
indicadosparaseremcacheadosouentoparaseremtiradosdeumpool.
Objetospesadossoaquelesquenitidamenteconsomemmuitosrecursosdosistemaoperacional
oudaplataforma,comoThreads,conexescombancodedadoseoutros.
Isto,sea PaginaWeb paraestaurljfoicriadaalgumdia,nohanecessidadede
criarumnovoobjeto:podemospeglodeumcache.Senoexiste,iremoscriar,guardare
retornar,paraquepossaserreutilizado.
Emquemtodocolocamosessaimplementao?Seforemummtodoparaoobjeto,s
poderemosacessaressemtodojtendoumobjetoantes,oquenofazsentido.Precisamos
deummtodoestticoparapoderseracessadopelaclasse.Almdisso,nopodemosusarum
atributodeobjetodentrodeummtodoesttico,entoonossomapanopodeseracessado
pelothis,poistratariasedeumatributodeobjeto.Nossomapadeveserumatributoesttico.
1.
2.
3.
publicclassPaginaWeb{
privatestaticMap<String,PaginaWeb>paginasJaCriadas=new
HashMap<String,PaginaWeb>();
privateStringurl;
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25. }
privatePaginaWeb(Stringurl){
this.url=url;
}
/**
*Fbricadepginasweb.
*Sejexistirumobjetonocache,retornaele.
*/
publicstaticPaginaWebgetPaginaWeb(Stringurl){
//senoexistirnocache
if(PaginaWeb.paginasJaCriadas.get(url)==null){
//colocanocache
PaginaWeb.paginasJaCriadas.put(url,newPaginaWeb(url));
}
//retornadocache
returnPaginaWeb.paginasJaCriadas.get(url);
}
Captulo20ApndiceCDesignPatternsPgina192
classPesquisa{
PaginaWebpesquise(Stringurl){
returnPaginaWeb.getPaginaWeb(url);
}
}
Ointeressanteperceberaquique,paraocliente,indiferenteoqueessemtodofez,se
elepegoudocacheouno.Alis,vocpodemudarasregrasdoseucachedanoiteprodia,
seminterferirnobomfuncionamentodaaplicao.
EsseDesignPatterntemonomedeFactory(Fbrica)eexistemdiversasvariaesdo
mesmo.
Memriacheia?
Fazerocachedetodososobjetospodeconsumirmuitamemria.Vocpodeestarusandoumtipo
demapaqueguardaapenasosltimos50objetosinstanciadosouentoosmaisacessados,por
exemplo.
Captulo20ApndiceCDesignPatternsPgina193
captulo
21
21
Apndice D - Servlets
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>
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
Paraguardarobjetosqueseroutilizadosportodosasservletsutilizamosoescopo de
aplicao,chamadotambmdeservlet context.
Cadaaplicaowebpossuiumnicoservletcontext,etodasasservletspossuemacesso
aele.
Objetosguardadosemtalcontextopodem,porexemplo,serlidoseutilizadosporuma
pgina jsp. Para usar o ServletContext em uma servlet basta chamar o mtodo
getServletContextdamesma.
ServletContextcontext=getServletContext();
DataSourceds=(DataSource)context.getAttribute(datasource);
Connectioncon=ds.getConnection();
//usaaconexoaqui
con.close();
con=null;
Captulo21ApndiceDServletsPgina195
Captulo21ApndiceDServletsPgina196
captulo
22
22
Nestecaptulo,vociraprendera:
13. solucionaroproblemadecontroledeacessoaoconstrutordeobjetos;
14. criarinstnciasnicasdeobjetosemumprograma;
15. resolveralgunsproblemasclssicosdeorientaoaobjetos.
22.1 - Singleton
SINGLETON
Emalgunscasos,desejamosquedeterminadaclassespossaserinstanciadaumavez.
Isto , s queremos um objeto daquela classe e que a referncia para ao mesmo seja
compartilhadapordiversosoutrosobjetos.
Istomuitocomumquandoaclasserepresentaumaentidadenicanosistema,comoo
presidentedeumaempresa,ogerenciadordelogsdaaplicaoouocontroladordeusurios.
Como faremos? Com certeza aproveitaremos o truque anterior, deixando o construtor
privadoecriandoummtodoestticopararetornarareferncia.Masoquefazerpararetornar
sempreumarefernciaparaamesmainstncia?
publicPresidentegetPresidente(){
returnreferenciaUnica;
}
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
Aoaplicaropattern,aclasseaplicaodeverutilizaromesmoobjetodotipo Logger
nasduaschamadasaomtodolog,portantooresultadodaaplicaoser:
Captulo22ApndiceEDesignPatternsPgina198
PRIMEIRAMENSAGEMDELOG
SEGUNDAMENSAGEMDELOG
Passo1:TorneoconstrutordeLoggerprivado
Passo2:Crieumavriavelestticaloggerparaconterumareferncianicaaoobjetode
Logger;instancieavarivelnadeclarao
Passo3:CrieummtodoestticogetLoggerquedevolvearefernciaparaologger
Passo4:NaclasseAplicacao,substituaonewLogger()pelousodomtodoesttico
getLoggercriadonopasso3.
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