Sie sind auf Seite 1von 897

se a Cabeca Servlets

...:>

& JSPTM
Segunda Edio

No seria fantstico se existisse um livro sobre Servlets que fosse mais interessante do que apagar spam da sua caixa de mensagens? Talvez isso seja uma iluso ...

Bryan Basham Kathy Sierra Bert Bates

Rio de Janeiro.2008

Use a Cabea Servlets & JSpTM


Alta Books Editora - Starlin Alta Con Com Ltda 2008 Do original Head First Servlets and JSPTM. , 2st Edition 2008 O'Reil/y Authorized translation of the English edition of Head First Servlets and JSPTM Media,lnc. ISBN: 978-0596102340 This translation is published and sold by permission ofO'Reil/y Media, Inc., the owner of ali rights to publish and sell the some. Todos os direitos reservados e protegidos pela Lei 5988 de 14/12/73. Nenhuma parte deste livro, sem autorizao prvia por escrito da editora, poder ser reproduzida ou transmitida sejam quais forem os meios empregados: eletrnico, mecnico, fotogrfico, gravao ou quaisquer outros. Todo o esforo foi feito para fornecer a mais completa e adequada informao, contudo a editora e o(s) autor(es) no assumem responsabilidade pelos resultados e usos da informao fornecida. Recomendamos aos leitores testar a informao, bem como tomar todos os cuidados necessrios (como o backup), antes da efetiva utilizao. Este livro no contm CD-ROM, disquete ou qualquer outra midia. Erratas e atualizaes: Sempre nos esforamos para entregar a voc, leitor, um livro livre de erros tcnicos ou de contedo; porm, nem sempre isso conseguido, seja por motivo de alterao de software, interpretao ou mesmo quando alguns deslizes constam na verso original de alguns livros que traduzimos. Sendo assim, criamos em nosso site, www.altabooks.com.br. a seo Erratas, onde relataremos, com a devida correo, qualquer erro encontrado em nossos livros. Avisos e Renncia de Direitos: Este livro vendido como est, sem garantia de qualquer tipo, seja expressa ou implcita. Marcas Registradas: Todos os termos mencionados e reconhecidos como Marca Registrada e/ou comercial so de responsabilidade de seus proprietrios. A Editora informa no estar associada a nenhum produto e/ ou fornecedor apresentado no livro. No decorrer da obra, imagens, nomes de produtos e fabricantes podem ter sido utilizados, e desde j a Editora informa que o uso apenas ilustrativo e/ou educativo, no visando ao lucro, favorecimento ou desmerecimento do produto/fabricante. Produo Editorial: Editora Alta Books Coordenao Editorial: Roberto Baptista Barroco Traduo: Eveline Vieira Machado Reviso: Fernanda Rigamond Reviso Tcnica: Helder Borges Diagramao: Impresso no Brasil Equipe Alta Books

o cdigo de propriedade intelectual de 10 de Julho de 1992 proibe expressamente o uso coletivo sem autorizao dos detentores do direito autoral da obra, bem como a cpia ilegal do original. Esta prtica generalizada nos estabelecimentos de ensino, provoca uma brutal baixa nas vendas dos livros a ponto de impossibilitar os autores de criarem novas obras.

Editora Alta Books Rua Viva Claudio, 291 - Jacar Rio de Janeiro - RJ CEP 20551-010 Tel: 21 3278-8069 Fax: 21 3277-1253 www.altabooks.com.br altabooks@altabooks.com.br

os autores

Os "procurados" da srie Use a Cabea! (e deste livro)


Beart Bates Bryan Basham

Bert um antigo desenvolvedor e arquiteto de software, mas um perodo de 10 anos em inteligncia artificial o fez se interessar por teoria da aprendizagem e treinamento via computador. Ele passou a primeira dcada de sua carreira como desenvolvedor viajando pelo mundo e ajudando clientes como a rdio Nova Zelndia, o The Weather Channel e a rede de entretenimentos Arts and Entertainment Network (A&E) em suas transmisses. Atualmente, ele membro da equipe da Sun responsvel pelo desenvolvimento de diversos exames de certificao em Java, incluindo o recente SCWCD. Bert um antigo e incorrigvel aficionado pelo GOl e vem trabalhando h bastante tempo em um programa. O Java h de se tomar uma linguagem expressiva o suficiente para que ele finalize seu projeto. Ele um bom guitarrista e, atualmente, est experimentando o banjo. Sua mais recente aventura foi a compra de um cavalo islands, o que dever trazer novos desafios aos seus conhecimentos na rea de treinamento ...
VIII

Kathy gosta de teoria da aprendizagem e assuntos relacionados mente desde a poca em que era designer de jogos (ela escreveu jogos para a Virgin, MGM e Amblin') e desenvolvedora em I.A2 Grande parte do formato da srie Use a Cabea! foi desenvolvido enquanto lecionava Interatividade Usando Novas Midias, no programa de extenso de Estudos em Entretenimento da Universidade da Califmia (DCLA). Recentemente, se tomou instrutora-chefe da Sun Microsystems e ensina os instrutores de Java a divulgarem as mais novas tecnologias desta linguagem. Alm disso, desenvolve diversos exames para certificaes Sun, incluindo o SCWCD. Junto com Bert Bates, ela tem aplicado extensivamente os conceitos da srie Use a Cabea! no ensino de milhares de desenvolvedores. Ela fundou uma das maiores comunidades em Java no mundo virtual, a javaranch. com, premiada em 2003 e 2004 com o Prmio Produtividade em Desenvolvimento de Software. Ela adora correr, esquiar, montar a cavalo, andar de skate e cincias esotricas.

Bryan tem mais de vinte anos de experincia em desenvolvimento de software, incluindo um perodo com software de automao avanada usando tcnicas de I.A na NASA Ele tambm atuou em uma consultoria, desenvolvendo aplicaes comerciais em 00 personalizadas. Atualmente, Bryan Desenvolvedor de Cursos da Sun, com nfase nos princpios de design em Java e em 00. Ele j trabalhou em diversos cursos de Java da Sun, incluindo JDBC, J2EE, Servlets e JSP, alm de Desenvolvimento de Software utilizando 00. Ele foi tambm o primeiro designer dos exames SCWCD, nas verses original e atual. Bryan pratica o Zen Budismo, joga Ultimate Frisbee, adora som e pratica o ski telemark.

contedo

(Sumt19)
Introduo Por que usar Servlets & JSPs: uma introduo Arquitetura da aplicao web: viso geral de alto nvel Minitutorial do MVC: praticando com o MVC Sendo um servlet: request e resposta Sendo uma aplicao web: atributos e listeners Estado de conversao: sincronizando o bean/entidade Sendo um JSP: escrevendo cdigos em JSP Pginas sem scripts: escrevendo JSPs sem scripts As tags customizadas so poderosas: usando a JSTL Quando nem a JSTL o bastante: desenvolvendo tags customizadas Distribuindo sua aplicao web: distribuio da aplicao web O poder dos filtros: wrappers efiltros Padres de Design Enterprise: padres e Struts Apndice A: TestePreparatrio Final ndice
XIX

37 67 93 147 223 281 343 439 499 601 701 737 791
865

Mantenha em segredo, mantenha seguro: segurana da aplicao web 649

Introduo
Seu crebro pensando em Servlets. Aqui est voc tentando aprender algo, enquanto seu crebro lhe presta o favor de certificar-se de que tal aprendizado no ser interrompido. Ele pensa, " melhor reservar espao para coisas mais importantes, como qual animal selvagem evitar e se esquiar sem roupa ruim mesmo". Ento, como voc vai induzi-lo a pensar que sua vida depende do conhecimento em Servlets? A quem se destina este livro? Ns sabemos o que seu crebro est pensando Metacognio Domine seu crebrp O que voc precisa para este livro Passando no exame de certificao Os revisores tcnicos Agradecimentos
XX
XXI XXlll

xxv
XXVI XXVlll XXX XXXI

IX

Por que usar servlets & JSPs?

As aplicaes web esto na moda. Quantas aplicaes GUI voc conhece que so usadas por milhes de usurios em todo o mundo? Como desenvolvedor de aplicaes web, voc no precisar se prender aos problemas de distribuio presentes em toda aplicao standalone e ir distribuir sua aplicao a qualquer pessoa que possua um browser. Mas voc precisar dos servlets e dos JSPs, pois as velhas e estticas pginas HTML so to, digamos, "1999". Saiba como mudar do sUe na web, para a aplicao na web. Objetivos do Exame O que os servidores web e os clientes fazem e como conversam entre si Guia rpido de HTML 2 4 7 10

Principais elementos do fluxo de solicitao: O mtodo HTTP (a ao de se~ executada) A~<rinaqueseracessada (umaURL)
Osp:mi:mctrosdofurmulrio(curoo argtIIIlell!oSparamnrnloOO)

solicitao HTTP

O que o protocolo HTTP?

A anatomia das solicitaes HTTP GET ePOST e das respostas HTTP 16 Localizando pginas web usando URLs
Cliente Servidor
Principais elementos do fluxo de resposta:
Um cdigo solicitao O contedo de .umIS (no caso de uma bem sucedida) (tc."to, i~oem, HIML, ctc_) (o HTML real, a imagem, etc_)

20 24 30

Servidores web, pginas estticas e

cm

Desmistificando os Servlets: escreva, distribua e rode um servlet

TIpo de contedo

JSP foi o que aconteceu quando algum apresentou o Java ao HTML 34

Arquitetura da aplicao web

2
Serv!et

Os servlets precisam de ajuda. Quando uma solicitao chega, algum tem que instar o servlet ou, pelo menos, alocar uma thread para tratar a solicitao. Algum tem que chamar ou o mtodo doPostO ou o mtodo doGetO do servlet. Algum precisa levar a solicitao e a resposta para o servlet. Algum precisa gerenciar a vida, a morte e os recursos do servlet. Neste captulo, vamos estudar o Container e dar uma primeira olhada no padro MVC. Objetivos do Exame O que um Container e o que ele oferece? Como fica o cdigo (o que toma um servlet um servlet) Nomeando os servlets e mapeando-os a URLs usando o DD Histria: Bob Constri um Site de Encontros (introduo ao MVC) Viso geral e exemplo de MVC (Model- View-Controller)
Modelo

38

39 44 46 50 54 64 65

(Controlador '\

JSP

iJSP
JCVQ

1
1,
Ba",o de Dad,,,

antigo

View

Um Deployment Descriptor (DD) "funcionando" Como o J2EE cabe nisso tudo

contedo

Minitutorial do MVC

3
Especffico Este nome para o Tomcat de diretf'io

Criando e distribuindo uma aplicao MVC. Chegou a hora de colocar a mo na massa e escrever um formulrio HTML, um controlador de servlet, um modelo (classe Java simples), um deployrnent descriptor XML e uma view em JSP. hora de criar, distribuir e testar. Antes, porm, voc dever configurar seu ambiente de desenvolvimento. Em seguida, voc ter que configurar o seu ambiente de distribuio, de acordo com as especificaes do servlet e do JSP, e as exigncias do Tomcat. Concordo, esta uma aplicao pequena ... Porm, quase NO existe aplicao que seja to pequena e use o MVC.
r::::a ~ !
;~
j

root" querepresenta tambm o Torncat usa o context quando est resolvendo URLs. Ns exploraremos em maiores detalhes este conceno no

Esta parte da estrutura de diretrios exigido

Objetivos do Exame Vamos construir uma aplicao MVC: primeiro o design Criando os ambientes de desenvolvimento Criando o Deployment Descriptor (DD) Criando, compilando, distribuindo e testando o servlet de controle Design, criao e teste do componente modelo Otimizando o controlador para chamar o modelo e distribuindo o componente view; (isto um JSP)
o

68 69 72 77 81 82 87 88 e distribuio

copt1Jlo sobre Distribuio.

'-; diretamente pelo Tomcat e d~ve estar l;;;J ablllxo do I {' seu diretno home.

-~8)~_OOOmedaapricao.

dos Servlets ! _ parteda pecifj~o~l 1""""

j- '-'\

ll
_ z;;
A estrutura

Criando e testando o HTML para o formulrio inicial


,!J.

l_ _ _

~" ~

Este arquivo web.xmJ h~TEMQ~Eestarem WEB-INF


deste pacote

Especfico Aplicao

da

8,- : . ~
- - .' .'

menos que voc esteja

1 _~ .. ,'- ,

i _~ :~:~~~~u:n=;~o ~~(~:~~a~:e~t~i:O ~; _ ~ _". Criando g 8


_ -_-maIs

tarde).

voc

DEVE colocar

[pacote

de estrutura de diretrios
abaixo de WEB-

~>

_si"",

irnediatamente INF/classes.

Otimizando o servlet de controle para chamar o JSP

Sendo um servlet

4
NO Idempotente

Servlets vivem para servir clientes. A funo de um servlet receber uma solicitao do cliente e devolver uma resposta. A solicitao talvez seja simples: "traga-me a pgina de Boas-vindas". Ou pode ser complexa: "Finalize o processo do meu carrinho de compras."A solicitao carrega dados cruciais e o cdigo do seu servlet tem que saber como encontr-Ios e utiliz-Ios. E ele tem que saber como enviar uma resposta. Ou no ... Objetivos do Exame Os Servlets so controlados pelo Container Cada solicitao roda em uma thread separada! A verdadeira funo do servlet no tratamento das solicitaes A histria da solicitao no-idempotente O que determina se voc recebeu uma solicitao GET ou POST?
o
servlet

94 95 101 105 112 117 119 126

usa os

Enviando e usando parmetro( s)


dados

do POST para atualizar

Ento, essa foi a Solicitao ... vejamos agora a Resposta

<_ ....

~:"::

LJ

~~ Cliente

':::~ irO servJet WW'. envia de volta uma resposta ~ com uma pgina gerada em HTML

/servlet

.... wz

-----8 ..

ObanCOde ..... d ... QdOS.

Voc pode configurar headers de resposta, voc pode adicionar headers de resposta 133 Redirecionamento de servlets faz o browser trabalhar 136 Reviso: HttpServletResponse 140

XI

5
9rset
,,,
~set
Acessvel

Sendo uma aplicao web


Nenhum servlet vive sozinho. Nas aplicaes web atuais, vrios componentes trabalham em conjunto por um objetivo. Temos os modelos, os controladores e as views. Temos os parmetros e os atributos. Temos as classes helper. Mas, como juntar os pedaos? Como permitir que os componentes compartilhem informaes? Como voc oculta informaes? Como voc torna uma informao thread-safe? Seu trabalho pode depender destas respostas. Objetivos do Exame Os Parmetros Init do uma fora Como um JSP consegue obter os parmetros init do servlet? Os parmetros init do contexto do uma fora Comparando o ServletConfig com o ServletContext Ela quer um ServletContextListener Tutorial: escreva um ServletContextListener Compile, distribua e teste o seu listener A histria completa, uma anlise do ServletContextListener Listeners: eles no servem apenas para os eventos de contextos O que exatamente um atributo? AAPI Atributo O escopo de contexto no thread-safe! Como tomamos os atributos do contexto thread-safe? Testando a Sincronizao Os atributos de Sesso so thread-safe? Os males do SingleThreadModel simples 148 150 155 157 159 166 168 176 178 180 185 189 192 194 195 198 201

apennspamoquelescomoc:essoQ_HttpSessionespecifico

Atributos de SOUctTAO

Apenas os atnbutos da Solicitaoe as variveis locais so thread-safe! 204 Atributos da Solicitao e request dispatching 205

XII

contedo (sumrio)

Estado de conversao

6
06of.if-f,-",",,-!--r.~""~'-

Os servidores web no tm memria curta. Assim que eles lhe enviam uma resposta, eles esquecem quem voc . Na prxima vez que voc fizer uma solicitao, eles no o reconhecero. Eles no se recordam do que voc solicitou no passado e nem do que eles enviaram como resposta. Nada. Porm, algumas vezes voc precisa manter o estado de conversao com o cliente durante vrias solicitaes. Um carrinho de compras no funcionaria se o usurio tivesse que escolher seus produtos e finalizar a compra de uma nica vez. Objetivos do Exame Esperamos que seja uma conversa (como as sesses funcionam) IDs de sesso, cookies e outros fundamentos das sesses Reescrita de URL: uma alternativa Quando as sesses envelhecem; dando adeus s sesses ruins Posso usar cookies para outras coisas alm das sesses? Os principais momentos de um HttpSession No se esquea do HttpSessionBindingListener A migrao da sesso Exemplos de listener 226 231 237 241 250 254 256 257 261 224

~"' .... "'~=

Sendo um JSP
Um JSP torna-se um servlet. Um servlet que voc no cria. O Container olha o seu JSP, o traduz em cdigo-fonte Java e o compila em uma classe servlet de Java completa. Porm, voc tem que saber o que acontece quando o cdigo que voc escreveu em JSP se transforma em cdigo Java. Voc pode escrever cdigos Java em JSP, mas ser que voc deveria? E se no for um cdigo Java, o que voc pode escrever? Como ele jaz a traduo para o cdigo Java? Veremos seis diferentes tipos de elementos JSP ~ cada um com seu prprio propsito e, sim, sintaxe nica. Voc aprender como, por que e o que escrever no seu JSP. E voc aprender o que no escrever. Objetivos do Exame Criando um JSP simples usando o "out" e uma diretiva de pgina Expresses, variveis e declaraes em JSP 283
288 282

~' .,
,.

Hora de ver. um servlet gerado a partir do JSP


._.~.

296
298

A varivel out no o nico objeto implcito

">.,.
MyISP-.J<pSc1vlet

O Ciclo de vida e a inicializao de um JSP J que estamos falandosobre isso ... as trs diretivas Scriptlets considerados perigosos? Eis a EL Mas, espere ... ainda no vimos as aes

306 314 317 323


XIII

Pginas sem scripts


Fuja do scripting. Ser que seus webdesigners precisam mesmo saber Java? Ser que eles pensam que quem programa Java para servidores tomar-se-, digamos, designer grfico? E mesmo que a equipe seja s voc, voc quer mesmo um monte de bits e pedaos de cdigos Java nos seus JSPs? Voc sabe o que significa "um pesadelo na hora da manuteno"? Escrever pginas sem scripts no s possvel, como tambm mais fcil e mais flexvel com a nova especificao JSP 2.0, graas nova Expression Language (EL). Padronizada depois do JavaScript e do XPATH, os webdesigners sentir-se-o em casa com a EL. E voc tambm vai gostar (assim que voc se acostumar). Porm, existem algumas armadilhas ... a EL se parece com o Java, mas no . s vezes, a EL se comporta de forma diferente de como comportar-se-ia a mesma sintaxe no Java. Portanto, fique atento! Objetivos do Exame Quando os atributos so beans Aes-padro: useBean, getProperty, setProperty Voc sabe fazer referncias polimrficas para beans? atributo param d uma ajuda Convertendo propriedades A Expression Language (EL) salva o dia! Usando o operador ponto (.) para acessar propriedades e mapear valores O [c:catch] d a voc mais opes (Lists, arrays ...)
.""'<0""" ... '''<1''''<:;

344 345 349 354 360 363 368

370 372 376 385 392 402 416 417 417

'9"",'~.,,<!~~",-,.~.".

_~d~.

Mais detalhes dos operadores ponto e [ ] Os objetos implcitos da EL Funes EL e tratando o "null" Os pedaos reutilizveis do template - dois tipos de "include" A ao-padro <jsp:forward> Ela no conhece as tags JSTL (uma viso rpida) Revisando as aes-padro e o include

XIV

contedo

As tags customizadas so poderosas

Em alguns casos, voc precisa de mais do que a EL ou aes-padro. E se voc quisesse fazer um loop atravs dos dados de um array, exibindo em seguida um item por linha em uma tabela HTML? Voc sabe que poderia escrever isso em dois segundos, usando um loop for em um scriptlet. Mas voc est tentando evitar os scripts. Sem problema. Quando a EL e as aes-padro no forem suficientes, voc pode usar tags customizadas. Elas so to fceis de usar em um JSP quanto as aes-padro. Melhor ainda, algum j escreveu boa parte das tags de que voc mais provavelmente precisar, e as juntou na JSTL (JSP Standard Tag Library, ou Biblioteca de Tags JSP Padro). Neste captulo, aprenderemos a usar tags customizadas, e no captulo seguinte, aprenderemos a criar as nossas prprias tags. Objetivos do Exame Fazendo loops sem scripts; <c:forEach> Controle condicional com o <c:i:f> e o <c:choose> Usando as tags <c:set> e <c:remove> Com a <c:import>, h trs maneiras de incluir contedo Customizando o que voc inclui Fazendo o mesmo com <c:param> A <c:url> para todas as suas necessidades de hyperlink Crie suas prprias pginas de erro A tag <c:catch>. Semelhante a try/catch ... mais ou menos E se voc precisar de uma tag que NO esteja na JSTL? Preste ateno ao <rtexprvalue> O que pode existir no corpo de uma tag O tag handler, o TLD e o JSP A taglib <uri> apenas um nome, no um local Quando um JSP usa mais de uma biblioteca de tags
() .H-ritr.rl'c.te #fler+4.f';tJ

440 446 451 455 460 462 463 465 468 472 475 480 482 483 484 487

,lll.prN.ltLlsi
<c;forEach var="1i.stElement"

,"-----V;jrJ<!l

J'
>

items="${movi.es}"

va.r=-mov.ie" items="${1i;,...tE:J.ezent}" <td>${llICIVie}</td> '-</c:f:~~ </c:forEach> lIJoo. {(as fi.:N.js. .j"nll1\ (I:!-""jV;,,!DS

>

5i!"'!~5 5tte

'u fI,+"tJ,,,,+a

/"* exhl'~c.

MatrL,,{Ievoiutions

!:so,!h"''''f,,''~iro s,'''''J,n---'7'j

KillBilI BoondockSaints melie ReturnoflheKing MeanGirls

xv

Quando nem a JSTL o bastante ...

10

Em alguns casos, a JSTL e as aes-padro no so suficientes. Quando voc precisa de algo customizado, e no quer voltar aos velhos scripts, voc pode escrever os seus prprios tag handlers. Dessa maneira, os seus desenvolvedores de pginas podero usar a sua tag nas suas pginas, enquanto todo o trabalho duro feito nos bastidores, na sua classe tag handler. Mas h trs maneiras diferentes de se criar os seus prprios tag handlers, ento, h muito o que aprender. Dessas trs, duas foram introduzidas com o JSP 2.0 para tomar a sua vida mais fcil (Simple Tags e Tag Files). Objetivos do Exame Tag Files: iguais ao include, s que melhores Onde o Container procura por Tag Files Tag handlers simples Uma tag Simples com um corpo E se o corpo da tag usar uma expresso? Voc ainda precisa saber sobre os tag handlers Clssicos Um tag handler Clssico bem pequeno O ciclo de vida Clssico depende dos valores retomados A interationTag lhe permite repetir o corpo Valores-padro retomados pela TagSupport A interface DynamicAttribute Com BodyTag, voc tem dois novos mtodos E se voc tiver tags que funcionam conjuntamente? Usando a API PageContext para tag handlers 500 502 509 513 514 519 529 531 536 537 539 556 563 567 577

Distribuindo sua aplicao web

11
Refernciaaumbeanlocal

Finalmente, sua aplicao est pronta para o horrio nobre. As suas pginas esto finalizadas, seu cdigo est testado e ajustado, e o prazo de entrega era h duas semanas atrs. Mas, para onde vai isso tudo? Tantos diretrios, tantas regras. Que nome voc d aos seus diretrios? Qual nome o cliente pensa que eles tm? O que que o cliente realmente solicita, e como o Container sabe onde procurar? Objetivos do Exame Principal tarefa da distribuio: onde entra o qu? Arquivos WAR ~ Como o mapeamento de servlets REALMENTE funciona Configurando arquivos de boas-vindas no DD =~?::::::~;~:::. Configurando pginas de erro no DD ~ __ ~ Configurando a inicializao de servlets no DD um JSP compatvel com XML: um Documento JSP ~" 602 603 612 616 622 626 628
629

-Criando

XVI

contedo

Mantenha em segredo, mantenha seguro

12
'Iil
lJmpaucomais deprtirocomXML

Sua aplicao web est emperigo. O perigo espreita em cada canto da rede. Voc no quer os Caras Maus xeretando nas transaes da sua loja virtual, roubando nmeros de cartes de crdito. Tambm no quer os Caras Maus convencendo o seu servidor de que eles na verdade so os Clientes Especiais Que Recebem Grandes Descontos. E voc no quer ningum (amigo OU inimigo) olhando dados confidenciais dos empregados. Ser que o Jim, do departamento de marketing, precisa mesmo saber que a Lisa, do departamento de engenharia, ganha trs vezes mais do que ele?
Sua

As Dez Melhores Razes para realizar a segurana declaratwamente


11rJfazmal

a 11ingum.

Objetivos do Exame O Top 4 em segurana de servlets Como Autenticar no Mundo HTTP

650 653 656

O :~:U~::te,

e e

as.~eclaraes casamnaturalmente deparrame;oSd~~ ':mp~O) j existentesno

Fica multo bem no seu curriculo.

o ~~:: ::j~~:ma ~;~~asmais


G Est no exame. O legal, simplesmente.

flexveis,

As Dez Melhores Razespara realizara sua seguranadeclarativamente 659 Quem implementa a segurana em uma aplicao web? Autorizao: funes e restries Autenticao: quatro sabores OS QUATRO tipos de autenticao Protegendo a segurana dos dados em trnsito: HTTPS em ao Como implementar confidencialidade a caso e declarativamente 660 662 677 677 682 e integridade de dados caso 684

Permite aos dcsenvoh-edores de aplicaes IeUtJlizarem senlets, mesmo sem acesso ao cdigo-fonte.

o poder dos filtros

13

Os filtros lhe permitem interceptar a solicitao. E se puder interceptar a solicitao, voc poder tambm controlar a resposta. E, melhor de tudo, o servlet nem percebe o que aconteceu. Ele nunca ficar sabendo que algum intercedeu entre a solicitao do cliente e a invocao do mtodo serviceO do servlet pelo Container. O que isso significa para voc? Mais frias. Porque o tempo que voc levaria reescrevendo apenas um dos seus servlets pode ser despendido, em vez disso, escrevendo e configurando um filtro com a capacidade de afetar todos os seus setvlets. Adicionar tracking das solicitaes do usurio a todos os servlets da sua aplicao? Sem problema. Manipular o output de cada servlet da sua aplicao? Sem problema. E voc no precisa nem sequer tocar no cdigo do servlet. Objetivos do Exame 702 707 708 710 713 719 722 724

--_ ....
181'"
a pilha a pilha

Construindo um filtro para o monitoramento das solicitaes O ciclo de vida de um filtro

Declarando e ordenando filtros Comprimindo o output com um filtro no lado da resposta

a pilha

o Conta;tle<"

a pilha

a pilha

""'P<Jn"otrltodo ~i<eOdo SleM I""" o

~;::o::-,. Os wrappers so demais

~~::~~~
fircl,m-.e ""tilo,; ",t;rndodo.pilll<l.

i::: O cdigo do verdadeiro filtro de compresso


Conta;ner-nMlQa respost"-

Cdigo do wrapper de compresso

XVII

Padres de Design Enterprise

14

Algum j fez isso antes. Se estiver comeando agora a desenvolver aplicaes web em Java, voc tem sorte. Poder se beneficiar do saber coletivo das dezenas de milhares de desenvolvedores que j trilharam esse caminho e sobreviveram para contar. Usando tanto os padres de design especficos do J2EE quanto outros padres, possvel simplificar o seu cdigo e a sua vida. E o padro de design mais significativo para aplicaes web, o MVC, possui at mesmo um framework absurdamente popular, o Struts, que ajudar voc a criar um servlet Front Controller flexvel e de fcil manuteno. Voc deve a si mesmo tirar vantagem do trabalho dos outros para que possa despender mais tempo nas coisas mais importantes da vida ... Objetivos do Exame O poder do hardware e do software por trs dos padres Reviso dos princpios do design de software... Padres para dar suporte a componentes de modelos remotos Viso geral da JNDI e da RMI O Business Delegate um "intermedirio" 738 739 744 745 747 753

Simplifique os seus Business Delegates com o Service Locator 759 Hora de usar um Transfer Object? Nosso primeiro padro revisitado ... MVC Sim! o Struts (e o Front Controller), em poucas palavras Refatorando a aplicao Beer para o Struts Reviso sobre padres 761 762 767 770 778

fausa pata cat


o Teste Preparatrio
final. isso, 69 perguntas. A aparncia, os assuntos abordados e o nvel de dificuldade so praticamente idnticos aos da prova oficial. Ns sabemos. Teste preparatrio final Respostas 791 828

ndice

865

XVIII

Introduo

Como usar este livro?

Use a Cabea JSP

A quem se destina este livro?


Se voc responder "sim" a todas estas perguntas:

(1) Voc

sabe Java? (no precisa ser um guru)

Voc gosta de consertar - voc aprende


aprender, compreender, for Java EE 1.5? lembrar

fazendo, ao invs de apenas ler? Voc deseja dos servlets e dos JSPs e passar no exame SCWD

Voc prefere

uma conversa descontrada graa e tediosas este livro para voc.

em uma festa a palestras

acadmicas

sem

este livro no para voc.

Quem provavelmente deveria manter-se longe deste livro?


Se voc responder "sim" a alguma destas perguntas:

(!) Voc totalmente

inexperiente em Java? Voc no precisa estar em um nvel avanado, mas, definitivamente, deve ter alguma experincia. Se no tiver, pegue um exemplar do Use a Cabea! Java agora mesmo. Hoje! E s ento retome a este livro.

Voc um desenvolvedor Voc um veterano


@ Voc tem medo

Java "forado" em busca de um livro de consulta?

em J2EE em busca de tcnicas ultra-avanadas e "como-fazer" especficos para servidores, projetos para empresas e cdigos complexos, robustos e reais?

de experimentar coisas diferentes? Voc prefere fazer um canal no seu dente a misturar listras num tecido xadrez? Voc acha que um livro tcnico perde a credibilidade se os componentes Java tiverem aparncia humana?

este livro no para voc.

xx

introduo

Ns sabemos o que voc est pensando.


"Como este livro de programao pode ser srio?" "Com tantas ilustraes?" "Eu consigo realmente aprender desta forma?"

E ns sabemos o que seu crebro est pensando.


Seu crebro clama por novidades. Est sempre procurando, examinando e esperando por algo diferente. Ele foi criado assim e o ajuda a se manter vivo. Atualmente, pouco provvel que voc vire o lanchinho de um tigre, mas seu crebro continuar em alerta. Nunca se sabe. Ento, como seu crebro faz para lidar com todas as coisas rotineiras, comuns e normais com as quais voc se depara? Tudo o que ele puder fazer para impedir que tais coisas interfiram no seu real trabalho: registrar o que interessa. No faz mal guardar as coisas fteis; elas nunca passaro pelo filtro que retm o que "obviamente no importa". Como seu crebro reconhece o que importante? Suponha que voc tire um dia para fazer uma caminhada e um tigre pule na sua frente. O que acontece com a sua cabea e o seu corpo? Os neurnios disparam. As emoes so ativadas. As reaes qumicas explodem. E assim que seu crebro reconhece ...

Isto pode ser importante! No esquea!


Mas, imagine que voc est em casa, ou em uma biblioteca. um local seguro, acolhedor e sem tigres. Voc est estudando. Preparando-se para um exame. Ou tentando aprender um assunto tcnico e difcil, que seu chefe acredita que levar uma semana, dez dias no mximo. S um problema. Seu crebro est tentando lhe fazer um grande favor. Ele est tentando assegurar-se de que aquele contedo, obviamente irre1evante, no v confundir os poucos recursos. Recursos estes que seriam melhores se usados para armazenarem coisas realmente importantes. Como tigres. Como o perigo do fogo. Ou como voc nunca mais deveria praticar snowboard de short. E no existe um jeito simples de dizer ao seu crebro, "Ei crebro, muito obrigado, mas no importa se o livro tedioso, ou o quanto estou registrando agora na escala Richter emocional, eu realmente quero que voc guarde estas coisas por aqui."

voc est

XXI

Use a Cabea JSP

Ento, o que necessrio para se aprender algo? Primeiro, voc precisa absorver e depois se certificar de que no ir esquecer. No tem nada a ver com enfiar coisas na sua cabea. Baseando-se nas ltimas pesquisas em cincia cognitiva, neurobiologia e psicologia educacional, o ato de aprender envolve muito mais que textos em uma pgina. E ns sabemos o que faz o seu crebro funcionar.

Alguns princpios de aprendizagem da srie Use a Cabea:


D nfase parte visual. As imagens so muito mais fceis de serem memorizadas do que palavras soltas e tomam o aprendizado muito mais produtivo (aumenta em at 89% a memria e o aprendizado usando a tcnica da transferncia). E facilita a compreenso. Ponha as palavras dentro ou prximas s respectivas figuras, em vez de no rodap ou em outra pgina e os leitores sero at duas vezes mais capazes de solucionar os problemas relacionados com aquele contedo.
precisa chamar um

Use um estilo prprio e em forma de conversa. Em estudos recentes, o desempenho dos alunos nas provas realizadas aps aprenderem a matria, melhorava em 40% se o contedo falasse diretamente ao leitor usando a primeira pessoa, com um estilo que simulasse uma conversa em lugar do tom formal. Conte histrias em vez de dar palestras. Use a linguagem coloquial. Evite ser muito srio. Em que voc prestaria mais ateno: em uma companhia interessante na festa ou em uma palestra?

mtodo no servidor

servio
remoto
RMI

Faa o aluno refletir. Em outras palavras, nada acontece na sua cabea a menos que voc exercite muito os seus neurnios. O leitor precisa estar motivado, atrado, curioso e inspirado para resolver problemas, tecer concluses e gerar um novo conhecimento. E para isso voc precisa de desafios, exerccios e perguntas que estimulem o raciocnio, alm de atividades que envolvam ambos os lados do crebro e os mltiplos sentidos. Prenda - e segure - a ateno do leitor. Todos ns j pensamos "eu realmente gostaria de aprender isto, mas eu no consigo me manter acordado depois da primeira pgina". Seu crebro presta ateno a coisas roam () ; que so extraordinrias, interessantes, estranhas, atraentes e inesperadas.
f,
c.M !)WI

abstrac

Aprender um assunto novo, difcil e tcnico no precisa ser chato. Seu crebro aprender muito mais rpido se o assunto for interessante.

pM'l.fb-rV!i!'5Udi,

Mexa com a emoo do leitor. Agora ns sabemos que sua capacidade de recordar algo depende enormemente do seu contedo emocional. Aquilo que voc se preocupa, voc se recorda. Voc se recorda quando sente algo. No, ns no estamos falando de histrias de sofrimento entre um menino e seu co. Estamos falando de emoes como a surpresa, a curiosidade, a diverso, o "caramba!. .." e aquela sensao de "Eu sou o cara!" que vem quando voc consegue matar uma charada, aprender algo que todos acham difcil ou perceber que sabe uma coisa que o "bam-bam-bam" da engenharia no sabe.

XXII

introduo

Metacognio:

pensando sobre pensar

Se voc realmente quer aprender - e aprender mais rpida e definitivamente -, preste ateno em como voc presta ateno. Pense em como voc pensa. Aprenda como voc aprende. A maioria de ns no fez cursos de metacognio ou teoria do aprendizado enquanto crescia. Esperam que aprendamos, mas raramente nos ensinam a aprender. Supomos que se voc est segurando este livro, voc quer aprender servlets e, provavelmente, no quer perder muito tempo. Considerando que voc far a prova, voc ter que lembrar do que leu. Logo, precisa entender o que foi lido. Para obter o mximo deste livro - ou de qualquer outro livro ou forma de aprendizado -, d responsabilidades ao seu crebro. Faa-o ficar atento a este contedo. O truque fazer com que seu crebro encare como Realmente Importante o novo material que voc est aprendendo. Crucial para o seu bem-estar. To importante quanto um tigre. Caso contrrio, voc estar constantemente em conflito, com o seu crebro dando o melhor de si para no assimilar o assunto novo.

Ento, como voc FAZ para que seu crebro considere os servlefs um tigre faminto?

Existem as formas lenta e tediosa e a mais rpida e efetiva. A forma lenta a pura repetio. claro que voc sabe que ser capaz de aprender e relembrar at mesmo o assunto mais estpido se o ficar repetindo. Com uma repetio intensa seu crebro diz, "isto no parece importante para ele, mas ele fica olhando para a mesma coisa repetidamente, ento eu imagino que deva ser". A maneira mais rpida fazer qualquer coisa que aumente sua atividade cerebral, principalmente atividades de tipos diferentes. O que foi dito na pgina anterior uma grande parte da soluo e foi comprovado como forma de ajudar seu crebro a trabalhar em seu favor. Por exemplo, estudos demonstram que colocando as palavras dentro das figuras que elas representam (em vez de soltas na pgina, como uma explicao ou dentro do texto) faz com que seu crebro entenda como as figuras e as palavras se relacionam, ativando mais neurnios. Mais neurnios ativados significa mais chances do crebro entender que determinado assunto merece ateno e, possivelmente, deve ser registrado. O estilo interativo tambm ajuda, pois as pessoas tendem a prestar mais ateno quando percebem que esto em uma conversa, j que se espera que ela;s acompanhem at o final. O interessante que seu crebro no se importa necessariamente que a "conversa" seja entre voc e um livro! Por outro lado, se o estilo de escrever for seco e formal, seu crebro entender isso do mesmo modo que voc o faria se estivesse em uma palestra numa sala repleta de participantes indiferentes. Porm, as figuras e o estilo que simula uma conversa so s o comeo.

voc est

~ XXIII

Use

Cabea JSP

Eis

que NS fizemos:
Ro<:hd'~ttltf

Ns usamos figuras, pois seu crebro est adaptado ao que visual, no texto. Para ele, uma imagem vale 1.024 palavras. E quando figuras e textos trabalham juntos, ns inserimos o texto na imagem, pois seu crebro funciona melhor quando o texto est dentro daquilo a que se refere, diferente de estar numa observao ou escondido em algum lugar no texto. Ns usamos a repetio. Dizemos a mesma coisa de formas distintas e atravs de meios diferentes - e mltiplos sentidos -, para aumentar as chances de o assunto ser registrado em mais de uma rea cerebral. Ns usamos os conceitos e as figuras de maneira inesperada, pois seu crebro ativado quando encontra uma novidade. E usamos figuras e idias com pelo menos algum contedo emocional, pois seu crebro est predisposto a dar mais ateno bioqumica das emoes. Aquilo que te faz sentir algo tende a ser mais facilmente lembrado, ainda que esta sensao no passe de um pouco de humor, surpresa ou interesse. Ns usamos um estilo prprio que simula uma conversa, porque seu crebro tende a prestar maior ateno quando acredita que voc est participando d~ uma conversa e no assistindo passivamente a uma apresentao. E assim que funciona mesmo quando voc est lendo. Ns inclumos mais de 40 atividades, pois seu crebro est habituado a aprender e a relembrar mais quando voc faz alguma coisa do que quando voc l a respeito. E colocamos exerccios dificeis, porm possveis de serem feitos, pois como a maioria das pessoas prefere. Ns usamos mtodos diferentes de aprendizado, pois voc poderia preferir os procedimentos passo a passo, enquanto outra pessoa poderia preferir entender primeiro as figuras grandes, enquanto outras, simplesmente ver os exemplos de cdigos. Mas, independentemente da sua prpria preferncia de aprendizado, todos se beneficiam vendo o mesmo contedo representado sob mltiplas formas. Ns colocamos assuntos para serem usados por ambos os lados do seu crebro, pois quanto mais voc usar do seu crebro, mais chances ter de aprender e lembrar, alm de mais tempo de concentrao. J que colocando para funcionar um lado do crebro significa geralmente a oportunidade do outro lado descansar, voc poder produzir mais por mais tempo. E ns inclumos estudos de caso e exerccios que apresentam mais de um ponto de vista, pois seu crebro est adaptado a aprender mais intensamente, quando forado a fazer avaliaes e julgamentos.

W<wd<;::ligners~ Quthere ..

Ns inserimos desafios com exerccios e perguntas que nem sempre tm respostas diretas, pois seu crebro est mais propenso a aprender e lembrar quando tem que se esforar por algo. Pense nisso - voc no consegue manter seu corpo em forma apenas observando as pessoas na academia. Porem, ns fizemos o melhor possvel para garantir que, quando voc estiver trabalhando duro, ser pelas coisas certas. E que voc no estar desperdiando nenhum dendrito a mais, tentando entender um exemplo complicado ou analisando um texto dificil, repleto de jarges, ou ento, extremamente resumido. Ns usamos pessoas nas histrias, nos exemplos, nas figuras, etc. Afinal, voc uma pessoa e seu crebro d maior ateno a pessoas do que a coisas. Ns usamos a tcnica do 80/20. Entendemos que se voc pretende ser um PhD em JSP, este no deve ser seu nico livro. Logo, no falamos sobre tudo. Apenas da matria que voc realmente precisar.

XXIV

introduo

Eis O que VOC pode fazer para dominar seu crebro


Ento, fizemos a nossa parte. O resto com voc. As dicas a seguir so o ponto de partida. Preste ateno no seu crebro e descubra o que serve e o , que no serve para voc. Experimente novidades.
P/'r",
;

Jef!c/'h

! " f: C<J!Y4{1P "i!I ~" ,J1?1tJ;elf'tI. ().

(1) V

devagar. Quanto mais voc entender, menos ter que memorizar. No leia apenas. Pare e pense. Quando o livro perguntar algo, no pule para a resposta. Imagine que algum esteja realmente lhe fazendo a pergunta. Quanto mais voc forar o seu crebro a pensar, melhores sero as chaTIces de aprender e recordar. suas prprias

Fale. Em voz alta.


Falando, voc ativa uma parte diferente do crebro. Se voc estiver tentando entender algo ou aumentar sua chance de recordar mais tarde, leia em voz alta. Melhor ainda, tente explicar isto para outra pessoa em voz alta. Voc aprender mais rpido e talvez observe idias que voc no havia percebido que estavam ali enquanto lia.

Faa os exerCcios. Faa anotaes.

Q) Oua

Ns os colocamos no livro, mas se ns resolvermos, vai parecer que algum est fazendo a ginstica para voc. E no basta olhar os exerccios. Use um lpis. Est provado que a atividade fisica, enquanto se estuda, pode melhorar o aprendizado.

@) Leia

a seo "Perguntar no ofende". Ou seja, todas elas. Elas no so barras laterais opcionais. Elas s o parte do contedo principal! No as pule.

seu crebro. Observe se o seu crebro no est ficando sobrecarregado. Se voc se pegar passando a mo na superficie do livro ou esquecendo o que acabara de ler, hora de uma pausa. Uma vez que voc ultrapasse um determinado ponto, voc no aprender mais rpido se tentar "enfiar" mais informao na cabea e poder at comprometer o processo. algo! Seu crebro precisa saber que isto importante. Envolva-se com as histrias. Crie suas prprias legendas para as fotos. Dar um sorriso amarelo quando uma piada no tem graa ainda melhor do que no esboar reao. Final s DEPOIS

Sinta

@ Antes

de ir dormir, faa desta a sua ltima leitura. Ou pelo menos a ltima que lhe exija racioCnio. Parte do aprendizado (especialmente a transferncia para a memria de longa durao) acontece depois que voc fecha o livro. Seu crebro necessita do seu prprio tempo para maior processamento. Se voc puser uma informao nova durante este tempo de processamento, o que voc acabou de aprender ser perdido. gua. Muita gua. Seu crebro funcionar melhor se receber um belo banho. A desidratao (que pode . acontecer bem antes de voc sentir sede) reduz a funo cognitiva. A cerveja, ou algo mais forte, ser bem-vinda quando voc passar no exame.

de Faa o Teste Preparatrio acabar o livro.

@ Beba

Se voc fizer o teste muito cedo, voc no ter uma idia clara da sua preparao para o exame. Espere at sentir que voc est quase pronto e ento faa o teste em, no mximo, 135 minutos - o tempo verdadeiro doSCWCD.

voc est

XXV

Use a Cabea JSP

o que voc

precisa para este livro:

Alm do seu crebro e um lpis, voc precisa do Java, do Tomcat 5 e de um computador. Voc no precisa de nenhuma outra ferramenta de desenvolvimento como o Integrated Development Environment (IDE). Definitivamente, recomendamos que voc no use nada alm de um editor simples at terminar o livro. Um IDE que reconhece servlet e JSP poder priv-l o de algum detalhe realmente importante (e que cair na prova). Por isso, melhor voc evitar desenvolver todo o bean manualmente. Uma vez que voc realmente entenda o que est acontecendo, poder utilizar uma ferramenta que automatize alguns dos passos para a criao e distribuio do servlet/JSP. Se voc j sabe como usar o Ant, poder us-lo aps o captulo 3 para ajudar na distribuio. Porm, no recomendamos usar o Ant at que voc tenha memorizado completamente a estrutura de distribuio da aplicao web.
OBTENDO O TOMCAT --------,

Caso ainda no possua o Java SE v1.5 ou superior, voc vai precisar (de preferncia 1.4). Se voc no tem ainda o Tomcat 5, obtenha-o em: http://tomcat.apache.org/ Selecione "Tomcat v5.5" no menu Downloads no lado esquerdo da home page. Pagine at a seo "Binary Distributions" (Distribuies Binrias) e faa o download da verso escolhida. Se no souber, ento, selecione a distribuio "Core" (Bsico); tudo que voc precisa. Salve o arquivo de instalao em uma pasta temporria. Instale o Tomcat. Para Windows, d um duplo-clique no arquivo install.exe e siga as instrues do assistente de instalao. Para os outros sistemas, descompacte o arquivo de instalao no diretrio onde voc quer que o Tomcat resida. Para facilitar as instrues do livro, renomeie para "tomcat" o diretrio home do Tomcat (ou configure um cognome "tomcat" que aponte para o home verdadeiro do Tomcat). Configure as variveis de ambiente para JAVA_HOME e TOMCAT HOME, da mesma forma como voc normalmente faz em sua mquina. Voc deve ter uma cpia das especificaes, embora no precise delas para passar no exame. At o lanamento deste livro, as especificaes eram: Servlet 2.4 (JSR #154) http://jcp.org/eng/jsr/detail?id=154 JSP 2.0 (JSR #152) http://jcp.org/eng/jsr/detail?id=152 JSTL 1.1 (JSR #52) http://jcp.org/eng/jsr/detail?id=52 V at a pgina JSR e clique em Download Page para o lanamento mais recente. Teste o Tomcat rodando o script tomcat/bin/startup (startup. sh para os sistemas Linux/Unix/OSX). Digite na barra de endereos do seu browser: http://localhost:8080/ e voc ver a pgina inicial do Tomcat.
XXVI
.~

Java 2 Standard Edition 1.5 Tomcat 5 O exame abrange as seguintes especificaes: Servlets 2.4 JSP 2.0 JSTL 1.1

...

introduo

Coisas de ltima hora que voc precisa saber:


Isto uma experincia de aprendizado e no um livro de referncia. Ns retiramos deliberadamente tudo que pudesse atrapalhar o caminho do aprendizado, independentemente do que estejamos trabalhando no livro. E, desde o primeiro instante, comece do comeo, pois o livro faz consideraes quanto quilo que j foi visto e aprendido. Ns usamos diagramas simples e parecidos com UML. Embora exista uma grande chance de voc j saber UML, isto no cobrado no exame e no um pr-requisito para o livro. Ento, voc no ter que se preocupar em aprender servlets, JSP, JSTL e UML ao mesmo tempo. Ns no cobrimos todos os detalhes minuciosos da especificao. O exame muito detalhado, mas, ns tambm somos. Porm, se existe um detalhe na especificao que no cobrado no exame, s o citaremos se for importante para a maioria dos desenvolvedores de componentes. O que voc precisa saber para comear a desenvolver componentes web (servlets e JSPs), e o que precisa para passar no exame, cobre cerca de 85%. Ns inclumos algumas coisas que no caem na prova, mas sinalizamos para que voc no se preocupe em memoriz-Ias. Ns criamos o verdadeiro exame, portanto, sabemos onde voc dever concentrar sua energia! Se houver a possibilidade de um mnimo detalhe figurar em uma questo da prova, mas se o esforo para aprend-Io realmente no valha a pena, provavelmente ou o omitiremos, ou o abordaremos sucintamente, ou o colocaremos em uma questo do teste preparatrio. As atividades NO so opcionais. Os exerccios e as atividades no so meros adicionais; eles so parte do contedo principal do livro. Alguns esto l para ajudar na memorizao, outros para ajudar na compreenso, enquanto outros o ajudaro a aplicar o que voc aprendeu. No pule nada. A redundncia intencional e importante. Uma coisa que claramente diferente em um livro da srie Use a Cabea! que ns queremos muito, muito, muto que voc entenda. E gostaramos que voc terminasse o livro lembrando o que aprendeu. A maioria das informaes e dos livros de referncias no tem, necessariamente, a reteno e a lembrana como objetivos, mas aqui voc ver alguns conceitos aparecerem mais de uma vez. Os cdigos-exemplos so os mais resumidos possveis. Nossos leitores tm relatado o quanto frustrante ler minuciosamente 200 linhas de cdigos procurando por aquelas duas linhas que eles precisam. A maioria dos exemplos deste livro exibida dentro dos menores contextos possveis, para que a parte que voc precisa fique clara e simples. No espere que o cdigo seja robusto ou completo. Esta sua tarefa para quando terminar o livro. Os exemplos aqui so escritos especialmente para aprender e nem sempre so totalmente funcionais. Alguns exemplos de cdigo para o livro esto disponveis em www.altabooks.com.br

fJS{Ufl6S VI?,

fJMI-.

m~Ji/tllt:M.,lt~ f! h!4,(~

Diretor
getMovies getOscars getKevin BaconDegrees() ()

voc est aqui ~ XXVII

fazendo a prova

Sobre o exame SCWCD

(para Java EE

1.5)

exame SCWCD atualizado chamado de "Sun Certified Web Component Developer for Java Platform, Enterprise Edition 5" (CX-310-083), mas no fique confuso com o ttulo. O exame atualizado ainda designado para o Java EE vIA, para o servlet v2A e as especificaes JSP v2.0.

Primeiro tenho que passar no SCJP?


Sim. O exame Web Component Developer, exame Business Component Developer, exame Mobile Application Developer, exame Web Services Developer e exame Developer requerem que voc seja um Sun Certified Java Programmer.

Quantas questes?
Voc ter 69 questes quando fizer o exame. Ningum tem as mesmas 69 questes; existem muitas verses diferentes do exame. Mas todas tm o mesmo grau de dificuldade e o mesmo equilbrio de tpicos. No exame real, espere ver pelo menos uma questo do objetivo de cada exame e existem alguns objetivos nos quais voc ter mais de uma questo.

Quanto tempo tenho para completar o exame?


Voc tem trs horas (180 minutos). A maioria das pessoas no acha que isso um problema, pois essas questes no so longas, complicadas, complexas. A maioria das questes muito curta, tem mltipla escolha e voc sabe a resposta ou no.

Como so as questes7
Elas so quase exatamente como as nossas perguntas simuladas do exame, com uma grande diferena - o exame real informa-o quantas respostas esto corretas, ns no. Contudo, voc ver algumas perguntas do tipo arrastar e soltar que no podemos fazer aqui. Mas as questes com arrastar e soltar so apenas o modo interativo de coincidir uma coisa com outra.

Quantas tenho que responder corretamente?


Voc deve ter 49 questes corretas (70%) para passar no exame. Quando terminar de responder a todas as questes, mantenha o cursor do mouse sobre o boto Done (Terminado) at que tenha coragem de clic-Io. Em cerca de seis nanossegundos, voc saber se passou (claro, voc passar).

Por que os exames simulados no livro no informam quantas opes escolher para a resposta correta?
Queremos que nossos exames sejam apenas um pouco mais difceis que o exame real, para lhe dar uma idia mais verdadeira para saber se voc est pronto para fazer o exame. As pessoas tendem a ter notas mais altas nos exames simulados do livro porque refazem o mesmo teste mais de uma vez e no queremos que voc tenha uma falsa sensao de sua aptido para o exame. Os leitores tm informado que a pontuao consegui da no exame real muito prxima da pontuao que eles tm no exame simulado final neste livro.

XXVIII

introduo

o que acontece

depois de fazer o exame?

Antes de deixar o centro de teste, obtenha o relatrio de seu exame. Ele mostra um resumo de sua pontuao em cada rea maior e se passou ou falhou. Guarde-o! sua prova inicial de que voc foi certificado. Em poucas semanas depois do teste, voc receber um pequeno pacote da Sun Educational Services que inclui seu certificado impresso real, uma carta de felicitao da Sun e um adorvel alfinete de lapela informando Sun Certified Web Component Developer em uma fonte to pequena que voc poderia declarar ser certificado em qualquer coisa que quisesse e ningum poderia ler para saber a diferena. No inclui a bebida alcolica que voc estar querendo depois de passar no exame. Quanto custa e como me registro? O exame custa US$200. E por isso que voc precisa deste livro ... para assegurar que passar na primeira vez. Voc registra-se atravs do Sun Educational Services, fornecendo o nmero de seu carto de crdito. Em troca, receber um nmero de voucher, que usar para agendar um encontro em um Prometric Testing Center mais prximo de voc. Para obter detalhes on-line e comprar um voucher do exame, comece em:bttp://www.sun. com/training/certificationi. Se estiver nos Estados Unidos, estar marcado. Se no, poder selecionar um pas na barra de menus Como o software do exame? bem simples de usar - voc tem uma questo e responde-a. Se no quiser responder, poder pul-Ia e voltar para ela mais tarde. Se a responder, mas no estiver certo e quiser voltar para ela se tiver mais tempo, poder "marcar" uma questo. Assim que tiver terminado, ver uma tela que mostra todas as questes que voc no respondeu ou marcou, para que possa voltar para elas. Bem no incio do exame, voc obter um pequeno tutorial sobre como usar o software, onde conseguir um pequeno teste prtico (no sobre Servlets). O tempo gasto no tutorial no conta como o tempo gasto no exame SCWCD. O relgio no iniciar at que voc tenha terminado o tutorial do software de exame e estiver pronto para comear. Onde posso encontrarum grupo de estudo e quanto tempo levar para me preparar? O melhor grupo de anlise on-line para este exame aquele que os autores presidem! (Deus, quais so as probabilidades?) Pare em j avaranch. com e v para Big Moose Saloon ( onde esto todos os fruns de discusso). Voc no pode perder. Sempre haver algum para responder suas perguntas, inclusive ns. JavaRanch a comunidade Java mais amistosa na Internet, portanto, voc ser bem-vindo no importando o nvel em que estiver no Java. Se voc ainda precisar ter o SCJP, iremos ajud-Io com ele tambm. Quanto tempo leva para ficar pronto para o exame depende muito de quantos servlets e experincia JSP voc tem. Se voc for novo. nos servlets e no JSP, poder precisar de 6 a 12 semanas, dependendo de quanto tempo pode dedicar a cada dia. Aqueles com muitos servlets recentes e experincia JPS geralmente podero estar prontos em at trs semanas.

direita.

voc est

~ XXIX

a equipe de revisores

Beta testers & Revisores Tcnicos

lA"fi.iS

d"'$

f . u de
f>4!JJ'"

~a,beld$!JT'rt.b'Jc'(';s
Cwsa

desh

Itvrc,

IV';" 1"+(;5f'~f~d", ("'4S +'

''''Prhwl-e

"$ "'1I+r"s)
/1-",1'+

&1/4",1-"
-I

L"",dhe

de: J""'5

---.----/

A"drew

1Lf.""k/,{Jtlse

fl.ee,l-ish

lA.adafta

(~

XXX

introduo

introduo J.tU' ct'~J.t.f<}

Outras pessoas a quem ~:


Na O'Reilly: Nossos maiores agradecimentos a Mike Loukides na O'Reilly, por iniciar tudo e ajudar a dar forma ao conceito Use a Cabea em uma srie. Adoramos ter um editor que um Verdadeiro Java. E um grande agradecimento fora motriz por trs do Use a Cabea, Tim O'Reilly. Felizmente para ns, ele sempre est pensando no futuro e gosta de ser uma influncia destruidora. Obrigado a Kyle Hard "a mame da srie" Use a Cabea inteligente por descobrir como o Use a Cabea encaixa-se no resto dos livros de computador. Nossos revisores intrpidos: Tudo bem, ento, o livro levou um pouco mais de tempo do que tnhamos planejado. Mas sem o gerente de reviso JavaRanch Johannes deJong, ele teria ficado assustadoramente atrasado. Voc nosso heri, Johannes. E nossos agradecimentos especiais a Joe Konior cujo feedback em cada captulo foi quase do mesmo tamanho do captulo. Estamos profundamente agradecidos pelo esforo inexorvel e experincia (e alegria) de Philippe Macquet. Todos os trs autores adoram-no tanto que queremos casar com ele ... mas isso seria estranho. E estamos muito gratos a Andrew Monkhouse pelo feedback tcnico e ajuda nas tradues sutis do ingls para a lngua australiana. Jef Cumps, sua interpretao MP3 da cano "setHeader" foi impressionante (exceto talvez por ser um pouco emo) e seus comentrios tcnicos foram realmente teis. Dave Wood trabalhou com afinco em tudo e foi carinhoso ao apontar para as primeiras pginas e dizer: "Isso no o estilo Use a Cabea". Tambm tivemos um feedback excelente dos moderadores JavaRanch Jason Menard, Dirk "cara de peixe" Shreckmann, Rob Ross, Ernest Freidman-Hill e Thomas Paul. E como sempre, agradeo especialmente ao chefe javaranch.com, Paul Wheaton.

Agradecimentos especiais aos seguintes revisores tcnicos pela segunda edio: Bear Bibeault, Theodore Casser, UlfDittmer, Preetish Madalia, Sergio Ramirez, Oliver RoeU, Neeraj Singhal e Collins Tchoumba. Perguntas do examine simulado Se voc se encontrar balanando a cabea em uma questo simulada JSP particularmente capciosa, no nos culpe - culpe Marc Peabody! Obrigado Marc por ajudar a manter todos os candidatos SCWCD em alerta. Marc passa uma quantidade enorme de seu tempo livre moderando no JavaRanch, onde conhecido por estimular os usurios Ranch a construir misturas horrveis de suas tecnologias Java EE inocentes.

voc est

~ XXXI

mais reconhecimentos

Tem mais gente ainda*


Por Bryan Basham Eu poderia comear agradecendo minha me, mas isso j foi feito antes ... Meu conhecimento em desenvolvimento web com Java tem como base algumas aplicaes de mdia escala que escrevi, mas esta base foi melhorada e refinada por anos de debate em Java como instrutor da Sun, usando um e-mail com um nome fictcio. Em particular, gostaria de agradecer a Steve Stelting, Victor Peters, Lisa Morris, Jean Tordella, Michael Judd, Evan Troyka e Keith Ratliff. Muitas pessoas ajudaram a lapidar meu conhecimento, mas estes seis foram as facas que melhor me esculpiram. Como em todos os projetos de livro, os ltimos trs meses foram muito dificeis. Gostaria de agradecer minha noiva, Kathy Collina, por ter sido paciente comigo. Eu quero agradecer a Karma e Kiwi (nossos gatos) pelas sesses de lambidas tarde da noite e as pancadas no teclado. Por ltimo, e mais importante, tenho que agradecer Kathy e ao Bert por sugerirem que levssemos adiante o projeto. Kathy Sierra mesmo nica no mundo. Seu conhecimento em metacognio e design educacional s se comparam sua essncia criativa que transborda nos livros desta srie. Eu tenho trabalhado com educao h cinco anos e praticamente tudo o que aprendi foi com a Kathy ... Oh, no se preocupe com minha me; ela receber uma grande dedicatria em meu prximo Use a Cabea!. Eu te amo, me!

Por Kathy e Bert Isso foi to sentimental, Bryan, ohhhh ... (No que a Kathy no goste de rasgar uma seda). Mas, concordamos quando fala sobre sua noiva. Mas no por ela ter sentindo saudades suas, enquanto jogava Ultimate o vero todo e ns trabalhvamos feito cachorro em nossos Powerbooks 1. Mas voc realmente fez disso uma experincia recompensadora, Bryan, e hoje o melhor(NA) co-autor que j tivemos! Chega quase a assustar o quanto voc calmo e feliz o tempo todo. Todos ns adoramos a equipe que trabalha duro nos exames de certificao da Sun, em especial a Gerente de Certificao em Java, Evelyn Cartagena. Queremos agradecer tambm a todos os colegas que ajudaram a desenvolver as especificaes dos JSRs para Servlet e JSP.

* grande nmero de agradecimentos porque estamos testando uma teoria de que todos os mencionados na seo de agradecimentos do livro compraro pelo menos uma cpia, talvez mais, contando os parentes e tudo. Se voc quiser estar na seo de agradecimentos do nosso prximo livro, e se tiver uma famlia grande, escreva-nos.
1

Ponto de esclarecimento: O Bryan foi o nico co-autor que ns tivemos, mas isto no diminui em nada a nossa inteno.

XXXII

Por que usar Servlets & JSPs?

As aplicaes web esto na moda. Claro, as aplicaes GUI podem usar aquelas coisas exticas do Swing, mas quantas aplicaes GUI voc conhece que so usadas por milhes de usurios em todo o mundo? Como desenvolvedor de aplicaes web, voc no precisar se prender aos problemas de distribuio presentes em toda aplicao standalone e ir distribuir sua aplicao a qualquer pessoa que possua um browser. Porm, para construir uma aplicao web poderosa mesmo, voc precisa do Java. Dos servlets. Dos JSPs. Pois as velhas e estticas pginas HTML so to, digamos, "1999". Hoje, os usurios esperam por sites dinmicos, interativos e customizveis. Aqui, voc aprender como mudar do site na web, para a aplicao na web.

este

um

novo ca~)tuio

objetivos do exame oficial da Sun

Viso geral dos Servlets & JSP


1.1 Para cada um dos Mtodos HTTP (como GET, POST, HEAD e assim por diante):
Descrever os beneficios do Mtodo HTTP Descrever as funcionalidades do Mtodo HTTP Listar os triggers que podem levar um Cliente (geralmente um browser) a usar o mtodo Tambm jaz parte do Objetivo 1.1, mas no ser abordado neste captulo: Identificar o mtodo HttpServlet que corresponda ao Mtodo HTTP

Notas sobre a Abrangncia:


Os objetivos deste captulo so abordados completamente em outro captulo, ento, considere este captulo como uma base, em primeira mo, para o que vir adiante. Em outras palavras, no se preocupe em terminar este captulo sabendo (e lembrando) de itens especificos destes objetivos; apenas use isto como uma base. Se voc j domina estes assuntos, poder simplesmente dar uma olhada rpida e passar para o captulo 2.

Voc no encontrar nenhuma pergunta no teste prtico sobre estes assuntos at que voc chegue ao captulo mais especifico, onde eles sero abordados.

2 capitulo 1

introduo

e arquitetura

rodos queretM UtM website Voc tem uma idia fantstica para um website. Para aniquilar com os concorrentes, voc precisa de uma arquitetura flexvel e escalonvel. Voc precisa de servlets e JSPs. Antes de comearmos a construo, vamos dar uma olhada na rede mundial de computadores, a uma distncia de aproximadamente 40k ps. O que mais nos importa neste captulo como os clientes e servidores web se comunicam entre si. Provavelmente, as muitas das pginas a seguir sero uma reviso para voc, principalmente se voc j um desenvolvedor. Contudo, teremos a chance de definir algumas das terminologias que usaremos no decorrer do livro.

A- we!I c4"Sls-!--f: (,/sa"dlJ Sa.lard redes

f!1t\

;l!t.;;es
lJ

de clte".f-es
llA.o;llla
{}V 6

brlJWSfJ'SCtl""lJ
fi!

serllt;/{}rff!S

(;'6;/0.";/6 apUctlj;;es 1JI)SS6 "''de+tv6

C61t\tl6 A-ptlct.e);

ClJ"ec.f-a;/lJS tl+NJ.V;S ;/e

ClJlt\Iltl e wtreless.

; ClJ"s.f-I'Vll' Vlt\tl tlpllca{6 ave lJS clle,,-I-es 44 red41' ;/6 It\V,,;/lJ p6S S8..." tlces sal'. "S +6N78.1''''''S es.f-vpt;/lJ..."e,,-I-e rlcf/'JS.

Cliente

a terra

voc est aqu

I;

servidor Web

o que

o seu servidor web faz?

Um servidor web recebe uma solicitao e devolve algo para o cliente. Um browser permite ao usurio solicitar um recurso. O servidor pega a solicitao, encontra o recurso e retoma com algo para o usurio. Algumas vezes este recurso uma pgina HTML. Outras, umafigura. Ou um arquivo de som. Ou at mesmo um documento PDF. No importa - o cliente solicita uma coisa (recurso) e o servidor a envia de volta. A menos que o recurso no esteja l. Ou pelo menos, no est onde o servidor esperava encontr-Io. Certamente, voc j est bem familiarizado com o erro "404 Not Found" - a resposta que voc recebe quando o servidor no pode encontrar o que ele acha que voc solicitou. Quando dizemos "servidor", estamos querendo dizer ou a mquina fsica (hardware), ou a aplicao do servidor web (software). Ao longo do livro, se a diferena entre o hardware e o software do servidor importar, ns diremos explicitamente a qual dos dois (hardware ou software) nos referimos.

/} sali'cl.fa{i6

J6 clle~

C611#1VI ()

l1lVle e el1Jel"eS6 (li. (J}t.f-); JIJ.3l1t1fJ alie fJ cltewh! es.f: fl"6ClIl"lJ.l1Ja.

~ ~ C3" ~ 6 sel'vti/tJl" bel"fi./lVlel1h; hlVl IVIlIt-.f6 C6#1htdtJ


fbJe seI' 1Vlfi.I1JI.Jb ffi.NJ.
tJ

/ lISVfJ.l't'"b.tsh

1__.1 (;tJ#1-rrtllJfJ

f6Je ser f~''''fJ.S; JPbs e <':Jv.fl"<':Js l'eCVI'SfJs.

\
Ja
sel"lI,i/t'J1" C6#1#1VI a !ve
tJ

/} l"espas.ffJ.

J.oclIlVlel1.fa vel"JaJell'tJ

dtewh

stJlicr.f6l1 (6V VIVI C:iiil51) de el"l" se I) feJti/6 1146fvJel'sel" fl"l)cessad6).

introduo

e arquitetura

o que UtM cliettte web

faz?

Um cliente web permite ao usurio fazer solicitaes ao servidor, exibindo para ele o resultado do pedido. Quando falamos em clientes, no entanto, geralmente queremos dizer ao mesmo tempo o usurio e o browser (ou um dos dois) . O browser o software (como o Netscape ou o Mozilla) que sabe se comunicar com o servidor. A outra grande tarefa do browser interpretar o cdigo HTML e exibir a pgina ao usurio. Ento, a partir de agora, quando usarmos o termo cliente, geralmente no nos preocuparemos se estamos falando do usurio ou do browser. Em outras palavras, o cliente o browser jazendo aquilo que o usurio solicitou.

o usurio
~

clica em um

link no browser.

o browser
solicitao o servidor.

formato

o servidor

encontra

e a envia para

a pgina solicitada.

. 'P:

------=7
Browser

G1J

I. I ;\"1'"
Usurio Servidor

o browser
formato usurio.

consegue o HTML e o traduz em visual para o

o servidor

formato

resposta e a envia para o cliente (browser).

-~I~I
Servidor
voc est aqui ~ 5

HTMLeHTTP

Os clietttes e os servidores conhecel\t HfML e HffF

HTML
Quando um servidor responde a uma solicitao, ele geralmente envia algum tipo de contedo para o browser, para que este possa exibi-Io. Os servidores geralmente enviam instrues para o browser escritas em HTML (HyperText Markup Language). O HTML diz ao browser como apresentar o contedo ao usurio. Todos os browsers sabem o que fazer com o HTML, embora algumas vezes um browser mais antigo possa no entender partes de uma pgina que tenha sido escrita usando as verses mais recentes do HTML.

o B1ML

Int9tma a9

bt9"'v\Tset C9m9 e)blt 9

;d9 a9 Usuatl9. ;c c9nteU


HTTP
A maioria das conversas que ocorre na web entre clientes e servidores mantida atravs do protocolo HTTP, que possibilita conversas de request e resposta simples. O cliente envia uma solicitao HTTP e o servidor retoma uma resposta HTTP. Concluso: se voc um servidor web, voc fala HTTR Quando um servidor envia uma pgina HTML ao cliente, o faz usando o HTTP. (Voc ver os detalhes de como tudo isto funciona nas prximas pginas.) (Para Sua Informao: HTTP significa Protocolo de Transferncia de Hipertexto.)

o BTTP

9 pt9t9c919 'Lue 95

clIentes e 9S set""Id9tes usam patq se C9munkatem.

USq9 BTTP pata en""'i!U' 9 B1ML W clIente.

o set""ld9t

6 capitulo 1

introduo e arquitetura

G-uia rpido de

HfML

Quando voc desenvolve uma pgina, voc usa o HTML para descrever que aparncia a pgina deve ter e como deve se comportar.

o HTML tem dzias de tags e centenas de atributos de tag. O objetivo do HTML , a partir de um documento texto, adicionar tags que diro ao browser como format-Io. Abaixo esto as tags que usaremos nos diversos captulos a seguir. Se voc precisar de um conhecimento completo em HTML, recomendamos o livro HTML & XHTML The Definitive Guide.
Tag
<!<a> <align> ~>

Descrio onde voc pe seus comentrios ncora - geralmente para colocar um hyperlink alinha os comentrios esquerda, direita, centralizado ou justificado

<body> <br> <center> <form>

define os limites do corpo do documento pular linha centraliza o contedo define um formulrio

(1'c/IliCQ.llle/ll+ej <.ce/ll+el'")

Q.S

e <.aIi5/1l") Cf).II'f).1IIt

'" (que geralmente

elll oferece

fesustJ

ctJll'I a

'i.0)
sel'elllt st.l'elt'l

lIItas eS+Q.lllttJs

um campo para a entrada de dados)


<hl> <head> <html> <input <p> <title> type>

uSQ./IlftJ-as elllt /IltJS StJS eXt!.l!'\fi(JS;

o cabealho de primeiro nvel define os limites do header do documento define os limites do documento HTML define um tipo de entrada em um formulrio um novo pargrafo o ttulo do documento HTML

1t'141"$

sil!'\fles

llilfJ.S

ft. StJ4S

l'espec+tv4S

a.f

p61'ZUe

Il es-ra

asvl

IfrM~,)

voc est

escrevendo HTML

o que voc
(o HfMU

escreve ...

Imagine que voc est criando uma pgina de login. O HTML simples poderia se parecer com isto:

<html> <!- Um HTML <head> <title>A </head> <body> Login Page</title> exemplo - >

4::--

{J1f\

Ce.lf!ifl1+:1'/4 /frML

tt +~<.I~> es+:
de viria

fJ.11/"I1t.adfJ. del1+l't:.

+~<.a.lijl1> de tfJ.I':51'fJ.1t:.;
(Lelrlbl'ese; lf!iitS Je

4 11t\ de c/e.C41' ti 1t\~elf!i IrItu's V


Login Page</hl>

<hl align="center">Skyler's

If!ifl14S lJl1de 3vel'flrl.s'. fJ.

<p align="right"> <img </p> src~"SKYLER2.jpg"

<form

action="date2"> Name: <input <input

width="130"

height="150"/>

+~<'Q.1I511> tCfJJv flrl JfSVS(J;


ser

Jeci/ihl.lJS vSQ-la tlJl' seI' !Ma)

sl~/es

() sel"vld

pal'a.

3Va./
A's +~S ~tfJ.f'fI. tV/lU' sel'velrl h"l1t.as.

el1i1I&lI'f!1rI6Sa. s()llct+fJ.f'li4.

type~"text" type="text

name~"paraml"/><br/> 'ame="param2"

Password:

I><br I><br I><br I>


1a./aN;lrIlJs ""(/,1"$

"-<center> <input type="SUBMIT"I>

()ptJl"+Vl1alrlel1+eJ I cgp+VI'fJ.1' sel'vtJIJI'.


I

II"IrIVIQI'14S; irias pal'a I'esvlrlir;

1JI'IJIf;Isel'
Qtl

l"I1pV+ JIJ VSV:1"14 e l"e+IJI"I1:-I",

</center>

</form>

</body> </html>
...........................................................

Voc s vai precisar dos conhecimentos

mais bsicos


:
:
:

emHTML.
0. HTML "pipoca" durante todo o exame. Mas voc no est sendo testado em HTML. No entanto, voc vai se deparar com o HTML no contexto de vrias perguntas. Portanto, voc precisar ao menos de uma idia do que est acontecendo quando vir um HTML simples.

: :

. . . . .
. .
: :

: :


8 captulo 1

..............................................................................

introduo

e arquitetura

o que o browser
o browser

cria ...

l todo o cdigo HTML, cria a pgina e a transforma em imagem para o usurio.

@ ----.:'\Iame: Password:

voc est

o protocolo

HTTP

o que o protocolo

HffP?

o HTTP roda no topo do TCP/IP. Se voc no est familiarizado com estes protocolos de rede, temos aqui um curso rpido: O TCP responsvel por garantir que um arquivo enviado de um n da rede para outro chegue ntegro ao seu destino, ainda que o arquivo esteja dividido em blocos no momento do envio. O IP o protocolo de sustentao que transfere/roteia os blocos (pacotes) de um host para o outro no seu caminho at o destino. Ou seja, o HTTP outro protocolo de rede que tem caractersticas especficas para web, mas ele depende do TCP/IP para obter a solicitao e a resposta completas de um lugar para o outro. A estrutura de uma conversa HTTP uma seqncia simples de Solicitao/Resposta; um browser solicita e um servidor responde.
~

Principais eleme solicitao: ntos do fluxo de


~ O mtodo RTTP _ executada) (a aao de ser e sera acessada ( Os parmetros do [o' , . uma URL) argumentos para nn?lano (como ummetodo)

~
~

A pgina qu

'

solicitao HTTP

resposta HTTP

Servidor

Principais elementos do fluxo de resposta:


~ Um cdigo de status (~o caso de uma solicitao bem suced1da) Tipo de contedo (texto, imagem, HTML, O contedo (o HTML real, a imagem, etc.) etc.)

i~
\ ~

..........................................................................

Voc no precisa memorizar a especijicao do HTTP. Se voc quer mesmo saber (felizmente, o exame no espera que voc queira), o protocolo HTTP segue o padro IETF, RFC 2616. O Apache um exemplo de servidor Web que processa solicitaes HTTP. O Mozilla um exemplo de browser que d ao usurio o mecanismo para realizar solicitaes HTTP e visualizar os documentos retomados pelo servidor.

......................................................................................
10

introduo

e arquitetura

o HfML parte

da resposta HffF

Uma resposta HTTP pode conter o HTML. O HTTP acrescenta a informao do headerno topo de qualquer que seja o contedo da resposta (em outras palavras, aquilo que retoma do servidor). Um browser HTML usa aquela informao de header para ajudar no processamento da pgina HTML. Considere o contedo do HTML como um dado que foi colado dentro de uma resposta HTTP.

solicitao HTTP

resposta HTTP

1
~Va.l7d4 6 bl"wsel" el'Jumfl"a a +f4j <"+11'I1> de abel"-!-v"4; ele el7+l"a.ell'l lI'Id6 de pI"4CeSSall'le~4 d6 I/rK.4.L e ex'-!!e a
</head.>

Servidor

p~lP;a ." t/SVfJ.I"it>. ~val'Jd bl"wsel" el'Jcl'J-!-I"Q vll'la

<bOdy> <img src== ... </bOdy>


</htm.l>

>

-!-~ de

Iw..~e..., ele jel"a V+l"a pal"14,,. bvscal"

sllct-!-a{iltrrp

6 l"ecvl"sespecllteadlJ.

/ AJes-h
a

ca.SIJ; 6 bl"wsel" !al"a. Vll'la.SejVl'Jda sllcl+a.{i I/rrp


1w..4jell'l

pal"a b-h" l'Jaf~

descl"i+.

<1"""5>.

voc est

11

Mtodos HTTP

Se esta

a resposta,

o que consta na solicita co

A primeira coisa que voc encontrar o nome do mtodo HTTP. Estes no so mtodos Java, mas a idia semelhante. O nome do mtodo informa ao servidor o tipo de solicitao que est sendo feita e como o resto da mensagem ser formatada. O protocolo HTTP possui diversos mtodos, mas os que voc usar com mais freqncia so o GET e o POSTo

o usurio ~

dica em um Iink para uma nova pgina.

o browser envia um HTiP GET ao servidor, pedindo ao servidor que CONSIGA a pgina.

Usurio

Browser

POST
O usurio digita em um

11I formulrio e dica no


i!':1lt

boto enviar.

O browser envia um HTiP POST ao servidor passando para o servidor o que o usurio digitou no formulrio.

I
Usurio Browser

12 captulo 1

introduo

e arquitetura

o &Ef uma

simples

solicita~o, o POSf

pode enviar dados do usurio

o GET o mtodo mais simples do HTTP e seu principal trabalho na vida pedir ao servidor que consiga um recurso e envi-Io de volta. Tal recurso pode ser uma pgina HTML, um JPEG, um PDF, etc. No importa. O objetivo do GET conseguir alguma coisa do servidor.
O POST uma solicitao mais poderosa. como se fosse um GET ++. Com o POST, voc pode solicitar algo e, ao mesmo tempo, enviar os dados de um formulrio para o servidor (mais adiante neste captulo, veremos o que o servidor pode fazer com esses dados).

r:

retguntas

N9 ex1stem

idl9tls

E com relao aos outros mtodos HTTP alm do GET e do POST?

Estes so os dois mtodos mais usados por todo mundo. Mas, existem alguns raramente usados (e os Servlets podem trat-Ios), tais como HEAD, TRACE, PUT, DELETE, OPTIONS e CONNECT. Voc realmente no precisa saber muito sobre estes outros para o exame, embora voc possa encontrlos em alguma pergunta. O captulo A Vida e a Morte de um Servlet aborda o resto dos detalhes dos mtodos HTTP que voc poder precisar.

1\:

Espere um momento ... Eu poderia jurar que vi solicitaes GET que enviavam alguns dados por parmetros ao servidor.

voc est

13

HTTPGET

verdade ... voc pode enviar algutls dados

COI11

o HffF G-Ef

Mas voc pode no querer. As razes para usarmos o POST no lugar do GET incluem:

G) O total

de caracteres no GET realmente limitado (dependendo do servidor). Se o usurio digitar, digamos, um trecho extenso em uma caixa de entrada do tipo "Procurar", o GET pode no funcionar.

@) Os dados que voc envia atravs do GET so anexados URL,


l em cima, na barra de endereos do browser; portanto, seja o que for, ficar exposto. Melhor no colocar a senha ou outra informao sensvel como parte de um GET!

Devido

ao item 2 acima, o usurio no pode adicionar aos seus favoritos a pgina que envia um formulrio, se voc usar o POST em lugar do GET. Dependendo de sua aplicao, voc pode querer ou no que os usurios sejam capazes de armazenar a pgina resultante do envio de um formulrio.
A-

U7"
.

sepQ,('Q,c cQ,/fI!,I;.,I.e d{JS Ccs dadtls ex+rQ,s). ()

pal"~e+('cs

+tl+1).1 de dadlJs lle vtlc pede a+l"Q,vs dlJ tf:r

(;"'1/1"41"

IIf'\l+ad6 e explis+6 para +"dlJ

f4alll e/fl!,clf'\a 11(J !Jr(Jwser; A- (J}t.l- (JI"ij'~Q,1 f4",l-es dcs pQ,('~dl"cs exf.ras. /fI!,v'Id(J ver, JfI'I+(JS;

f(J('/fI!,o./fI!, (J, s+rl~j

da (JJel- fle el1vi'4da Ctl/fl!,a st:.lici+a{i..

14 captulo 1

introduo

e arquitetura

At1atotMia

de utMa solicitao

HffF G-Ef

o caminho at o recurso e quaisquer parmetros adicionados URL esto includos na "linha de solicitao".

() calVli'l!." paJ"a " NtcVJ"S/i '10 sf!f'vldcJ".

~\

A- veJ"so es-f: do Pf'tJ-flJc/t, bl"cwseJ" SfJ!il..fa'ldlJ.

Os l.eo.df!J"sdO.

S("tcl-h'y",

GET /seiect! seiectbeer'l'aste. J sp?co.tor=aarK!itaste=mal ty HTTP/ 1.1 Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:l.4) Gecko/20030624 Netscape/7.1 Accept: text/xml,application/xml,application/xhtml+xml,text/ html;q~0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/ gif;q=0.2,*/*;q~0.1 Accept-Language: en-us,en;q~0.5 Accept-Encoding: gzip,defiate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive

~~

\)..

Ei servidor ... PEGUE a para mim a pgina que se encontra em / select/selectBeerTaste.jsp e, ah sim, aqui esto os parmetros para voc: color = dark & toste = malty. E depressa.

solicitao HTTP

U---~
Servidor

voc est

15

HTTPPOST

At1atotftia de utfta solicitao HffP POSf


As solicitaes HTTP POST so designadas para serem usadas pelo browser em solicitaes complexas para o servidor. Por exemplo, se o usurio acabou de preencher um longo formulrio, a aplicao poder querer que todos os dados do formulrio sejam adicionados a um banco de dados. Os dados a serem enviados de volta ao servidor so conhecidos como "corpo da mensagem" ou "payload" e podem ser bem extensos.

ti-

VE'l's'" dIJ

fl',,-I-t;IIJ llE' ti bI"6WSE'1' es-I-~ stlfiCl-l-a,ul.


Rost: www.wickedlysmart.com Mozilla/5.0 Gecko/20030624 (Macintosh; U; PPC Mac OS X Mach-O; en-

User-Agent: US; rv:l.4)

Netscape/7.1

Os t.eg,del"s

da

Accept:

text/xml,application/xml,application/xhtml+xml,text/

html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/

StJltcr-l-Il.S',,

jpeg,image/gif;q=0.2,*/*;q~0.1 Accept-Language: Accept-Encoding: Accept-Charset: Keep-Alive: Connection: 300 keep-alive en-us,en;q=0.5 gzip,defiate ISO-8859-1,utf-8;q=0.7,*;q=0.7

!Jes.f.1J.lIej tlS flJ.l'v,.e.f.l'tJs

E's.f."itl 4~1I1~
'1'IJ

O Cor'fD da

'lI) 11;'0.1

d" ctll'ftJ

eJ ftJl'.f.fJ.".j.I))

Ilc41/1i

lI1e'lS~f~ aljlll/lifJ.s color=dark&taste=malty ve~es cl.all1fJ.dtJde (

ul

1i'lI1l-l-4des dQ. l/Iial1E'/rQ.311eItcIJ.I'I"b.l/Iil1l1al1d" se usa 1Ii111 bf.:'; e fl'E'ci'sal/li seI' c(Jl<)cadlJs 114 N /I;,t.a de SlJ/tct+-aflJ.c.

_.f'Dj'<)lJ.d

Ei servidor ... por favor COLOQUE isto no recurso localizado em: / advisor / selectBeer Taste. do. No se esquea de olhar na parte interna do corpo os dados importantes que estou enviando.

Claro, eu vou procurar este recurso (na verdade, uma pequena aplicao) e quando eu achar, entregarei OS dados enviados no corpo da solicitao que voc enviou.

solicitao HTTP

u----::.;
Servidor
16 1

introduo

e arquitetura

A.,atolMia de ulMaresposta HffF e que .,egcio esse de "MIME typeN1


Agora que j vimos as solicitaes do browser para o servidor, vamos dar uma olhada no que o servidor envia de volta como resposta. Uma resposta HTTP composta de header e corpo. A informao do header informa ao browser o protocolo que est sendo usado, se a solicitao obteve xito e que tipo de contedo est includo no corpo. O corpo possui o contedo (por exemplo, o HTML) que o browser exibir.

A vel"s~"
ClSa'ld4.

d4Pl"4.f.4C"/4

f) C:'dij de S.f.a..f.ClS
Hr-rp pal"ti. a
iJ a

~Cle., Sf!l"vtiJ.,1"we6 es+: \


.1-

HTTP/1.1

Jeesf6s+a.. :.t ~tie


200 OK

vers., hx.f.(J ti., C:'dijtJ s.f.a+Cls.

i.etJ.deI"S de Jeesp4sh Hrrp'

Set~Cookie: Path~/testEL

JSESSIONID=OAAB6C8DE415E2E5F307CF334BFCAOC1;

_~
Content-Length: 397 Date: Wed, 19 Nov 2003 03:25:40 GMT

f) va/tJl" d6 t.eadel"
"' N!Sp6SrfJ. I pa.I"a 6 ;;te /

Server: .Apache-Coyote/1.1 Connectlon: close

C4~'1-1--I;fe e ctJl'lt.ecl'J" .:6 4 If4zJ4,f. +jpe. ()

!fA.ZIf4f. -Iype 1'I'J/41"1J'lfJ. fJ.4 bl"tJwsel" 3t1e -hj>o tie dfJ.titJ bl"(Jwsel" es+:
p41"4 I"ecebel"J1'41"43C1e' es+e f"ssa sdel" ClJ'l"

pl"ces sa-/(J. /t.efal"e 3C1e' 6 valtJl"para


(J

If4I!fA.f. +jfe' I"III:/el"ese QfJS1Ia./"I"es11'$+4"6S


'16 "eadel" ACCfp+ da sltd-h.{i.(J Hrrp' (Observe (J !.eadel"

l1a s6Iict+a{i.., PO.:s-rJIt. ":;I'I'Ja al1+el"161")

o
a resposta HTTP

Cliente

Servidor
est 17

solicitao

e resposta

(
\ \
\

o !H'WSft'
SfJltct-fo.{i6

cria v~a

'-V

Itrrp iG,!'(

GET /test1/Beer1.html HTTP/1.1 Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 (Macintosh ...

Beerl.html
<html><body> <hl align~eenter>Beer Login Page</hl> <form> Seleet a beer type or buy beer making supplies?<p> <input type~radio name~seleet value~Seleet> Seleet a beer<br> <input type~radio name~select value=Buy> Buy supplies<br><br> <center> <input type~SUBMIT> </eenter> </form> </body></html>

~5era

lI~a

Itrrp'

resf>t:Js+a

~erVitl<J1' e"JC6"J+r~ 4 f>~/"'Q

HTIP/1.1 200 OK
Set-Cookie: ...

<html><body> <hl align~eenter>Beer Login Page</hl>


<forro>

Seleet a beer type or buy beer . . .

lJr

f"f!Sf><JS.f.l1.

Itrrp eJ1vtatila

46

/;l'fJwser.
lJr c/tel7+-e ~v4rtila fJ.I7Si;'S14~el7+-e jVf! SVo. -frtJ.I7S144 s~a

Beer Login Page


Sclcrt a beer type o. huy beer making supplics?

o Select a bcer
O BllY supplies

reallj14tila C.:l~ sue,!SS.:l.

18

introduo

e arquitetura

GETou POST?
Para cada descrio, circule POST ou GET, dependendo de que mtodo HTTP voc usaria para implementar isso funcionalmente. Se voc achar que pode ser ambos, circule os dois, mas esteja preparado para defender suas respostas ...

POST

GET

Um usurio digitando um login e uma senha. Um usurio solicitando uma nova pgina via hyperlink. Um usurio em uma sala de bate-papo enviando uma resposta. Um usurio dica no boto "next" para ver a prxima pgina. Um usurio dica no boto de "logout" num site seguro de um banco. Um usurio dica em "Voltar" no browser. Um usurio envia um formulrio com nome e endereo para o servidor. Um usurio faz uma escolha em um boto de seleo.

POST

voc est

19

Anatomia da URL

URL. O que quer que voc faa, t1O prot1ut1cie "Ean".


Quando voc procura a letra U no dicionrio de acrnimos ocorre um congestionamento ... URI, URL, URN, onde isso termina? Por enquanto, vamos focar nas URLs, ou Uniform Resource Locators (Localizadores Uniformes de Recursos), que voc conhece e ama. Todo recurso na web tem seu endereo nico prprio, no padro URL.
Jeec(Jl',u,;
t:J

17"""e d"

C617-H!~d" Sel7dlJ s6Ilcl+lJ.dlJ. ~1'+4:

S+4 ?41'-H! I'


IV

da fiJt.L.

~de

seI' (J*11J. ?~/;'IJ.


V""

e "PCI6'10.I, fif'l tl17IC(J Sel'vit61' stI?"I'+a Pr.o+tJctJl,,: Il7ltu'f'l11.


f4.:l

Hr14.L.;

Sf!I''11le+" v""a

v:I'i'1J.Sf61'+o.s, e tde'l-r'fI,co.Jo.
I I,

i'f'ltJ.jf!") P!JF; f'I~Si'ca; v!Je(J 6(1 3(1IJ.I1;Vf!1' tW+1'1J.C6iSIJ. 3ve

U""4 ~/ico.f46

sel'vi/cl'

(pai

1'61' tlf'lo.1'01'+0., Se vtlc 'l" especilical' SVo. uJt.L.J f4til'';6


I'
IJ.

6 sel'lIitlJl'

S(lelrfJ. Se es+a

?I'+CC(J16 de cOf'ltll7lctJ.5';" (l7es-H! CIJ.S{J I {J Hrrp'> sel'lJ. tlS4dtJ, atle

tlf'lo.p61'+4 f!f'I fI'+4

dl's?"17tbtli'fJ.I'.
tl

80 seI':

Pf4I'-H! "pcl6l7alll' t!Jf'll-ha; IJ. ""o.i6I'i'8. d6S sel'lIitl'es


I'

eJ CI;,ettie'l-H!l/1Iel7+e J
f41'fJ. S

Iro. fl'lJC(lN.1'

PCI' I;'dex,t.+"",

eS+4 e fJ. ?"I'+fJ.-?f4Jl' sel'vitl't!,S

j
I
Sel'vlt1iJl':
t:J

wd,
fCI' ?f4dl'';C, \,

http://www.wickedlysmart.com:8~/beeradvice/select/beerl.html

'\

17t>f'lf! tlmc" ti" sel'lIlt1t'J1'

Ca""I"'II<";

t:J

ca"",;,t.6plJ.l"a

a ItJcalt;,6;

I IISICtJ pelt'J 3vo.I

~ 11 vtJce es-ra fl'tJCtll'fJ.I7J.D,


Vf'I ~l7i'c6

1S-H! 1761/11e 8.f6'1-f-1J. f41'fJ.

'16 sel''Ilt1"I'; J(J I'f!C(lI"StJ (Je es+a de a sel7d" st:Jltct+aJlJ. 1"" vlr.fvJe f'Iail'iit dos sel"!/llJl'es

el7tiel'f!j6 IP. t:Js e'lJel'ej.Ds I l7t1f'1el'i'u~s e as stlf'le"" fJ.

IP

"s"
xxx.

wd

I/1I(M$

jj}';;;'IJ.fJ.1Il

, ~ce p6de f!specl/l'c1A1' (lf'I

'16!/t:JS I't!dal" fi 171)( IJ. Sl;,-f-alcf! thl1l)( J f 41;,Ja e (JsadIA. fal"a descl"evel" as t,tel'aI"3(Ji'tJ.s Je Jlre+:l"ibs.

f!"'Itiel'(j6 fIP 8.f.(li"ef'l V('t Q I J tie tll/1I'16f'1f! J f'IlJ.S (Jf'I170l/1le e bef'l f'Ia.ts IlJ.crl de le*1bNJ.t',

;
~~c

20 captulo 1

introduo

e arquitetura

Os '7VIlflt!1"4S lIfI~i"$ c(mt.eeM"s Je p61"+as tJ.Sapli"ctii;;t!s

rcpparI),
Uma porta TCP apenas um nmero
Um nmero de 16 bits que identifica um programa especfico servidor. no hardware do
Telnet

ellfl IIfIfJ.I"$ CllIIfIV'7S 3"e N,,:i8.11f1 St!I"VM4I"fS

o software do seu servidor de intemet (HTTP) roda na porta 80. Isto padro. Se voc possui um servidor de Telnet, ele rodar na porta 23. FTP? 21. Servidor de e-mail POP3? 1l0. SMTP? 25. O Time server fica na 37. Considere as portas como identificadores nicos. Uma . porta representa uma conexo lgica para um determinado software rodando no hardware do servidor. S isso. Voc no pode virar o seu gabinete e encontrar uma porta TCP. Por um motivo, voc tem 65536 delas em um servidor (O a 65535). Alm disso, no conectamos dispositivos fsicos nelas. Elas so apenas nmeros representando uma aplicao para servidor.
Sem os nmeros das portas, o servidor no teria meios de saber a qual aplicao o cliente gostaria de se conectar. E j que cada aplicao deve ter seu prprio protocolo, imagine o problema que voc teria sem estes identificadores. E se o seu browser, por exemplo, fosse parar no servidor POP3 em vez do servidor HTTP? O servidor de e-mail no sabe analisar uma solicitao HTTP! E mesmo que soubesse, o servidor POP3 no sabe nada sobre disponibilidade de pginas HTML. Se voc est escrevendo servios (programas de servidores) para rodar na rede de uma empresa, voc deve checar com o administrador de sistemas quais portas j esto sendo usadas. Seu administrador poder dizer, por exemplo, que voc no pode usar nenhuma porta inferior a, digamos, 3000.

Time

HTTPS

POP3

(J SfJ.'7Jtl

V"'IJ. apltefJ.S';(J 1'41" p41"+a., li'" 11.-#

S(!l"Vti/(Jf' ptlJe fff' apli'ca{;;es Jtfel"fl1ffs I

'S-S-3(.

NultJ.I1JtJ

(e"'!?tlf'1J. S!jl), ptJS sl'lIel f'If:lJIJ.f' 11<\4/"$ Je VII<\4apltCf<f';6 111), II<\es",~ P6f'+fJ. se elas VSIJ.N!1IfI PI"(J+(Jc6ItJS JI"$-h"'+tJS)

Os nmet9s das p91tas de O a 10Z3 s9


o; C9hneCl 1 0d 9S pata ser" l95ja
TO

(Inclu'iud9 a -PrIncIpalplta h9S - a p9tta 80)$ N9 use estflS p9ttas 9S sen ti


21

pt9h"tamas pattlculates!
voc est

diretrio web site

A estrutura de diretrios para um site Apache simples


Ns falaremos mais sobre o Apache e o Tomcat mais adiante, mas por enquanto vamos admitir que nosso site simples esteja usando o Apache (um servidor web bastante popular, de cdigo aberto e que provavelmente voc j est usando). Como parecer-se-ia a estrutura de diretrios para um site chamado www. wickedlysmart.com, hospedando duas aplicaes, uma dando conselhos sobre esquiar e a outra, sobre assuntos relacionados cerveja? Imagine que o Apache esteja rodando na porta 80. Marcamos cada uma das pginas .html com uma letra (A, B, C, D) para o exerccio na prxima pgina.

puiex.t.-r1ti\1 e 4 f>~/"'4'" I p4dl'IJ.C 3ue Sel'4 l'e-/-':JN1IJ.d4 4<) USU:I"iJ 3ue djt+6U
WliI/liI/.
(J"" d

Sf!I'Vtd61' 1Jrf>b.ct.e IJ.ss{J""tl':

<)

J.+dlJcs (;<)1'1I\6
td

d'I"e+;l'liJ-1'4l;f>fJ.NJ.

+6tas 4S apl'c4';es

sel'vtiJ{<)I'. lJr f4S+a-l'li.t;pfl.l'fJ. !Jeel'lJrdvtce.


fi.

wtcked'jsIf!\41'+.C6""/
I1IJ

seu PNlliI/Sel'.

apliClJ.ji!l

v:

<~bd> Index.html

22 capitulo 1
~"

introduo

e arquitetura

Apontando as URLs para o contedo


Observe a estrutura de diretrios da pgina ao lado e escreva a URL que levaria voc a cada uma das quatro pginas .html marcadas com as letras A, B, C e D. Ns fizemos a primeira (A) para voc, porque assim que ns somos. Para o exerccio, considere que o Apache esteja rodando na porta 80. (As respostas esto no rodap da prxima pgina.)

Far com que o servidor retome para voc a pgina index.html no ponto

Far com que o servidor retome para voc a pgina index.html no ponto

Far com que o servidor retome para voc a pgina index.htrnl no ponto

Far com que o servidor retome para voc a pgina selectBeer.html no ponto

23

voc est

pginas estticas

Servidores Web aiMaiMservir pginas Web estticas

lT .1 o ." Jma pflbma esf:atma


(J

apenas tep9usa l dentt9 d9 d1tet9t19. O setv''id9t a enc9ntta e a dev'9Ive pata 9 clIente C9m9 est. '19d9 () clIente
'V

a mesma

s.f-as f>~/"I1t1.SV';fJ di,;'e.f-(J f>tU'Q.(J


4f1i'clJ.g';fJ

dle'1ff) eXfA..f-a.htt'1ff

C"ht(J

alie f"ddo. 1M
S,!f"IIi"JtJf"

elas f6f"alit\ c"/(JctAdas '1() sel''r/liA.rJf''.

servidor

Mas e se eu quiser, digamos, que a hora atual aparea na minha pgina? E se eu quiser uma pgina com contedo dinmico? Eu no poderia ter algo como uma varivel dentro do meu HTML?

f. se

3l1lSel'htS

f!'1cD.i'xo.f"

o.'5l1hta CiHSo. V4f"1fJ.llel

da f>~I"l1a
<html> <body> The current </body> </html> time i8

[insertTimeOnServer].

HrKA.L?

cD- MMM'M,C~GqJ8lligr~'cOlli\pGGr~qA,CG\ MMM'M,C~GqJ8lligr~'cOlli\pGGr~qA,CG\8GJGC~\8GJGC~BGGr'p~llirl B- MMMM'C~GqJ8lligr~cOlli\8~"uVqA'CG\

24

introduo

e arquitetura

Mas algutHas vezes voc precisa de tHais do que s o servidor

Mas como isso vai ajudar? Meus clientes so todos clientes web. O browser s conhece o servidor ... ou seja, ele no vai ser capaz de chamar aquela outra aplicao.

servidor

outra aplicao do servidor

Isto no problema. Eu cuidarei de entregar a solicitao aplicao helper correta. A, eu pego a resposta da aplicao e entrego de volta ao cliente. Na realidade, o cliente nunca precisa saber que outra pessoa participou do trabalho.

outra aplicao do servidor

voc est

25

quando um servidor no

o bastante

Vuas coisas que o servidor no faz sozinho


Se voc precisa de pginas instantneas (pginas criadas dinamicamente e que no existiam antes da solicitao) e da capacidade para escrever/salvar dados no servidor (que significa escrever em um arquivo ou banco de dados), voc no pode contar apenas com o servidor.

As Ph1nclSInstantnelB n9 eXIstem antes de


l'

ser te'lta a s91'lc'lta-9.E C9m9 tqz.er uma pblna B11\t[., de tepente. A s91'lc'ltay9cbet;a. q apllca-9 beIpet ~~escteve" 9 BINIL, e 9 setVld9t tet9tna a9 clIente.

1 Contedo dinmico
A aplicao que roda no servidor disponibiliza somente pginas estticas, porm uma outra aplicao "assistente", com a qual o servidor pode se comunicar, pode construir pginas dinmicas instantaneamente. Uma pgina dinmica poderia ser qualquer coisa, desde um catlogo at um weblog, ou at mesmo uma pgina que escolha imagens aleatoriamente para exibi-Ias.

Quando em vez disto:


<html> <body> The curent time is

Voc quer isto:


<html> <body> The curent time is

always 4:20 PM on the server </body> </html>

[insertTimeOnServer] on the server always on the </body> </html> 4:20 PM server

2 Salvando os dados no servidor


Quando o usurio envia os dados em um formulrio, o servidor analisa os dados e pensa: "E a? Eu devo me preocupar?". Para processar esses dados, salv-Ios em um arquivo ou banco de dados, ou at mesmo para us-Ios na criao da pgina de resposta, voc precisa de outra aplicao. Quando o servidor recebe uma solicitao para uma aplicao helper, ele considera que aqueles parmetros so destinados ao assistente. Assim, o servidor passa os parmetros, fornecendo aplicao uma forma de gerar uma resposta ao cliente.

26 captulo 1

introduo

e arquitetura

o fernto
que roda

t1o-Java para uttta aplicao helper


tiO

servidor o "C&I~~

A maioria dos programas CGI escrita como scripts em Perl, mas vrias outras linguagens podem servir, incluindo o C, o Python e o PHP. (CGI significa Common Gateway Interface - Interface de Passagem Comum -, e no nos importamos por que ele chamado assim.) Usando o CGI, veja abaixo como funciona uma pgina dinmica que possui a data atual do servidor.

servidor

~-,
Cliente

aplicao do servidor

o usurio dica em um link que tem uma URL, que chama um CGI em vez de uma pgina esttica.

..
Cliente

servidor A aplicao do servidor "v" que a solicitao para o programa assistente, ento o servidor abre e roda o programa. A aplicao do servidor envia junto os parmetros do GET ou POST.

aplicao do servidor

parmetros aplicao helper

servidor A aplicao helper constri a nova pgina (que tem a data atual inserido) e devolve o HTML ao servidor. Para o servidor, o HTML da aplicao helper uma pgina esttica.

~)

Cliente

aplicao helper

servidor

aplicao do servidor

[J

A aplicao helper fechada e o cliente recebe de volta uma pgina HTML contendo a data atual, agora esttica, como parte

voc est aqui ~

27

dois lados, CGI

e Ser,;iets

Os Servlets

e o

CG-I

aruaIM COlMOuIMa aplicao

helper no servidor Preste ateno na conversa dos nossos dois faixaspretas sobre os prs e os contras do CGI e dos Servlets.

CGI

Servlets

o CGI melhor

que os Servlets. Ns criamos os scripts CGI em Perl na nossa empresa, pois todo mundo sabe PerI.

Com todo o respeito, mestre, existem muitas vantagens em se usar o Java, em vez do Perl, para essas coisas que voc quer fazer com o CGI.

Eu acho que legal usar Java, se voc souber. Mas certamente, no valer a pena para ns mudar para Java. No h nenhuma vantagem.

Desempenho, por exemplo. Com o Perl, o servidor tem que rodar um processo superpesado para todas as solicitaes que sejam para este recurso!

Voc est me desafiando? Em quais assuntos? Ah, sim, mas os Servlets ficam carregados e as solicitaes dos clientes para um recurso do Servlet so tratadas como threads de um nico Servlet em execuo. No existe overhead ao carregar a NM, as classes e tudo mais ...

Isto no diferente do Java ... O que voc chama de JVM? Cada ocorrncia da JVM no um processo superpesado?

Eu vejo que voc esqueceu muita coisa. Atualmente, os servidores web so capazes de manter um nico programa Perl rodando entre as solicitaes dos clientes. Por isso, seu argumento de que ele mais pesado no vale de nada.

Eu no esqueci, mestre. Mas no so todos os servidores que podem fazer isso. Voc est se referindo a um caso isolado que no se aplica a todos os programas CGI em PerI. Porm, os Servlets sero sempre mais eficientes quando isso ocorrer. E no vamos esquecer que um Servlet pode ser um cliente J2EE e um programa CGI em Perl no.

Do que voc est falando? Qualquer coisa compatvel com o CORBA pode ser um cliente J2EE.

Chega, estou atrasado para minha aula de Pilates. Mas no pense que acabou. Vamos terminar isso mais tarde.

Eu no quero dizer um cliente para um J2EE, e sim um cliente que um J2EE. Servlet rodando em um container J2EE participar da segurana e das transaes enterprise beans e existem ...

programa Um pode com

continua ...

Eu duvido que todos saibam PerI. Eu gosto do Perl, mas todos somos programadores Java aqui na empresa; ento, preferimos Java.

28 captulo 1

introduo

e arquitetura

o I/Sil~l'. J.iji.f(J,

Solicitao Resposta
Complete as caixas escrevendo o que acontece durante cada passo no processo. Esta uma cpia da pgina 18. Ou seja, ao terminar, volte l para comparar suas respostas.

t/W\(J,

u~l-.

11
\HTTP/U
GET /test1lBeer1.htm . WicKed\ysmart.com Host. www '1\ /5 o (Macintosh ... user-Agent: Mozl a .

<htrnl><body> <hl align=center>Beer


<forro>

Login Page</hl>

Seleet a beer type ar buy beer making supplies?<p> <input type=radio name=select value=Select> Select a beer<br> <input type=radio name=select value=Buy> Buy supplies<br><br> <center> <input type~SUBMIT> </center> </form> </body></html>

Sd\~ ervl or i
1
HTIP/1.1 2000K
Set-Cookie: ...

<html><body> <hl aIign=center>Beer


<orrn>

Login Page</hl> ...

SeIeet

a beer type or buy beer

A- c!ie#i-fe fJ.5t/tJ.1'(fi.
a#iSl(jSfA~e#i-fe ~tlf st/a .ff'fI.#isa{i(J

Beer Login Page


Select a beer type or buy beer making .supplies? O Selccr a beer C Buy $upples

S~(J, f'f4'l-;l'J.tifl. c.o~ St/Cf!S SlJ.

voc est

29

uma rpida olhada nos servlets

Servlets Desmistificados (criar, distribuir, executar)


Pois , os novatos em servlets j podem parar de prender a respirao; aqui est um guia rpido para criar, distribuir e executar um servlet. Este guia pode gerar mais perguntas que respostas no se assuste! Voc no precisajaz-Io neste exato momento.

apenas esperar. uma O prximo rpida demonstrao captulo incluipara um tutorial aqueles mais que no detalhado/ conseguem / Construa esta rvore de diretrios (em qualquer lugar, exeeto sob o tomcat).

Ch1Servletjava

weh.xml

Crie um servlet chamado ChlServlet.java e o coloque no diretrio sre (para simplificar este exemplo, no colocaremos o servlet em um pacote; mas aps este, todos os outros exemplos com servlet neste livro estaro em pacotes).
javax.servlet.*; javax.servlet.http.*; java.io.*;

import import import

public public

void

doGet(HttpServletRequest HttpServletResponse

request, response) { ~

class

ChlServlet HttpServlet throwsextends IOException { out ~ response.getWriter(); " + +

PrintWriter

ou t .pr in tln ("<h tml> "<body>"

rrrJl4.L
e"",

IPJSf;l"it/.t)
;1"1J!t) J

"<hl align~center>HF\' s Chapterl Servlet</hl>" + "<br>" + today + "</body>" + "</html>"); java.util.Date today ~ new java.util.Date();

\'l"
+
IV

"46 ti! w,es""'(J?

'" Java. ";. J !

vw, PI"t)51"fJ.""'(J.

c.<J"Jsi'tI.eN4;es

Crie um deployment descriptor (DD) chamado web.xml e ponha-o no diretrio ete.


version="l.O" encoding-"ISO=8851-1" ?> 2ee" xmlns=''http://java.sun .com/xml/ns/j

1Ry>4/' l-a'J.f-e S:

<?xml

- (J "'" :b!J pfJ.l"tI.c!J.t/.fJ.


apliClJ.yfltJ

<web-app

web.

xmlns: xSi= http://www.w3.org/200l/XMLSchema-instance xsi:schemaLocation~''http://java.sun.com/xml/ns/j2ee/ http://java.sun.com/xml/ns/j2ee/web-app 2 4.xsd" version="2.4/> <servlet> <servlet-name>Chapterl name> Servlet</servlet-

-(Jlt\lJ!Jpt)t/.eJ.ecllU.1J.1..

V8.1"14S sel'v

!.

Ie.,-s. I

- (JIt\ <:'sel'lIle-!-'JIJ.w,e>
1J.""'41'1'1J. 4 e/e"",e",-!-a

<:.sel'lIle-!->

4tJ

ele""'e,,-!-a

<servlet-class>ChlServlet</servlet-class> </servlet> </servlet-mapping> <servlet-name>Chapterl name> Servlet</servlet-

<:.sel'v1e-!-lt\tJ.pp'-"5

>.

- (J1t\<:'sel'lIle-!-clfJ.ss>
IJ. clfJ.S se J4VIJ..
11"",

flSfJ.

<:'fll"l-pfJ.fflM> dle,,-h

<url-pattern>/Servl</url-pattern> </servlet-mapping> </web-app>

(J

",,,,,,,,e afie"

1'41'4

a s4IiCi-!-tJ.{i6.

30 captulo 1

introduo

e arquitetura

o o

Construa esta rvore de diretrios abaixo do diretrio tomcat existente ...

Do diretrio projectl,

compile o servlet...

o nome
web -d classes src/ChlServlet.java

da

aplicao

servlet-api.jar

[%javac

(IS+6

+V1I16 VII'I ~"l'c6 Ct)II'IIU'I1I14)


-classpath /your

path/torncat/common/lib/

(o arquivo Chl Servlet.class vai terminar em projectl/classes)

o
fi

Copie o arquivo ChlServlet.class para WEB-INF/classes, arquivo web.xml para o diretrio WEB-INF. Rode o Tomcat a partir do diretrio tomcat ...
%bin/startup.sh

eo

Ch1Servlet.class

Abra seu browser e digite:


http://localhost:8080/chl/Servl

deve aparecer:

HF's Chapterl Servlet


Tue Feb 10 15:01:24 MST 2004

@) Por

enquanto, toda vez que voc atualizar ou uma classe de servlet, ou o deployment descriptor, d um shutdown no Tomcat:
%bin/shutdown.sh

voc est aqui .

31

HTML em um println() no rola

I
Sem ofensas, mas existe alguma coisa SERIAMENTE errada com esta figura sobre servlets ... tentando enfiar o HTML dentro de um printlnO?? Isso no pode estar correto..

I
I~c
.A

f. 4SSI"" IJ 'l.(le lI.:lce CI'I"!A (1110\4 r t:>(J,f;1i14 "


dli1M-.tc(J,e~ (I~ sel'lIle.f-. ex"!!ll'
.A

+ello\ 3ye

.f-yJ() pal'fJ. y~fJ. salda ex+eI''JfJ. ('JfJ. I$S4 e plJ.l''TT:."1(;, I'espas-r(;, j'

J. V!!I'91"'14l1e)

'

rr

JlrrO r

&'

/I"r
+

... .Iev_ ... ,.. .~('.".I.).

out.println(~<html> ~ + ~<body>" + ~<hl>Skyler\'s Login Page</hl>" ~<br>" + today + ~</body>" + ~</html>");

Na verdade, tehtar fort\1atar o HfM\. dehtro de Ut\1out.prihtlhO hO servlet pior aihda.


Esta uma das piores partes (no, a pior parte) dos servlets. Enfiar tags HTML, devidamente formatadas, dentro do printlnO, s para que voc possa inserir variveis e mtodos de chamadas simplesmente uma crueldade. Nem pense em inventar coisas, ainda que pouco sofisticadas.

r:

No pode ser to ruim assim ... Por que eu no posso simplesmente copiar uma pgina HTML inteira do meu editor, como o Dreamweaver, e colar dentro do printlnO? No s para eu ser capaz de ler o cdigo l dentro?

1\: Obviamente,

voc ainda no tentou fazer isso. Que bom. Sim. Eu fao minha pgina em um editor decente (ou at mesmo um simples arquivo de texto seria mais fcil que no meu cdigo Java) e, ento, fao um copiar/colar rapidinho no printlnO e pronto!

Pena que voc vai receber 1.378 erros de compilao. Lembre-se de que voc no pode ter um carriage return (retorno de carro) de verdade dentro de uma String literal. E j que estamos falando de Strings ... o que dizer do seu HTML com todas aquelas aspas duplas?

32 captiulo 1

introduo

e arquitetura

Oh, se pelo menos existisse uma maneira de colocar o Java dentro de uma pgina HTML, em vez de colocar o HTML dentro de uma classe Java.

Ela tto cottheee o JSP

<html> <body> <hl>Skyler's <br>

DptJ.!Is+;;; se p4.t'ece
Login Page</hl> %> VIM pf.'1pe.l1tJ 1Mf./~

CIJIM

"fIM l1

<%= new java.util.Date() </body> </html>

Je

VIM

H-rA4.L?!

sky/erlogin.jsp
Uma pgina JSP bem parecida com uma pgina HTML, com a diferena de que voc pode inserir Java (e coisas relacionadas ao Java) dentro da pgina. Portanto, realmente semelhante a inserir uma varivel no seu HTML.

voc est aqui ~

33

o Java encontra o HTML = JSP

JSP foi Oque acottteceu quatldo alguttt apresetltou o Java ao HfML Itlserir o Java tiO HfML a soluo para dois probletttas:

1 Nem todos os designers

que fazem pginas em HTML conhecem Java

Os desenvolvedores de aplicao sabem Java. J os designers de pginas sabem HTML. Com o JSP, os desenvolvedores Java fazem a parte Java, enquanto que os desenvolvedores HTML fazem as pginas.

2 Formatar

o HTML dentro de uma String literal REALMENTEterrvel

Inserir um HTML, mesmo que levemente complexo, dentro de um argumento em um printlnO esperar que ocorra um erro de compilao. Pode ser que voc tenha que fazer um trabalho enorme para formatar o HTML, de forma que ele funcione no browser do cliente, mas satisfaa as regras do Java para aquilo que ele for designado a fazer na String. Voc no pode ter, por exemplo, carriage returns, embora a maioria dos HTMLs que voc baixa e edita ter carriage returns de verdade na fonte. As aspas podem significar um problema tambm - muitas tags HTML usam aspas antes e depois dos valores para atributos, por exemplo. E voc sabe o que acontece quando um compilador d de cara com as aspas duplas ... ele pensa "este deve ser o final da String literal". Naturalmente, voc pode voltar e substituir suas aspas duplas pelos escape codes ... mas isso tudo aumenta demais a chance de erros.

r:

Espere ... ainda tem algo de errado aqui! A vantagem nmero 1 diz que "nem todos os designers de pginas sabem Java ...", mas quem cria pginas em HTML ainda tem que escrever o Java dentro da pgina J5P! O J5P alivia o programador Java de escrever o HTML, mas ele no ajuda, de fato, o designer que cria o HTML. Poderia ser mais fcil escrever o HTML em um J5P, em vez de num printlnO, mas o profissional que escreve o HTML ainda ter que saber Java.

I\: Parece que sim, no parece?

Mas com a nova especificao para o JSP - e seguindo alguns conselhos -, o desenvolvedor da pgina incluir, de Java mesmo, muito pouco (ou nenhum) no JSP. Eles tero que aprender alguma coisa ... mas algo como colocar labels que de fato chamem os mtodos Java, em vez de escrever o cdigo Java real na pgina mesmo. E tero que aprender a sintaxe JSP, mas no a linguagem Java. 34 captulo 1

introduo

e arquitetura

HTTP significa HyperText Transfer Protocol (Protocolo para Transferncia de Hipertexto), e o protocolo de rede usado na Web. Ele roda no topo do TCP/IP. O HTTP usa um modelo solicitao/resposta - o cliente faz uma solicitao HTTP e o servidor web devolve uma resposta HTTP, que o browser ento calcula como trat-Ia (dependendo do tipo de contedo da resposta). Se a resposta vinda do servidor for uma pgina HTML, o HTML adicionado resposta HTTP. Uma solicitao HTTP inclui a solicitao URL (o recurso que o cliente est tentando acessar), o mtodo HTTP (GET, POST, etc.) e (opcionalmente) os dados de parmetros do formulrio (tambm chamado de "query string"). Uma resposta HTTP inclui um cdigo de status, o tipo de contedo (tambm conhecido por MIME type) e o contedo real da resposta (HTML, imagem, etc.). Uma solicitao GET anexa dados do formulrio no final da URL. Uma solicitao POST inclui dados do formulrio no corpo da solicitao. Um MIME type informa ao browser que tipo de dados ele dever receber, para que o browser saiba como trat-Ios (processar o HTML, mostrar o grfico, tocar a msica, etc.). URL significa Uniform Resource Locator (Localizador Uniforme de Recursos). Todo recurso na web tem seu prprio e nico endereo neste padro. Ele comea com o protocolo, seguido pelo nome do servidor, um nmero de porta opcional e geralmente um caminho especfico acompanhado do nome do recurso. Opcionalmente, ele tambm pode incluir uma query string, se a URL for para uma solicitao GET. Os servidores web so bons em disponibilizar pginas HTML estticas, mas se voc precisa de dados gerados dinamicamente na pgina (como a hora atual, por exemplo), voc precisar de algum tipo de helper que possa trabalhar com o servidor. O termo no-lava para estas aplicaes assistentes (freqentemente escritas em Perl) CGI (que significa Common Gateway Interface - Interface de Passagem Comum). Colocar o HTML dentro de uma declarao println( ) terrvel e suscetvel a erros, mas os lSPs solucionam este problema ao permitir colocar lava em uma pgina HTML, em vez de colocar o HTML dentro de um cdigo lava.

voc est

35

A arquitetura da aplicao web

Os servlets precisam de ajuda. Quando uma solicitao chega, algum tem que instanciar o servlet ou, pelo menos, criar uma nova thread para tratar a solicitao. Algum tem que chamar ou o mtodo do PostO ou o mtodo doGetO do servlet. E, claro, esses mtodos possuem um argumento crucial - os objetos request e response HTTP. Algum precisa levar a request e a response para o servlet. Algum precisa gerenciar a vida, a morte e os recursos do servlet. Esse algum o Container. Neste captulo, vamos ver como sua aplicao roda no Container e daremos uma primeira olhada na estrutura de uma aplicao usando o padro de projeto Model View Controller (MVC).

este

um

novo captulo

ll>

37

objetivos do exame oficial da Sun

IS!!hS.i ....- - -

06jetivgs

A Arquitetura das Aplicaes de Alto Nvel

Notas sobre a Abrangncia: 1.1 Para cada Mtodo HTTP(como GET, POST,
HEAD e assim por diante), descrever o seu propsito e as caractersticas tcnicas do protocolo do Mtodo HTTP, listar os triggers que podem levar o cliente (geralmente um browser) a usar o Mtodo e identificar o mtodo HttpServlet que corresponde ao Mtodo HTTP. Todos os objetivos nesta seo sero abordados completamente em outros captulos. Portanto, considere este captulo como uma base para o que vir depois. Em outras palavras, no se preocupe em terminar este captulo sabendo (e recordando) assuntos especificos destes objetivos. No existir nenhuma pergunta sobre estes assuntos nos testes prticos, at que voc chegue ao captulo especifico em que eles sero abordados. Aproveite este material legal, simples e que servir de base enquanto voc pode! PORM .. voc precisa conhecer estes assuntos para prosseguir. Se voc j tem alguma experincia com servlet, poder simplesmente pular as pginas, olhar as figuras, jazer os exerccios e avanar para o captulo 3.

1.4 Descrever o propsito e a seqncia de eventos


do ciclo de vida do servlet: (l) carregar a classe do servlet, (2) instanciar o servlet, (3) chamar o mtodo init, (4) chamar o mtodo service, e (5) chamar o mtodo destroy.

2.1 Construir a estrutura de arquivo e diretrios


de uma aplicao que contenha (a) contedo esttico, (b) pginas JSP, (c) classes do servlet, (d) o deployment descriptor, (e) bibliotecas de tags, (f) arquivos JAR, e (g) arquivos de classe Java; e descrever como proteger os arquivos de recurso do acesso HTTP.

2.2 Descrever o propsito e a semntica


para cada um dos seguintes elementos do deployment descriptor: instncia do servlet, nome do servlet, classe do servlet, parmetros de inicializao do servlet e a URL que aponta para o respectivo servlet.

38 capitulo2

arquitetura de alto nv~1

que

um Container?

Os servlets no possuem um mtodo mainO. Eles esto sob o controle de outra aplicao Java chamada Container. um exemplo de Container. Quando sua aplicao web (como o Apache) recebe uma solicitao para um servlet (ao contrrio de, digamos, uma antiga e esttica pgina HTML), o servidor entrega a solicitao no ao servlet em si, mas para o Container no qual o servlet distribudo. o Container que entrega ao servlet a request e a response HTTP, e chama os mtodos do servlet (como o doPostO ou o doGetO).

o Tomcat

servidor

Y
aplicao do Container
web

cdigo Java

servidor

voc est aqui

11>

39

ti vida sem servlets

se voc tivesse o Java e no tivesse nel\t servlets, net\1 Oontaineres?


E

E se voc tivesse que escrever um programa em Java para tratar as solicitaes dinmicas que chegam na aplicao do servidor (como o Apache), mas sem um Containet como o Torncat? Em outras palavras, imagine que no exista nada como os servlets e tudo que voc tem so as bibliotecas principais do J2SE? ( claro que voc pode admitir que tem a possibilidade de configurar a aplicao do servidor para que ela possa chamar a sua aplicao Java). Tudo bem, voc ainda no sabe bem o que o Container faz. Apenas imagine que voc precise de um suporte ao lado do servidor para uma aplicao e tudo o que voc tem um Java antigo e comum.

Liste algumas das funes que voc teria que implementar numa aplicao J2SE Se no existisse o Container:

"'U!J9UI~m ~p Olu~UIu~:)ml~ll'iud~ "'dSf ~llodns 'sllol OUIO:) SUS~O;) lUlllY IUl~nb 'u6U1un1l~slUlu~m~ldm~ 'spu~.nn ~p lOPU~;)U~l~ll mn lU!J;) :s~~AJssodSUlsods~lI

40 capitulo 2

arq'ut,'Jtwra de alto nvel

o que o Cotttait1er oferece?


Ns sabemos que o Container que gerencia e roda o servlet, mas por qu? Vale a pena o overhead extra?

..

Gta'i.cts p9de a9 C9nt:Unet, VOC se C9noonttlt " na 1.1" mais 9hICa d9 seu pt9ptl9 neh9c19, em ve;z de se pte9cupat em esctey'et c9dIh9s pata thteads, sehuttn,?a e tede. VOC tem 'Lue.ctnallz.u' t9da a sua enetgIa na Ctla,?9 de uma 19ja y'Iltual tabu19sa pata emballhens de p15tlc9-b91ha e deIxat 9S sety'I,?9S de SUP91te, C9m9 a sehuttn,?a e 9 JSf, plta 9 Pt900SSament9 " C9ntUnet.

o container

oferece uma maneira simples para seus servlets se comunicarem com seu servidor. Voc no

precisa construir um ServerSocket, escutar uma porta, criar trfego, etc. O Container conhece o protocolo entre o servidor e ele mesmo, para que seu servlet no tenha que se preocupar com uma API entre, digamos, o servidor Apache e o cdigo da sua prpria aplicao. Tudo o que voc tem que se preocupar com a lgica do seu prprio negcio, que est contida em seu Servlet (como aceitar um pedido na sua loja virtual).

. ..

. .-

O Container controla a vida e a morte dos seus servlets. Ele cuida de carregar as classes, instanciar e inicializar os servlets, chamar os mtodos do servlet e tornar as instncias do servlet aptas a coletar o lixo. Com o Container no controle, voc no precisa se preocupar tanto com o gerenciamento dos recursos. O Container cria automaticamente uma nova thread em Java para cada request do servlet recebida. Quando o servlet conclui a execuo do mtodo de servio HTTP para a solicitao daquele cliente, a thread termina (isto , morre). Isto no significa que voc est liberado da segurana do thread voc ainda pode ter problemas de sincronizao. Porm, contar com o servidor para criar e gerenciar as threads para as vrias solicitaes ainda nos poupa de muito trabalho. Com um Container, Certeza de segurana voc pode usar um deployment descriptor XML para configurar (e modificar) a segurana, sem ter que escrever direto no cdigo da classe do seu servlet (ou qualquer outro). Pense nisso! Voc pode gerenciar e alterar sua segurana sem tocar, ou recompilar, seus arquivos-fonte em Java.

Agora, tudo o que eu tenho que me preocupar como vender me suado plstico-bolha, em vez de escrever todos aqueles cdigos para as coisas que o Container far para mim ...

o
O

Suporte ao .,ISP Voc j sabe como os JSPs so legais. Bem, quem voc pensa que se encarrega de traduzir aquele cdigo JSP em Java de verdade? claro. O Container.

est

41

o Container
Co~o o Comaitter trata u~a solieita~o
Vamos economizar alguns dos cartuchos para mais tarde, mas aqui est um breve esquema:

o
container

dica em um link que contm uma URL para um servlet, em vez de uma pgina esttica.

o usurio

-,
Cliente

container "v" que a request para um servlet e ento ele cria dois objetos:

response

1) HttpServletResponse 2) HttpServletRequest

-.
Cliente

encontra o servlet correto baseado na URL da request, cria ou aloca uma thread para essa request, e passa os objetos request e response para a thread do servlet.

o container

42 captulo 2

arquitetura de alto nvel

, I

I
j

C1J
containe~~er~let
__

<--::::.J

O container chama o mtodo serviceO do servlet. do tipo de Dependendo] request, o mtodo serviceO chama ou o mtodo doGetO, ou o mtodo doPostO Para este exemplo, consideraremos que a request foi um HTTP
GET.

I !
"
1,1,:

request response.

'"/

serviceO

-.
Cliente

container response

servlet

I O

serviceO
,J.

O mtodo doGet gera uma pgina dinmica e a insere no objeto response. Lembrese, o container ainda tem uma referncia do objeto response!

doGetO

container

O thread termina, o container converte o objeto response em uma response HTTP, envia de volta ao cliente e apaga os objetos request e response.

re~ res~

voc est aqui ~

43

o cdigo

do servtei

Cot\to fica

cdigo (o que toma ut\t servlet Ut\tservletJ

PrintWriter out ~ response.getWriter(); java.util.Date today = new java.util.Date(); out.println(ft<html> ft + "<body>" + ft<hl style="text-align:center>" + ftHF\'s Chapter2 Servlet</hl>" + "<br>U + today + ft</body>" + ft</html>");

..

\4ce pl:Jtle c6J?se5uir PrlPi-PNl't-t-e1' ~ue

u~
I'ecebe

tJe+

6 seu

sel'vle+

d6

C6111+tJ.fPiel'. ti+lit"3e l:JPrlJ?.fWl'l-t-e1' pt1.Nl escl'evel'


J?()

-t-eX+6

#rJlA.L

tltJe+6 l'esptJlIIse. p<Jde 1._ I "" r r "'I""f:1' (j(l-rI't1.S 6pf6es de sQlda ale~ tltJ Prll1-PNl'lhl') dija~6sll pal'(J, escl'evel'.) e~ vej

Me;

u~1.l f~(lf'aJ hx+" ffrJlA.L)

de u~

f eth'untl5
r:

N9 exIst~m

Idl9tls

Voc foi muito superficial ao explicar como o container encontrou o servlet correto ... ou seja, como uma URL se relaciona com um servlet? O usurio tem que digitar o caminho exato e o nome do arquivo de classe do servlet?

r: e
I\:

Eu me lembro de ter visto o doGetO o doPostO, mas na pgina anterior voc mostrou o mtodo serviceO? De onde ele surgiu?

I\: No. Mas esta uma boa pergunta.

Mas ela nos leva a um Assunto Bem Grande (mapeamento de servlet e padres de URL). Portanto, daremos apenas uma rpida olhada nas prximas pginas, mas veremos muito mais detalhes adiante (no captulo sobre Distribuio).

Seu servlet herdou isso do HttpServlet, que herdou isso do GenericServlet, que herdou isso do ... ahhh, ns veremos muita hierarquia de classes no captulo Sendo um Servlet; portanto, aguarde s um pouquinho.

44

arq'uitE,1fW"a

de alto nvel

Voc est se perguntat1do et1cotttrou o Servlet ...

COlMO

o Contait1er

De alguma forma, a URL que chega como parte da solicitao do cliente mapeada para um servlet especfico no servidor. Este mapeamento de URLs para servlets pode ser tratado de vrias formas e um dos assuntos fundamentais que voc ir lidar como desenvolvedor de aplicao. A solicitao do usurio deve mapear para um servlet especfico e cabe a voc entender e (geralmente) configurar este mapeamento. O que voc acha?

EXERCITE
faz alguma coisa no browser (clica num link, clica no boto "Enviar", digita uma URL, etc.) e espera-se que esta ao envie a solicitao para um servlet especifico (ou outra aplicao como o JSP) que voc construiu. Como isso pde acontecer?

o usurio

Como o Container deveria mapear os servlets para as URLs?

Para cada um dos seguintes procedimentos, considere os prs e os contras.

Escrever o mapeamento direto no cdigo da sua pgina HTML. Em outras palavras, o cliente est usando o caminho exato e nome do arquivo (de classe) do servlet. PRS: CONTRAS:

Usar as ferramentas

do fabricante do seu Container para criar o mapeamento:

PRS: CONTRAS:

Usar algo como uma tabela de propriedades para armazenar os mapeamentos: PRS: CONTRAS:

voc est

45

o mapeamento

URLS para senl/ets

Uttt servlet pode ter fRS notttes


Um servlet tem um nome do caminho para o arquivo, obviamente, como classes/registrationlSignUpServlet.class (um caminho para um arquivo de classe real). O legtimo desenvolvedor da classe do servlet escolhe o nome da classe (e o nome do pacote que define parte da estrutura de diretrios), e o local no servidor define o nome completo do caminho. Mas qualquer pessoa que distribua o servlet tambm pode atribuir a ele um nome de distribuio especial. Um nome de distribuio simplesmente um nome interno secreto, que no precisa ser igual ao nome da classe ou do arquivo. Ele pode ser igual ao nome da classe (registration.SignUpServlet) ou o caminho relativo para o arquivo da classe (classes/registrationlSignUpServlet.class), mas tambm pode ser algo completamente diferente (como EnrollServlet). Pra terminar, o servlet tem um nome pblico de URL - O nome que o cliente conhece. Ou seja, o nome codificado no HTML de modo que, quando o usurio clicar em um link, que se supe que v quele servlet, este nome pblico de URL enviado ao servidor na solicitao HTTP.

()

Nome da URL conhecido pelo cliente


O cliente v uma URL que liga a um servlet (no HTML), mas no sabe realmente como esse nome de servlet mapeia para verdadeiros arquivos e diretrios de volta ao servidor. O nome pblico de URL um nome falso, criado para os clientes.

Nome interno secreto conhecido pelo distribuidor


O distribuidor pode criar um nome que somente seja conhecido apenas por ele e pelos outros que participam da rea operacional de verdade. Este tambm um nome falso, criado somente para a distribuio do servlet. Ele no precisa coincidir nem com a URL pblica usada pelo cliente, NEM com o nome do arquivo verdadeiro ou o caminho da classe do servlet.

Nome do arquivo verdadeiro


A classe do servlet do desenvolvedor tem um nome completamente qualificado, que inclui os nomes da classe e do pacote. O arquivo de classe do servlet possui um nome de arquivo e caminho real, dependendo de onde o pacote com a estrutura de diretrios resida no servidor.

46 captulo 2

arquitetura de alto nvel

Nossa, interessante como todo mundo quer expressar Sua criatividade e aparecer com seus prprios nomes para se referir mesma coisa. Mas por que ser?! Realmente? Por que ns todos no usamos o nico, real e inconfundvel nome do arquivo?

Mapear O nome dos servlets aumenta a flexibilidade e a segurana da sua aplicao.


Pense nisso. Ento, voc escreveu direto no cdigo o caminho verdadeiro e o nome do arquivo em todos os JSPs e nas outras pginas HTML que usam aquele servlet? timo. Agora, o que acontecer quando voc precisar reorganizar sua aplicao e, possivelmente, mover coisas para diferentes estruturas de diretrios? Voc realmente quer forar todos que usam aquele servlet a conhecer (e seguir eternamente) esta mesma estrutura de diretrios? Mapear o nome, em vez de codificar o verdadeiro caminho e nome do arquivo, garante-lhe flexibilidade ao mover as coisas. E evita aquele pesadelo na hora de acompanhar e mudar o cdigo do cliente que aponta para a antiga localizao dos arquivos dos servlets. E quanto segurana? Voc realmente quer que o cliente saiba exatamente como a estrutura no seu servidor? Voc quer que eles, digamos, tentem navegar diretamente para o servlet, sem passar pelas pginas e formulrios corretos? Pois, se o usurio final puder ver o caminho verdadeiro, ele pode digit-lo em seu browser e tentar acess-lo diretamente.

voc est

47

o mapeamento

do servlet no DO

Usando o VeploytMettt Vescriptor para tMapear as URLs aos servlets


Quando voc for distribuir seu servlet em seu Container, voc criar um documento XML, razoavelmente simples, chamado Deployment Descriptor (DD), para informar ao Container como executar seus servlets e JSPs. Embora voc use o DD para outras tarefas alm de simples mapeamento de nomes, voc usar dois elementos XML para mapear as URLs aos servlets - um para mapear o nome pblico de URL conhecido pelo cliente para o seu prprio nome interno, e o outro para mapear seu prprio nome interno para um nome de classe completamente qualificado.

Os dois elementos do DD para mapeamento de URL: <servlet>


mapeia o nome interno para o nome da classe completamente qualificado

<servlet-mapping>
mapeia o nome interno para o nome pblico de URL () elelJ\e'l-f.(j
'IalJ\e:> e IIsad"
IIIJ\ efew,fl'1+1J
li! 1Iw,

dtll$ sel'vle-f.s. "I''''"S''

p.n"r '\

( ~
...> name l</servlet-name>

<web-app

<sfl'vle+:> 4(jC{;j'l+4/~el'l' de
\ flJ\

fi <servlet> <servlet-name>Internal

I~sel'e

</servlet> ~{;ji'J{;jw,(! <servlet> <servlet-class>foo.Servletl</servlet-class> <servlet-name>Internal name 2</servlet-name> <servlet-class>foo.Servlet2</servlet-class> </servlet>

.................

'Ii!

<servlet-name>Internal name l</servlet-name> <url-pa~tern>/Publicl</url-pattern>

c~ss

tl </servlet-mapplng> ~ ti e1ew,e'l+/<serVlet-maPPlng> IS+tlftl


lisa 'ItI,
I.IIP\~ '~
li!: ti I'jt:;w,f! <servlet-mapping> <servlet-name>Internal

ftl,I'4

name

2</servlet-name>

<url-pattern>/Public2</url-pattern> </servlet-mapping>

;
</web-app> Z.

I
I.ISI' WtlJcllil'JS 1'10

48

arquitE1tW"a

de alto nvel

Mas espere!

retlt tltais coisa que voc

pode fazer COtlt o

UU

Alm de mapear URLs aos servlets verdadeiros, voc pode usar o DD para personalizar outros aspectos da sua aplicao, incluindo atribuies de segurana, pginas de erro, bibliotecas de tags, informaes sobre a configurao inicial e, se for um servidor J2EE completo, voc pode inclusive declarar que estar acessando enterprise javabeans especficos. No se preocupe ainda com os detalhes. O ponto crucial, por enquanto, que o DD oferece uma manira de modificar declaradamente a sua aplicao, sem alterar o cdigo- fonte! Pense nisso ... significa que mesmo aqueles que no so programadores Java podem personalizar sua aplicao Java, sem precisar arranc-Io das suas frias ao sol. N9
ex'Sbiom

o de,p19fment

de,SCtlpt9l" (DD) 9te,l"e,ce,um

me,cUllsm9 ~doolfltad9" pata a cust9m1zay9 das suas apl'lcly9e,s, se,m t9Cm' n9 c9dlg9--t9nte,!

r:

pethuntlS

Idl9tls
Os Benefcios do DO Reduz a necessidade de alterao do cdigo-fonte que j foi testado. Permite que voc ajuste os recursos da sua aplicao, mesmo que voc no possua o cdigo-fonte. Permite que voc adapte sua aplicao de acordo com diferentes recursos (como bancos de dados), sem ter que recompilar e testar nenhum cdigo. Facilita a manuteno das informaes dinmicas sobre segurana, tais como listas de controle de acessos e funes de segurana. Permite que aqueles que no sejam programadores modifiquem e distribuam suas aplicaes, enquanto voc d mais ateno s tarefas mais interessantes. Por exemplo, se o seu guarda-roupas est apropriado para uma viagem ao Hava.

Estou confuso. Olhando para o DO, voc ainda no tem nada que indique o verdadeiro nome do caminho do servlet! Apenas diz o nome da classe. Isto ainda no responde pergunta de como o Container usa aquele nome de classe para encontrar um arquivo de classe de um servlet especfico. Existe ainda UM OUTRO mapeamento em algum lugar que diga que tal nome da classe, mapeia para tal arquivo em tal lugar?

1\: Voc

prestou ateno. Voc est certo, pois colocamos apenas o nome da classe (totalmente qualificada para incluir o nome do pacote) no elemento <servlet-class> . Isso porque o Container tem um lugar especfico em que procurar por todos os servlets para os quais voc especificou um mapeamento no DO.

Alis, o Container usa um sofisticado esquema de regras para encontrar um par entre a URL que chega da solicitao do cliente, e uma classe Java real localizada em algum lugar do servidor. Mas entraremos neste assunto em um captulo mais adiante (em Distribuio). Por enquanto, o mais importante que voc deve lembrar que voc pode fazer isto mapeando.

49

Bob

se corresponde

no site

Histria: Job Cot1stri Ui\t Site de Et1cotrtros


Marcar um encontro est dificil hoje em dia. Quem tem tempo, quando tem sempre um outro disco para ser desfragmentado? Bob, que quer uma fatia desse mercado virtual (o que sobrou, pelo menos), acredita que criar um site de encontros especfico para nerds o seu passaporte para deixar o emprego Dilbertiano1 que ele tem agora. O problema que Bob j um gerente de software h tanto tempo, que ele est, digamos, por fora das prticas atuais de engenharia de software. Mas ele conhece alguns conceitos bsicos, um pouco de Java e j leu um pouco sobre servlets. Ele ento faz um projeto rpido e comea a escrever o cdigo ...

Input your state


Handle ~I ~
_

GeekDates

Age

~!

OS ~I

~
~! _

Attributes

Exceptionsl~

Refactor
Modify your profile:

DQLQuery

[profile hereJ

I===~ __ -===

50 caplitulo 2

arquitetura de alto nvel

Ele cotMea a construir utMa poro de servlets ... UtM para cada pgina
Ele pensava em ter um nico servlet, cheio de testes if, mas decidiu que servlets separados seriam mais 00 - cada servlet deveria ter uma responsabilidade, como a pgina de questionrio, a pgina de cadastro, a pgina com os resultados da busca, etc. Cada servlet ter toda a lgica de negcio que precisa para modificar ou ler o banco de dados e exibir o HTML de volta com os dados da resposta do cliente.

II

declaraes class void

de import DatingServlet extends Http$ervlet {

public

public

doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {

a lgica de negcio entra aqui, dependendo do que este servlet deve fazer (escrever para o banco de dados, PrintWriter

II II II II

fazer

a query,

etc.)

out = response.getWriter();

escreve a pgina HTML dinmica out.println( ~something really ugly here") ;

goes

101HI1

IonOI
1010100001.0

101101

lQHllOO

lOllOl
1010100001.0

f) servle-l101101 101101 WIOIOOOOIO

010101
lClOlOl
lClOlOlO 1001010101

10111100 (110101.
101C101 10101010 1001010101

fa~ 4 ?l.le ele precise par3.prtlCe:ssal" a S4IiClh{i4 (C4"M4/;,seri'r (J~ Jat/4 4(J prtIC(Jrlu' #tt! Je: t/aJ4s) e:

InputDQLServlet
SignupServlet

[J
web

DoDQLQueryServlet

1010100 010101
101(1101 1.0101010 1001010101

Accept 19nup ervlet

server/container
10110l
101101 10101000010

1/1714 #tarespt!#tse
1Ja a 145,o.Je pa51;,a Je respal1se J~ clte#t+e

1010100 010101
1010101 10101010 1001010201

AcceptProfiJeChangesServlet et

MainPageServ

InputProfileChangesServJet

c~Jij~ t/a

, , ,

voc est aqui ~

51

80b adiciona JSPs

Mas fica horrvel e ele acrescetrta os JSPs


Aquelas declaraes printlnO irritantes para sada de resposta se tomam realmente terrveis muito rapidamente. Ele l sobre os JSPs e decide fazer com que cada servlet faa qualquer que seja a lgica de negcios de que ele precise (query no banco de dados, inserir ou atualizar um novo registro, etc.) e encaminhe a solicitao para um JSP, que far o HTML para a resposta. Ele tambm separa a lgica de negcio da apresentao ... e j que ele andou lendo sobre desi~n, ele sabe que separar as preocupaes um Otimo Negcio.

o design deste

JSP est muito tranqilo. Agora. o cdigo do servlet est mais claro... cada

e chama um JSP especfico para


tratar o HTML que ser usado na
resposta, separando a lgica de negcio da apresentao.

servlet roda sua prpria lgica

II

declaraes class

de import DatingServlet extends HttpServlet request, {

public

public void doGet(HttpServletRequest HttpServletResponse response) throws IOException {

II II II II II II
}

a lgica de negcio entra aqui, dependendo do que este servlet deve fazer (escrever para o banco de dados, fazer a query, envia a solicitao a uma pgina JSP especfica em vez de tentar exibir o HTML junto com os dados de sada

etc.)

._'.

.InpulSignupJSP AcceplSignupJSP InputProfileChangesJSP

1.'.,'

AcceptPrOfileChanlj.~~.sSe~lel AcceplProfileChangesJSP MainPageJSP InpulDQLJSP DoDQLQueJYJSP

DoDQLQueryJSP

lJib ib

"'''J)

"

O cllf!l';.f.efl"eel';ct.e lilI"IYoVI!J.I"I4J !I'4L '4t1e~7 e c/tcl). 11t!J bI:J.f:a I~ s.f.e el';vi tlIYo4 slJlil+ali" Hrrp POSrfal"4 a D"J)$L$vel"]. O sel"vtJ,,1" ",ell ct.alYofJ.
serv1e+; servle+ execv+a a y,tler 1';" btJ.l1ctIJ ~e a JfJ.Js e f!11+'ifJ. sliCt+fJ.j'i f!I1CalYol;"t.aJ4 a J-sP o.fN'prltJ.JlJ, O ,)-sp CtIJl1s+rfJt N:sffJl1se Hrl..-tL e t.l Jev()/ve.
fJ

52 capitulo 2

arquitetura de a/to nvel

Mas etrto o seu aiMigo diz: "Voc ESr usando MVC, certo?
Kim quer saber se o servio de encontro pode ser acessado a partir de uma aplicao GUI Swing. Bob diz: "No, eu no pensei nisso." Ento, Kim fala: "Bem, isso no problema porque eu estou certo de que voc usou MVC, ento ns podemos preparar num instante um cliente GUI Swing, que possa acessar as classes lgicas de negcio." Bob: "Glup." Kim: "No me diga ... voc no usou MVC?" Bob: "Bem, eu separei a apresentao da lgica de negcio ..." Kim: "J um comeo ... ma~-ne adivinhar ... a lgica do seu negcio est toda dentro de servlets?!" Bob percebe, rapidamente, porque ele se tomou gerente. Porm, ele est determinado a fazer isto corretamente. Ento, ele pede a Kim uma explicao bem rpida sobre MVC.

Com o MVC a lgica de negcio no fica apenas separada da apresentao ... ela sequer sabe que EXISTE uma apresentao.
A essncia do MVC que voc pode separar a lgica de negcio da apresentao, mas ponha algo entre elas para que a lgica de negcio possa agir sozinha como uma classe Java reutilizvel, sem precisar saber nada sobre a view. Bob estava quase l, separando a lgica de negcio da apresentao, mas sua lgica ainda tem uma forte ligao com a view. Ou seja, ele misturou a lgica de negcio no servlet, o que significa que ele no poder reutilizar sua lgica em outros tipos de view (como um GUI Swing ou at mesmo uma aplicao wireless). Sua lgica est presa em um servlet, quando deveria estar em uma classe Java stndalone que ele pudesse reutilizar!

voc est

53

o padro de design MVC

o Padro de Projeto Model~View~Comroller (MVc) cot1serta isto


Se Bob tivesse entendido o padro de design MVC, ele saberia que a lgica de negcio no deveria estar inserida em um servlet. Ele teria percebido que com a lgica de negcio embutida no servlet, ele ficaria "em maus lenis" caso algum dia tivesse que acessar o servio de encontro de uma maneira diferente. Como na aplicao GUI Swing. Ns falaremos mais sobre o MVC (e outros padres) mais adiante, mas voc precisa de um rpido entendimento agora, pois o tutorial que construmos no final deste captulo usa o MVC. ~ Se voc j est familiarizado com ele, ento voc sabe que o MVC no especfico para servlets e JSPs - a clara separao da lgica de negcio da apresentao igualmente vlida para qualquer outro tipo de aplicao. Porm, com aplicaes web realmente importante, porque voc nunca deveria considerar que sua lgica ser acessada apenas da web! Estamos certos de que voc trabalha neste negcio h tempo suficiente para saber que a nica garantia em desenvolvimento de software : a especijicao sempre muda.

o M9del*VleW*C9ntt91let
(MVC) tet1tl l 1991clde neg9c19 t9tl d9 set\"let e l 09190lem um ~~M9de19" - uml llrt'lgl dlSseJl\"l, plqnl e teutJ'l1z\"e1. O lVl9de19 l 09mblnly9 d9S dld9S de neg9c19 (09m9 9 e5tld9 de um 0ltt1nb9 de 09mptls) e 95 mt9d95 (tegtl5) 'Lue 9tetlm nesses dld9S.

o MVC no mundo Servlet

& JSP
CONTROLADOR Retira da solicitao do usurio OS dados de entrada e interpreta o que eles significam para o modelo. Obriga o modelo a se atualizar e disponibiliza o estado do novo modelo para a view (o JSP).

VIEW
Responsvel pela apresentao. Ela recebe o estado do modelo do Controlador (embora no diretamente; o Controlador pe os dados do modelo em um lugar onde a View possa encontr-Io). Tambm a parte que recebe os dados de entrada do usurio que volta ao Controlador.

MODELO Abriga a verdadeira e o estado do modelo.lgica Em outras palavras, ele conhece as regras para obteno e atualizao do estado. O contedo de um Carrinho de Coml?ras (e as regras sobre o que fazer com isso) seria parte qo Modelo no MVC. E a nica parte do sistema que se comunica com o banco de dados (embora ele provavelmente use outro objeto para a verdadeira comunicao com o DB, mas guardaremos este padro para mais tarde ...).

Vlew

54 captulo 2

arquitetura de alto nvel

Aplicando o padro MVC na aplicao de encontros


Pois bem, Bob sabe o que precisa fazer. Separar a lgica de negcio dos servlets e criar urna classe Java normal para cada um ... para representar o Modelo. Com isso, o servlet legtimo ser o Controlador, a nova classe para a lgica de negcio ser o Modelo e o JSP ser a View.

1111101 10101MClllll
010>-01 1"101<1l

lGllCl lGUOJ. -0/ 111101001l0>-0


'-''I1G100 01010 1

In~~;~::pModcl

'-""~f1~ '"-~
InpulSignupJSP AcceplSignupJSP

i\

(~~Modm

AcceplProfileChangesServlet

DoDQIQueryServlel

~
AcceplProfileChangesJSP MainPageJSP

Ej,.\ .
""""'" </101,

:. -"-.-:'-. <'"_>_<ll> <'rI_,,",,"_.....

Ej~'
'J>ooo' (},,,,,,

~= ..._b";> "li"''''''''''' ...


-.::."?"

;.1

InputProfileChangesJSP

InpulDQLJSP

DoDQLQueryJSP

voc est

55

sim, mas isso um bom

Neste tMotMemo, seu atMigo KitM d utMa olhada Kim aparece e diz que embora esse SEJA um projeto MVC, ele ruim. Claro, a lgica de negcio foi colocada em um Modelo, e os servlets atuam como Controladores trabalhando entre os Modelos e as Views, para que o Modelo possa be brain-dead about the Views2 Isso tudo muito bom. Mas olhe para todos aqueles pequenos servlets. O que elesfazem mesmo? Agora que a lgica de negcio est "guardada" com segurana no Modelo, o Controlador do servlet no est fazendo nada alm de alguns trabalhos comuns para esta aplicao e, ah sim, ele atualiza o Modelo e coloca a View para funcionar. Mas o pior que toda aquela simples lgica de aplicao repetida em cada um daqueles malditos servlets! Se algo requerer alterao, ter que ser alterado em todos os lugares. A manuteno de um trem destroado est por vir. "Sim, eu no gostei muito deste cdigo duplicado", diz Bob. "Mas o que mais eu posso fazer? Naturalmente, voc no quer que eu ponha tudo em um simples servlet novamente? Como isso funcionaria?"

Que projeto mais fraco! Observe todos estes cdigos duplicados em cada servlet. Voc tem que adicionar o mesmo cdigo geral de aplicao, como segurana, na maioria dos servlets.

o o

56

de a/to nvel

Existe utMa resposta?


Ser que o Bob dev ria volta para apenas um Controlador de servlet para evitar cdigo duplicado? Isso seria um modelo 00 ruim, pois os servlets esto realmente fazendo coisas diferentes? O Keanu Reeves luta mesmo Kung Fu?

D o

EXERCITE SUA MENTE


Deixe isto para voc meditar. o que ns vamos fazer. O que voc acha? Voc sabe a resposta? EXISTE uma resposta? Voc concordaria com Bob e deixaria os servlets como eles so, ou colocaria o cdigo dentro de um nico Controlador de servlet? E se voc usar mesmo apenas um Controlador para tudo, como ele saber qual Modelo e View chamar? A resposta para esta pergunta no vir antes do final deste livro, ento pense nisso por alguns momentos e depois coloque numa thread em background na sua mente ...

voc est aqui...

57

captulo 2 - reflexo

Usando o MVC no mundo servlet & JSP, cada um destes trs componentes (JSP, classe Java e Servlet) desempenha um papel MVC. Circule "M", "V" ou "C", dependendo de qual parte do MVC o componente executa. Circule apenas uma letra por componente.

M V C
J'SP

O Container oferece sua aplicao web suporte em comunicaes, gerenciamento do ciclo de vida, suporte a multithread, segurana declarada e suporte para JSPs, para que voc possa se concentrar em sua prpria lgica de negcio. O Container cria um objeto request e response que os servlets (e outras partes da aplicao) podem usar para conseguir informaes sobre a request e enviar dados ao cliente. Um servlet tpico uma classe que estende o HttpServlet e sobrepe um ou mais mtodos de servio que correspondem aos mtodos HTTP ativados pelo browser (doGetO, doPostO, etc.). O distribuidor pode mapear uma classe de servlet para uma URL, que o cliente pode usar para solicitar tal servlet. O nome pode ser completamente diferente do verdadeiro nome do arquivo da classe.

M V C
non-servlet J'ava c1ass

M
V

C
servlet

O que as letras MVC representam design MVC?

no padro de

M significa
V significa C significa

_ _ _

58 captulo 2

arquitetura de alto nvel

Ap9nte seu lpis

Quem o responsvel?
Preencha a tabela abaixo, indicando se o servidor, o container ou um servlet o mais responsvel pela tarefa listada. Em alguns casos, mais de uma opo pode ser verdadeira para a tarefa especificada. Para justificar, acrescente um breve comentrio descrevendo o processo.

Tarefa
dinmicos elemento <servlet-class> DD solicitaes response HTTP Cria os objetos request e no response Converte um objeto response em uma Encontra URLs no DD Conhece HTTP Gerencia os ciclos de vida Coordena uma referncia onova preparo para de contedos o objeto Inicia Tem um uma nome que tbread coincide para com tratar oas Acrescenta Apaga objetos o HTML request ao objeto e response response Chama os o mtodo serviceO

Servidor

Container

Servlet

voc est aqui

li>

59

servlet

e exerccio

DD

ms

de G-ela-del'tL

Um servlet funcionando e o seu DD so misturados em uma frigideira. Voc capaz de unir os pedaos de cdigo recortados direita com a listagem incompleta esquerda, a fim de criar um servlet e um DD que funcionem e cuja URL termine com /Dice? possvel que alguns cdigos direita no sejam usados!

- Servlet
public public class void doGet( extends HttpServlet {

throws

IOException

String dI String d2

Integer.toString((int) ((Math.random()*6)+I; Integer.toString( (int) ((Math.random() *6) +1;

out.println("<html> <body>" + "<hl align=center>HF\'s Chap 2 Dice Rol1er</hl>" "<p>" + dI + " and " + d2 + " were rolled" + "</body> </html>");

-DD
teS+-4 #'/';6 <web-app
() f!;cf!iIP<pic

4 +-~de
#'/';tJ

det'+-vt'fI.
se #,/c flplfJ.1

c<!IlJY>le+- ftI1Cc#'/+-Nr

IS+(j

fJ.fe+a (; e;cet'c:C/~).

</web-app>

60

captulo 2

arquitetura de alto nvel

import import import

javax.servlet.*; javax.servlet.http.*; java.io.*;

public </url-pattern>

void service(

<servlet-name>

ServletRequest

requeSt'

PrintWriter

out

response.getWriter(); HttpServletResponse response)

<servlet-mapping> ServletResponse response,

<servlet-name>

</servlet-class>

HttpServletRequest

request,

PrintWriter

out

request.getWriter() ;

</servlet-name> <url-pattern> </servlet> <servlet-c1 </servlet-mapping>

voc est aqui ~

61

Responsabilidade

- soluo do exercco

Tarefa
classe pblica qualquer coisa exibir uma Usa-o para response servlet. cliente. Container. com o browser chamar iniciar a) thread. O Container response. para request. gera a stream o doPost( doGet( ) ou de o request e response Cria os objetos Para encontrar A o mtodo Chama o mtodo

Servidor web
encaminhar ao O contedo

eto

Logo antes de Usa-o service( para ) servlet. chama falar Sabe a quem a finalizado. partir dos thread Inicia o servlet uma de response HTTP as entrega ao Quando ocorreto servlet service (e outros que voc do cliente.

Container

Servlet
dinmico para o

62 captulo 2

arquitetura de alto nvel

C9nt1nuac;9da S91uc;9

d9s Exel'cc9S...

- Servlet
irnport javax.servlet.*; irnport javax.servlet.http.*; irnport java.io.*; public class xtends HttpServlet

HttpServletRequest

HttpServletResponse

PrintWriter

out

String String

dI d2

Integer.toString((int) Integer.toString((int)

((Math.randorn()*6)+I); ((Math.randorn()*6)+I);

out.println("<htrnl> <body>" + "<hI align=center>HF\'s Chap 2 Dice Roller</hl>" "<p>" + dI + " and " + d2 + " were rolled" + "</body> </htrnl>");

-DD-------------------

</servlet-narne> /url-pattern>

voc est aqui ~

63

Dois objetos, dois blocos

Ul\1 PeploYl\1ettt Pescriptor

(PP) "funcionando

No se preocupe com o que isto realmente significa (voc ver isto em outros captulos e far testes). Aqui, ns quisemos apenas demonstrar um DD web.xml que funciona de verdade. Ficaram faltando muitos pedaos a serem nseridos na tag de abertura <webapp> nos outros exemplos deste captulo. (Voc pode perceber porque ns geralmente no nclumos isso em nossos exemplos.)

A forma que geralmente mostramos no livro


<web-app ... >

<
Beer</servlet-name>

<servlet> <servlet-name>Ch3

<servlet-class>com.example.web.BeerSelect</servlet-class> </servlet> <servlet-mapping> <servlet-name>Ch3

Beer</servlet-name>

<url-pattern>/SelectBeer.do</url-pattern> </servlet-mapping> </web-app>

A forma que REALMENTE funciona

L
2 4.xsd"

<web-app xmlns=''http://java.sun.com/xml/ns/j2ee'' xmlns:xsi~''http://www.w3.org/2001/XMLSchema-instance'' xsi:schemaLocation~''http://java.sun.com/xml/ns/j2ee/web-app

version="2.4rT>
<servlet> <servlet-name>Ch3

Beer</servlet-n~me>

<servlet-class>com.example.web.BeerSelect</servlet-class> </servlet> <servlet-mapping> <servlet-name>Ch3

Beer</servlet-name>

<url-pattern>/SelectBeer.do</url-pattern> </servlet-mapping> </web-app>

64

arquitetura de a/to nvel

Cot\10

o J!EE cabe "isso tudo

O Java 2 Enterprise Edition meio um "superspec" - ele incorpora outras especificaes, incluindo a especificao Servlets 2.4 e a especificao JSPJ2EE 2.0. Isto para o Web Container. Porm, a especificao 1.4 tambm inclui a especificao Enterprise JavaBean 2.1 para o Container EJB. Em outras palavras, o Container web para EJB componentes web (Servlets e JSPs) e o Container para componentes de negcios. Um servidor de aplicao tota~ente web, compatvel com o J2EE deve ter tanto um Contalller como um Contai~er EJB (al~ de outras coisas, c?mo uma JNDI e uma lmplementaao JMS). O Tomcat e apenas um Cont~iner -:eb! Embora esteja de acordo s :pores da especIflcaao J2EE que se referem ao Contamer web. O Tomcat um Container web e no uma aplicao J2EE completa, pois ele no possui um Container EJB.

Um set"Id9t de aplIcac;9 J2EE IncluI tant9 9 C9ntmnet


1 7 C9m9 9 C9ntain " et EJB. Web

O ]9'mcat

um C9ntmnet

A Web7 mas N11.0 um set"Id9t

de apllcadi9 J2EE c9mplet9. T Um set"Id9t J2EE 1.4 IncluI a especltlcadi9 Set"let T especltlcac;.9 ElB 2.1.

2.4

a especltlcac;9 JSf 2. o e a

iJ2EE

Application

Server

r:
1\:

Ento o Tomcat um Container web standalone ... isso significa que tambm existem Containeres EJB standalone?

Antigamente, digamos, no ano 2000, voc encontrava servidores J2EE completos, Containeres web standalone e Containeres EJB standalone. Hoje, porm, quase que todos os Containeres EJB so parte de servidores J2EE completos, embora existam ainda poucos Containeres web standalone, incluindo o Tomcat e

o Resin. Geralmente, os Containeres web standalone so configurados para trabalharem com um servidor HTTP (como o Apache), embora o Container Tomcat possa atuar como um servidor HTTP bsico. Mas, para a funo de servidor HTTP, o Tomcat nem se aproxima da robustez do Apache. Por isso, as aplicaes web no-EJB mais comuns usam o Apache e o Tomcat configurados juntos - com o Apache como Servidor HTTP e o Tomcat como Container. Alguns dos servidores J2EE mais comuns so o Weblogic da BEA, o JBoss AS de cdigo aberto e o WebSphere da IBM. voc est aqui ~

65

Minitutorial do MVC

Criando e distribuindo uma aplicao Web MVC. Chegou a hora de colocar a mo na massa e escrever um formulrio HTML, um controlador de servlet, um modelo (classe Java simples), um deployment descriptor XML e uma view em JSP. hora de criar, distribuir e testar. Antes, porm, voc dever configurar seu ambiente de desenvolvimento - uma estrutura de diretrios para o projeto que esteja separado da sua aplicao real distribuda. Em seguida, voc ter que configurar o seu ambiente de distribuio, de acordo com as especificaes do servlet e do JSP, e as exigncias do Tomcat. A partir da, voc estar apto a comear a escrever, compilar, distribuir e executar. Concordo, construmos uma aplicao bem pequena. Porm, quase NO existe aplicao que seja to pequena e use o MVC. Afinal, a aplicao pequena de hoje o sucesso da internet de amanh ... este

um

novo captulo.

objetivos do exame oficial da Sun

o
Distribuio Aplicao Web
2.1 Construir a estrutura de arquivo e diretrios de uma aplicao que possa conter (a) contedo esttico, (b) pginas JSP, (c) classes servlet, (d) o deployment descriptor, (e) bibliotecas de tags, (f) arquivos JAR e (g) arquivos de classe Java. Descrever como proteger os arquivos de recursos do acesso HTTP. 2.2 Descrever o propsito e a semntica de cada um dos seguintes elementos do deployment descriptor: error-page, init-param, mirnemapping, servlet, servlet-class, servletmapping, servlet-name e welcome-file. 2.3 Construir a estrutura correta para cada um dos seguintes elementos do deployment descriptor: error-page, init-param, mimemapping, servlet, servlet-class, servlet-name e welcome-file.

Notas sobre a Abrangncia:


Todos os objetivos nesta seo so abordados completamente no captulo sobre Distribuio; aqui daremos apenas uma primeira olhada. Este o nico captulo com um tutorial completo, do incio ao fim. Portanto, se voc pul-Io, poder ter problemas mais tarde, quando for testar alguns outros exemplos nos prximos captulos (no repetiremos cada detalhe novamente). Assim como nos anteriores, voc no precisar se preocupar em memorizar o contedo deste captulo. Apenas v e faa.

68 captulo 3

praticando com o MVC

Vat\tos cot1struir ut\ta (pequetW aplicao de verdade


Ns vimos a funo de um container, falamos um pouco sobre deployment descriptors e demos uma primeira olhada na arquitetura do MVC Model 2. Mas voc no po.de ficar a sentado e lendo o dia todo agora hora de realmente jazermos alguma coisa.

Os quatro passos que seguiremos:

O Revisar as views do usurio (o que o browser mostrar) e a arquitetura de


alto nvel.

Criar o ambiente de desenvolvimento que usaremos neste projeto (que voc poder usar para qualquer outro exemplo no livro).

Gl

e
o

Criar o ambiente de distribuio que usaremos neste projeto (que voc poder usar para qualquer outro exemplo no livro).

_~

f~
_~

i~~
--...01_ ~

Desenvolver e testar repetidas vezes os vrios componentes de nossa aplicao. (Tudo bem, isto mais uma estratgia do que um passo.) Nota: Ns recomendamos desenvolvimentos e testes repetitivos, embora nem sempre mostraremos todos os passos aqui.

voc est aqui ~

69

A view do usurio

A View do Usurio para a aplicao "&eer Advisor" (Especialista eltt Cervejas)


Nossa aplicao ser uma esp~cialista em cervejas. Os usurios podero navegar em nossa aplicao, responder perguntas e receber conselhos valiosssimos sobre cervejas.

Beer Seleetion Page


Select ooer characteristics

~ .

t~ z.s.f-a HrM.l_ p~tP1a e ser: ti":


N!.sps.f-a eJ?vi'o,PldlJ CIJ~"
ClJir ~lIe
<)

lISllfJ.I'i'(>

Color:

{light

.;

s.f-a

lI~a

IJ clJPlselt. C(l~ base PIo.

dI) lISlIfJ.l'i6.

Beer Recommendations JSP


try: Jack's Pale Ale try: Gout Stout

f:

Por que estamos criando uma aplicao que d conselhos sobre cervejas?

1\:

Depois de uma exaustiva pesquisa de mercado, conclumos que 90% dos nossos leitores apreciam cerveja. Para os outros 10%, basta simplesmente substituir a palavra "cerveja" por "caf".

70 capitulo 3

praticando com o MVC

Aqui est a arquitetura ...


Ainda que esta seja uma aplicao bem pequena, vamos constru-la usando uma arquitetura MVC simples. Desta forma, quando ela se tomar O SITE mais badalado da web, estaremos prontos para aument-la. Container

-~
C(J;r/-l'cladcl"

1 - O cliente solicita a pgina jorm.html. 2 - O Container vai buscar a pginajorm.html. 3 - O Container retoma a pgina ao browser, o usurio responde s perguntas do formulrio e...
A-pe"llJ.s
tllJ'I

servlet

componente BeerExpert

D/J Java

tJldec.f.

JavlJ, sllty.>les). 4 - O browser envia os Container dados da solicitao ao container. 5 - O Container encontra o servlet correto baseado na URL e passa a solicitao para o servlet. 6 - O servlet pede ajuda ao BeerExpert. 7 - A classe responsvel retoma uma resposta, a qual o servlet adiciona ao objeto solicitao. 8 - O servlet encaminha a solicitao ao JSP. 9 - O JSP recebe a resposta do objeto solicitao. 10 - O JSP gera uma pgina para o Container. 11 - O Container retoma a pgina para o usurio feliz.

componente solicitao BeerExpert

voc est

71

ambiente de desenvolvimento

Criat'ldo

seu at\tbiettte

de deset1volvit\tettto

Existem vrias formas de voc organizar a sua estrutura de diretrios de desenvolvimento, mas esta a que recomendamos para projetos de pequeno e mdio portes. Na hora de distribuir a aplicao, copiaremos uma poro disso para onde quer que o nosso Container especfico queira. (Neste tutorial, usaremos o Tomcat 5.)

ru ""410.6 .- pl"eclstI. I,.v"ce


Jes-fe pal"tI. Jll"e-!-:1"16

---7

Sevs CtrJl'I1flJl1t:l1ffS Vrf!W es-!-:-I-rctrJs e


.....

6 -!-V-!-61"I"o.I)

JinlA",i(;s

fleal?! a~tlr.

li. rr~vi' V6Ce c161:f1.


6S (U'3V1'vtrJSJA-Je Je -hI"Cfi"S (J" Sfl"vle-!-rJe-vs).
J'

....
result.jsp form.html

T
Sve fica Sf!V

a~vr

f..XfI'l1fItJS Je fI.;vns C6l'11flJnel1-H::Svtew.

Je C4I1fijvl'o"';.

BeerSelect.java

BeerExperLjava

BeerSeleel.elass

BeerExperLelass

i. du

ave eS-!-lAl?!as tlSfl.I1J a pal"a

~j
JeepfJ.I"e~ve Sf!PD.I'D."'l'JSS CIJ"'fIJI?f!I?+es clJl?-!-I""'adal" ell'JS c""'fIJI1f!I?+es

eS-!-l"v-!-vI"o.-po.Jl"a

Pfl.C6+e;

d"

"'t>Jel.

pal"tI. ~ve I ps StI."'S b+el" S benef,cl6s 41l"h'iIU'"s elele: "7

I"5anl";4,';a

el" pl"~e-l-6

5eN!l?crD."'f!I1.f. ela 1?D.",espD.ce p61"-!-d"'Maele e I"f!lI-hlt";aj

72 capitulo 3

praticando com

o MVC

Criat1do

atMbiettte de

distribui~o

!s+e

ti dl"d:l"itJ

t.(JIr<f

Distribuir uma aplicao envolve seguir regras especficas do Container e requerimentos das especificaes dos Servlets e JSPs (se voc no est usando o Tomcat, ter que descobrir onde exatamente a sua aplicao ligar-se- ao seu Container). No nosso exemplo, tudo abaixo do diretrio "Beer -vI" igual, independentemente do seu Container!

dtl t;Ir<Cfi.~ +el" siiJ cI:'a.Ir<adde

+"Ir<ca-l(dllel"f~J

S-.O. da

Especfico para o Tomcat


s+e l1lr<f!de di'l'e+:l"iiJ
J //

's+a

es+I"I.I+vI"{J, lIle
1/ / dl"e-r,fjl"itJs e

If

+aJi'lblr<l"epl'f!:se~a

<:l

pe!tJ
/

e
lIla set/ t.(J~e,

C6J'if"'eX+ I"Mi

alie 1;;Ir<ca+ lisa 1JlIfU1tlfJ eS+a

es+al' daixIJ

l"esIJlvfl1d

fJJt.Ls. AJ:s exp!(Jl'ttl"f.Ir<(Js es+e c4I1ce4"(J '14 cap:+lIla sobl"e PiS+l"l!llll{(J.

telr< Ji'lQltJl"esJe+alt,es

tlll"ef-:f'ltJ

~
1;;J A-8A-I>j.o des+a p(ji1+lIt.aJn.
tJ.

hi1t.tJ.

. a o.plilJ.{; 3ve seI':

Ir<es~a; li1tlepe'1Je'1+e~ei1+e Idl"i::tJ.J1+e tllJ sell CIJW/-QIi1fl",

result.jsp

Parte da especificao dos Servlets


~

af'Vlvt'J ~
</webapp>

wd.xIr<1 es+1J.1"e~ wU;-IAlF

rM.

web.xml

A- es.fl'v+vl"tJ.
exa.faJi'lt!I1+e a

tles+e pt4c+e VStJ.Ji'l6S 116

Especfico da Aplicao

fJ.Ji'I!Ji'el1+e tle tlt!Sfl1l1d!Vllr<fl1+. Ir<el1"s 3ve SVtJ.ScltJ.sses (h,ItJ.l"eJi'llJs


t:l

A-

tllS+l"l!JVIi1tlt>
f.Ir<

Vir<

+tJ.l"tle)J de es.fl"v.fvl'{J, llr<eJi'a.ffi.Ir<e~


0010 100 0001 0101 00 1001 0011 0110

IAlFlda.sses.

BeerSelectclass

BeerExpert.class

voc est

73

construindo aplicao

Mapa para a COttstruo da aplicao


Quando iniciamos este captulo, definimos um processo de quatro etapas para desenvolvermos nossa aplicao. At agora ns j: 123Revisamos as views do usurio para nossa aplicao. Vimos a arquitetura. Criamos os ambientes de desenvolvimento e distribuio para montar e distribuir a aplicao.

Agora a vez da etapa 4: criar a aplicao. Ns tiramos isso de vrias metodologias conhecidas de desenvolvimento incansveis repeties) e adequamos aos nossos propsitos malignos ... (muita programao e

Os cittco passos que seguireiMos (ttOpasso 4):


~ Construir e testar o formulrio HTML que o usurio ir solicitar primeiro.

$Construir

e testar a verso 1 do servlet controlado r com o formulrio HTML. Esta verso

invocada via formulrio HTML e exibe o parmetro que ela recebe.

$
~

Construir

uma classe teste para a classe modelo/expert, alm de construir e testar a classe

modelo/expert em si. $Atualizar o servlet para a verso 2. Esta verso nos d a capacidade de chamar a classe

modelo a fim de obter os conselhos sobre cervejas. Construir o JSP e atualizar o servlet para a verso 3 (que agrega a capacidade de entregar para o JSP), e testar toda a aplicao.

74

praticando com o MVC

o HfML do forntulrio da pgina inicial o HTML simples - ele coloca o cabealho, a lista dropdown de onde o usurio seleciona uma cor para a cerveja e o boto Submit. <html><body>
<hl align=Hcenter">Beer Selection Page</hl>

<form method="POST" ~ action~"SelectBeer.do"> ~ Select beer characte:rstics<P>"Calor: <select name="colo:r"

Ar 3ve escljlt.eJr;ljsposre"",

vej P/e

-h"", es-h #'Ic~e. AJ';1j"': AJltblt #'Ia sva es-!-rv+vra P/eJtre+:rlcs

OfirMI- pe#'lsa 3ve c servle+

size="l "> c"'a"",aJIj .5elec+8eer.P/(J/ Is+"


amber lght </option> </oPtion

~ v"'"#'I{)~e 1:5lclJ

<option <opton

value="amber"> value="lght">

<option

value="brown">

brown </ oPtion>?

<option value="dark"> dark </option> </select> / <br><br> <center> <input type~"SUBMIT"> </center> </form></body></html>

hl asstltl, 3ve crto.""'(Js Q "",e#'lv pvll\ JMIl/#'IltI,assvas "pg';esfcJell'l varl"4l'. ..,J L ~/ .) 7 (\4ce e#'l~#'I"ev (J sl-t.e= I / I

r:

Por que o formulrio est enviando para "SelectBeer.do" se no h NENHUM servlet com esse nome? Nas estruturas de diretrios

que vimos anteriormente, no havia nada com o nome "SelectBeer.do". E o que significa a extenso" .do" afinal?

1\: SelectBeer.do

um nome lgico, no um nome de arquivo de verdade. simplesmente o nome que queremos que o cliente use! Alis, o cliente JAMAIS ter acesso direto ao arquivo de classe servlet. Portanto, voc no cria, por exemplo, uma pgina HTML com um link ou ao que inclua um caminho para um arquivo de classe servlet. O truque , ns usaremos o Deployment Descriptor XML (web.xml) para mapear o que o cliente requisita ("SelectBeer.do"), para um arquivo real de classe servlet que o Container usar quando entrar uma solicitao "SelectBeer.do". Por enquanto, considere a extenso ".do" como uma simples parte do nome lgico (e no um tipo de arquivo mesmo). Mais adiante, voc aprender outras maneiras de usar as extenses (reais ou fictcias/lgicas) em seus mapeamentos de servlet.

voc est

75

distribuindo

e testando

l1istribuit1do e testat1do

a pgit1a it1icial

Para test"la, voc precisa distribu-Ia na estrutura de diretrios do Container (Tomcat), iniciar o Tomcat e acessar a pgina em um browser.

8
o

Crie o HTML no seu ambiente de desenvolvimento


Crie este arquivo HTML, chame-o deform.html e salve-o em seu ambiente de desenvolvimento, sob o diretrio /beerVl/webl.

Copie o arquivo para o ambiente de distribuio


Coloque uma cpia (Lembre-se, do arquivoform.html tomeat/ webapps/Beer-vll. o diretrio em home do seu tomcat pode ter um nome diferente). ~ ~ ~

form.html

Crie o DO em seu ambiente de desenvolvimento


Crie este documento XML, nomeie-o de web.xml e salve-o em seu ambiente de desenvolvimento, sob o diretrio /beerVl/etc/.
LI . ,.., V6ce "tu" precisa Ct!JI1t.ecer

<web-app

xmlns~''http://java.sun.com/xml/ns/j2ee''lJ('

l1o.d4diSS,,; apel1{).s
2 4.xsd"

xmlns:xsi=''http://www.w3.org/2001/XMLSchema~instance'' xsi:schemaLocation=''http://java.sun.com/xml/ns/j2ee/web~app version="2.4fl>

I li" 'U:J~e:lteru::"" j I . I e ~ve Y<:Ice vsara

'<servlet> '<servlet~name>Ch '<servlet~class>c </servlet> Beer</servlet-name>

e~ "v+ras
.example.web.BeerSelect</servlet-class>

f'ar+es

d"

~
Beer</servlet-name>

AJ,,~e+(fa/~el1+e
ar3vry" de classe servle.f.

<servlet-mapping> <servlet-name>Ch3

'<url-pattern>/SelectBeer.do</url-pattern>

</servlet-mapPing~~f\: </web-app>

"

I;. :

fJ.S si'~ 3ve "tlf!N!~II'JS 3ve " clre,,~L se

AJ'i1l'J se es~vesa servler.

f)

.da

U I

,.., e apel1fJ.s V~IJ. C611I1el1jfJ.IJ.

de c,,~egtlr CIJII'I Vll'ltl barro..

76 capitulo 3

praticando com o fV1VC

A principal funo deste DD definir o mapeamento entre o nome lgico que o cliente usa na solicitao ("SelectBeer.do") e o arquivo de classe servlet verdadeiro (com.example.web.BeerSelect).

Copie o arquivo para o ambiente de distribuio


Coloque uma cpia do arquivo web.xrnI em torneat/ webapps/Beer- v IIWEB-INFI. Voc DEVE coloc-Io a para que o Container o encontre; do contrrio, nada funcionar, e voc ficar deprimido.

web.xml

Inicialize o Tomcat
Estamos usando ao longo do livro o Torncat tanto como Servidor, quanto como Container. No mundo real, voc provavelmente usar um web server mais robusto (como o Apache) configurado com um Container (como o Tomcat). Mas o Tomcat um servidor perfeitamente decente para tudo o que precisamos neste livro. Para iniciar o Tomcat, v para o diretrio home do tomcat e execute o bin/startup.sh.

Teste a pgina
Abra a pgina HTML no seu browser e digite: http://localhost: 8080/Beer-v 1/ fOfill.htrnl. Voc dever ver algo parecido com esta tela.

Beer Seleetion Page


Seleet beer eharaeteristics Color.

f light

i~l

voc~est

77

mapeando

o servlet

POST IBeer-VllSelectBeer.do
HTTP/1.1 Host
WV.rw.wickedlysmart.com

User-Agent Mozilla60 (MaCintosh- U' :CMaCOSXMaCh-o;en_US;rV;l.~) ck0/20030624 NetscapeJ7. J Accept telCt/xml,application! xmr,application/xhnnl+xml,text/ htmJ~O.9,text/Plain;q""0.8,video!x_ ~ng,image/png,imageljpeg,jmijge/ grf;q:oO.2//';Q"'.l ,

Cliente

Container procura o DD e encontra um <servletmapping> com um <urlpattern>, que coincide com o /SelectBeer.do, onde a barra (I) representa a raiz do contexto da aplicao e o SelectBeer.do o nome lgico de um recurso.
<web-apP>

<serv1et>
<servlet-name> Ch3 Beer </servlet-name> <servlet-class> b Beerse~ect . COIfL.examP1e.we </servlet-class> </servlet> <servlet-mapping>

<serV
Ch3

let _name>
Beer

eo

</servlet-name>

<url-pattern>
ISelectBeer.do </url-pattern> </servlet-mapping>

Container v que o <servlet-name> para esta <url-pattern> "Ch3 Beer". Mas este no o nome verdadeiro de um arquivo de classe servlet. "Ch3 Beer" o nome de um servlet, e no de uma classe de servlet. Container Para o Container, servlet aquilo que foi definido no DD, abaixo da tag <servlet>. O nome do servlet simplesmente o nome usado no DD, para que as outras partes do DD possam mape-Io.

</web-app>

78 captulo 3

praticando com o MVC

oo o

Container procura dentro das tags <servlet> a tag <servlet-name> "Ch3 Beer".

Container
<servlet-mapping> <serv1et-

O Container usa a <servletc1ass> da tag <servlet> para descobrir que classe servlet responsvel por tratar esta solicitao. Se o servlet no tiver sido inicializado, a classe carregada e o servlet inicializado.

Ch3 Bee
<servlet-name> <url-pattern>

IselectBeer.dO </url-patter~>
</servlet-mapplng> </web-app>

O Container inicia uma nova thread para tratar a solicitao, e passar a solicitao para a thread (para o mtodo serviceO do servlet).

resposta

O Container envia a resposta (atravs servidor, claro) de volta ao cliente.

do

Cliente

Container

voc esta

79

primeira verso do controador senret

A pritMeiraverso do cotttrolador servlet


Nosso plano construir o servlet em etapas, testando os vrios links de comunicao, conforme avanamos. No final, lembre-se, o servlet aceitar um parmetro que venha da solicitao, invocar um mtodo no modelo, salvar a informao em um lugar que o JSP possa encontr-Ia e encaminhar a solicitao ao JSP. Mas para esta primeira verso, nosso objetivo apenas garantir que a pgina HTML possa chamar adequadamente o servlet e que o servlet esteja recebendo o parmetro HTML da forma correta.

Cdigo do servlet
package com.example.web;

~S~IA cer'+" de ~ue voc US6UlU Itl.f!:SIYlfJ.S es+ru+uri1.s de df!sf!I1vcllll#i-.f!I1+t:> f! ~ / dts+l"i!JGI/"{~Uf! crl"aItl.CSal1+el"frltl.e,,+e.

import import import

javax.servlet.*; javax.servlet.http.*; java.io.*;

public

class

BeerSelect

extends

HttpServlet

tJ H#p:5erIl1e+ bel1eriCSerll1e-lj

es+e"de " GleIWtpleltl.el1+a

IAIYt.ferlace d Serllle+
{

public

void

doPost(HttpServletRequest HttpServletResponse throws IOException,

request, response) ServletException

response. setContentType PrintWriter

("text/html");

J::::- 'l.s.fe Itl.+d


Vf!ltl.dIA
;

out = response.getWriter(); Advice<br>")

out .println ("Beer Selection

:5erIl1e+Je,!!sp"""Sf!..
, ~

String c ~ request.getParameter("COIOr");~ out.println("<br>Got beer color " + c);

li S&lr'fltl.tfJS Jc.R.s+ pal"&l +rlA+ar IAsali'ct+a{ic


1'61$

~) f!.S.f-&lItl.If)S "el1t.vlYl

~S+e lIeltl. da ltl.+cd6 Ii?.ferlace :5erv1e+Jeevf!s+. Jeepar'f ve


<:)

Hrr~
IIIl"j=

IJ

fCl"ltl.vl:r'lJ ltl.e+t,lll=PtJ:5r

tfntA.L.

ar5vltl.e"+1J clJli?cide c<:)1tl. vll.l"r' 1l.+I"I"'!JV+t:>


/I

I1ll.ltl.e "14 <selec+> dtfJ

APls itMportantes

80

praticando com

o MVC

COlMpilando, distribuindo e testando o cotttrolador servlet


Perfeito! Ns construmos, distribumos e testamos nosso HTML, e construmos e distribumos nosso DD (bem, colocamos o web. xml no ambiente de distribuio, mas tecnicamente o DD no ser distribudo at reiniciarmos o Tomcat). Agora hora de compilar a primeira verso do servlet, distribu-I o e test-Io via formulrio HTML. Vamos reiniciar o Tomcat para garantir que ele "enxergue" o web.xml e a classe servlet.

Compilando o servlet
Compile o servlet usando -d para colocar a classe no ambiente de desenvolvimento.
CCl1liJvre

ttle cI1ctJa C<:l~ I) c4~11t.1) de dtre.f.JU"I't!S #16 setl 1'1 I Sl"s.f.e*lti.. 1;;d6 IJf>)'S .f.lt'oca.f. sei"a iJVo.l.

ts.f." faro.

1"

I
(J se

n ....
;

lJ se';

4f'f6 -{ fai"Q. l1-/fJi"I't'iI'U"ti,) Cl!P>fllo.di" pl'J.i"4 (;lJlfJcal"


05 PlIJ

tl fM.f.

e IIIt'jula

li 1J.i"~1I1"v(J ,das ts.f.rv.f.vi"IJ.

{tre.f.:i"I't!

de

c/(J;sses; de#1.f."tJi {a

l1 SI"s-l-i!""tJ.fel"IJ.CI't!I?I'J.! WI1{WS

Ci"l"e.f.1J. {1/} flJ.cff.

Setl

at'~vlvQ

,c/ass vai' webl.

acabai" e"'" IbeerV

IlclQ.sstslcfJl't'ilelfal!P>f1el

Distribuindo o servlet
Para distribuir o servlet, faa uma cpia do arquivo .class e mova-o para o diretrio /Beer-vlIWEB-INF/dasses/comlexample/web/ na estrutura de distribuio.

Testando o servlet
I - Reinicie o tomcat! 2 - Abra seu browser e digite: http:// localhost: 8080/Beer -vI /form.htrnl 3 - Selecione uma cor de cerveja e dique em "Submit" 4 - Se o seu servlet estiver funcionando, voc dever ver no browser a resposta do servlet parecida com: Conselhos sobre Escolha de Cerveja Voc escolheu a cerveja marrom

FI

Ed" Wid

Hl

SI hdtM

% %

cd tomcat bin/shutdown.sh

% bin/startup.sh

http://localhost:8080

Beer Seleetion Page


Sckct bcen;l1arncterisocs

Color::ug~

voc est

81

classe modelo

Cot1struit1do e testat1do

a classe tModelo

No MVC, o modelo tende a ser o "back-end" da aplicao. Em geral, o sistema tradicional que est sendo exposto na web atualmente. Em muitos casos ele apenas um cdigo Java simples, sem saber que talvez possa ser chamado pelos servlets. O modelo no deve ficar restrito a ser usado por somente uma nica aplicao, portanto ele deve ficar dentro dos seus prprios pacotes de utilidades.

As especificaes para o modelo


Seu pacote deve ser com.example.model Sua estrutura de diretrios deve ser /WEB-INF/c1asses/com/example/model Ela disponibiliza um mtodo, getBrandsO, que obtm uma cor preferida (como um String) e retoma uma ArrayList de marcas de cervejas recomendadas (tambm como Strings).

Construa a classe de testes para o modelo


Crie a classe de testes para o modelo (sim, antes de construir o modelo em si). Aqui, voc est por sua prpria conta, pois no temos uma neste tutorial. Lembre-se, o modelo ainda estar no ambiente de desenvolvimento quando voc test-Io pela primeira vez - como outra classe Java qualquer, e voc pode test-Io sem o Tomcat.

Construa e teste o modelo


Os modelos podem ser extremamente complicados. Eles freqentemente envolvem conexes com bancos de dados tradicionais e chamadas a lgicas complexas. Aqui est nosso sofisticado e inteligente sistema baseado em regras que d conselhos sobre cerveja:
package com.example.model; import java.util.*; public class BeerExpert { public List getBrands(String color) List brands = new ArrayList(); if (color.equals ("amber")) { brands.add("Jack Amber"); brands.add("Red Moose");
}

C4i1'1l

Cap+VI'Il."'4S

as ,;;ftU"'tl.gDes

especi'Q!"~flI.dtl.s e clJ"'P1l!xas dlJ l!Xl!"'P!1J da cel'v~4.J vSIJ.'IdlJ expl'es sDes ct:J'Idi'ci'IJ'Iais alla'lsadfl.s.

else { brands.add("Jail brands.add("Gout


}

Pale Ale"); Stout") ;

return(brands);

% cd beerVl % java -d classes

src/com/example/model/BeerExpert.java

82

praticando com o fvlVC

Melhorando o servlet para chatMar o tModelo,para obtertMos conselhos VE VE~VAVE...


Nesta segunda verso do servlet, iremos melhorar o mtodo doPostO para chamar o modelo para oferecer o conselho (a verso trs far com que o conselho venha de um JSP). As alteraes de cdigo so triviais, mas a parte importante entender a redistribuio da aplicao melhorada. Voc pode tentar escrever o cdigo, recompilar e distribuir por sua prpria conta, ou ento virar a pgina e seguir adiante ...

AP9nte seu lpIS Melhorando o servlet, verso dois


Esquea os servlets por um minuto, vamos pensar apenas em Java. Quais so os passos que devemos tomar para realizar estas tarefas? 1. Melhorar o mtodo doPostO para chamar o modelo. 2. Compilar o servlet. 3. Distribuir e testar a aplicao atualizada.

voc est

83

chamando o modelo para o controlador servlet

cdigo do servlet verso dois

Lembre-se, o modelo apenas Java simples, ento o chamaremos como faramos para qualquer outro mtodo Java: instanciar a classe modelo e chamar o seu mtodo!
package import import import import import public com. example. web; com. example .model. *; javax.servlet.*; javax.servlet.http.*; java.util.*;. java .io. * ; / class BeerSelect void extends

V-

AJ se eS3f1esa lJ i"Y>tJt''';'' parti. 8eerl.xper";" es";": l'P7seri(Jl).

tJ

PQC..fe lJI'lille "

Ct'IfJ.I1"lJ ulI';a I1"V4 cltJ.sse. S.ffJ.IMS 1I';1IJ"i'Ii'ct/,l'UJlJ (J servle";"


HttpServlet (

J
rij/'P7al

e l1"

public

doPost(HttpServletRequest HttpServletResponse throws IOException,

request, response) ServletException

String

c = request.getParameter("color"); ~

List result be = be.getBrands(c); = new BeerExpert();~ BeerExpert

II1S";"fJ.l1clfJ.1' 4 classe 8eet'1..J(fel''';''


response.setContentType("text/html"); PrintWri ter out = response. getWri ter (); C tllI';I lJ ,e out.println("Beer Selection Advice<br>");

fi!

li

";"8,,, () t'tll1 s

Iterator it = result.iterator(); while(it.hasNext( { out.print("<br>try: " + it.next(;

praticando com o MVC

Os prit'lcipais passos para o servlet verso dois


Temos duas tarefas importantes a fazer: recompilar o servlet e distribuir a classe modelo.

Compilando o servlet
Ns usaremos o mesmo comando compilador que usamos quando construimos a primeira verso do servlet.
FI Edl '1" d Hei PI Go
<

% cd beerV1 % javac -classpath

/Users/bert/Applications2/tomcat/common/libl servlet-api.jar:classes:. -d classes src/com/example/web/BeerSelect.java __ ~~_~_'q,,,"_,,,,.

Distribuindo e testando a aplicao


Agora, alm do servlet, ns tambm temos que distribuir o modelo. Os principais passos so: 1Mova uma cpia do arquivo .class do servlet para:

../Beer-v lIWEB-INF /classes/com/example/web/ Isto substitui a primeira verso do arquivo de classe do servlet! 2Mova uma cpia do arquivo .class do modelo para:

../Beer-v l/WEB- INF /classes/com/example/modeV 3Feche e reinicie o tomcat

4 - Teste a aplicao via form.html; o browser dever mostrar algo como: Conselhos sobre Escolha de Cerveja experimente: JackAmber experimente: Red Moose
Fie Ed"! Wndow Help S IIH h

cd tomcat

% bin/shutdown.sh % bin/startup.sh

5elect beer chamcteristics.

COIDr::'Ii!lht',;i

~~/

voc est

85

a aplicao MVC

Revendo a aplicao MVC, parcialt\1ente cot\1pleta, que d conselhos sobre cervejas

o que est

funcionando at aqui ...


Container

Lgica do Container

I~. ;;:.;;,
~

~t
componente BeerExpert

1 - O browser envia os dados da solicitao para o Container. 2 - O Container encontra o servlet correto baseado na URL e passa a solicitao para o servlet. 3 - O servlet chama o BeerExpert para ajudar. 4 - O servlet exibe a resposta (que exibe o conselho). 5 - O Container retoma a pgina para o usurio feliz.

o que ns QUEREMOS...
1 - O browser envia os dados da solicitao ao Container. 2 - O Container encontra o servlet correto baseado na URL e
Container

passa a solicitao ao servlet. 3 - O servlet chama o BeerExpert para ajudar.

4 - A classe responsvel retoma uma resposta, que o servlet adiciona ao objeto request. 5 - O servlet encaminha a solicitao para o JSP. 6 - O JSP recebe a resposta do objeto request. 7 - O JSP gera uma pgina para o Container. 8 - O Container retoma a pgina para o usurio feliz.

86 carltulo 3

praticando com

o MVC

Criando a "view'" JSP que d o conselho


No fique to ansioso. Voc ter que esperar mais alguns captulos antes de realmente comearmos a falar sobre JSPs. Na verdade, este JSP nem to bom assim (devido ao seu cdigo scriptlet, que falaremos mais adiante). Por agora, ele deve ser bem fcil de ser lido, e se voc quiser experiment10, mos obra. Embora ns pudssemos testar agora este JSP direto do browser, vamos esperar at depois de modificarmos o servlet (verso trs) para ver se ele funciona.

Aqui temos o JSP...


<%@ page <html> <body> <hl align="center">Beer <p> <% import~"j ava. util.

s,/-o.

"'''ta
S~4

tlt,.ehv4

de p:5'-l'Ia

*"

%>

(es.J.a"t6s ~ e/a

c6l'1sile"lJ.l'ldlJ 3",e 6 3",e be"t :bVI"6).

Ia;

Recommendations

JSP</hl>

n'5"'''t

H rM.L p,uJ,.lJ

(3",e e

cDJ'It.ecillJ ClJ"tlJ .fe41p/4.fe


List styles - (List) request.getAttribute Iterator it ~ styles.iterator(); while (it. hasNext ()) ( out.print("<br>try: " + it.next()); ("styles") ;

.fe1e.J.

1'16"t"'l?dlJ J.sf1.

~
A-3v/~ esh."t6s "ece!JeI?J6 V/IfI

%>
</body> </html>

!t'5V"t

J4V4 plJ.d,." del'l.J."lJ das CIJ"t1J

a..J.,..l!JlI.J.1J dlJ IJtje.J.6 S6/tcl.J.lJ.j6. fJ"t PIJVClJ "tais adl41'1.fe;

+';3s <% %> (clJl?t.eddlJ ClJd~lJ scrtp.J.te.J.).

flep/i"cfJ."e"t6s

.J.(/dlJ s66N!

a..J.,..l6",.J.IJS e C"tlJ cl?se5""N.IJS ,,6.fe,.


IJ

IJtje.J." SIJ/lci.J.lJ.jlJ

Distribuindo o JSP
Ns no compilamos o JSP (o Container faz isso na primeira solicitao). Mas ns temos que: 123Cham-Io de "result.jsp". Salv-Io no ambiente de desenvolvimento, em: /webl.

Criar uma cpia dele no ambiente de distribuio, em: /Beer-vII.

result.jsp

form.html

voc est

87

despachando uma solicitao para o JSP

Melhorat1do

servlet para "chatMa(~O JSP (verso trs)

Neste passo, modificaremos o servlet para "chamar" o JSP para gerar o resultado (view). O Container providencia um mecanismo chamado "request dispatching", que permite que um componente gerenciado pelo Container chame por outro. assim que usaremos: o servlet receber a informao do modelo, ir salv-Ia no objeto solicitao e entregar a solicitao para o JSP.

Mudanas importantes que devemos fazer no servlet:


I - Adicionar a resposta do componente modelo ao objeto request, para que o JSP possa acess-Ia. 2 - Pedir ao Container que encaminhe a solicitao para "result.jsp" (passo 5). I - O browser envia os dados da solicitao para o container.
Container

2 - O Container encontra o servlet correto baseado na URL e passa a solicitao ao servlet. 3 - O servlet chama o BeerExpert para ajudar. 4 - A classe responsvel retoma uma resposta, que o servlet adiciona ao objeto solicitao. 5 - O servlet despacha para o JSP. 6 - O JSP recebe a resposta originada do objeto solicitao.
solicitao

7 - O JSP gera uma pgina para o Container. 8 - O Container retoma a pgina para o usurio feliz.

88

praticando com o fvJVC

o cdigo

para o servlet verso trs

Eis aqui o que modificamos no servlet para adicionar a resposta do componente modelo ao objeto solicitao (assim o JSP poder recuper-Ia) e como pedimos ao Container para despachar ao JSP.
paekage import import import import import publie eom.example.web; com.example.model.*; javax.servlet.*; javax.servlet.http.*; java.io.*; java.util.*; elass BeerSelect extends HttpServlet (

publie

void

doPost(HttpServletRequest request, HttpServletResponse response) throws IOExeeption, ServletException (

String c ~ request.getParameter(~color"); BeerExpert be ~ new BeerExpert(); List result ~ be.getBrands(c);

Ii
II

response.setContentType(~text/html"); out = response. getWriter Adviee

tt161"4 ~vetJ JSPVfJljf.I"til.1" til 1"esUI.f-{).(/c Jeveh\s I"e~vel" J(J;


) () ;~sel"vld61"e.sUI.f-4Jti

I I PrintWriter

Jti
t""

out. println (~Beer Seleetion

<br>");

1;fl.l1sll"WiG.~s
...

pfJJ"fl.

Zue

VCe' fJ.t;;JtJ. P"SSt1,

A-di'ci'tJl1fJ. u"" request.setAttribute(~styles", result);.J

l6e.f-6 s6Itct.f-tJ.jfICi ~
/

VSfJ.I".N'T'e 3ve (j pI"CCUI"fJ.l1dCi Pt:J1"

I 1_

RequestDispatcher

view .
1I1s+fJ.J"JclQ. VI!?!

request.getRequestDispatcher(~result.jsp");~ view. forward(request, ~


fJ SfJ..,

response);

J.
~t~4~~~

1"t!1JUt!S.fdi'spa.f-ct.el" pal"ti.
til.Q

pf.Jll"

C"I1.f-fJ.i;;f.1"

ave

l'i7i(;tfJ.lt-;t! '"
til.

J.sfJ., f!I1VifJ.I1J6 paN. e/e e


fJ.

scllcl-l-a{iJ

l"t!sp"S.f-u..

voc est aqui...

89

comple, distribua

e teste

CotMpile,distribua e teste a aplicao final!


Neste captulo, construmos uma aplicao MVC completa (embora pequena), usando HTML, servlets e JSPs. Voc j pode incluir isso no seu currculo.

Compilando o servlet
Usaremos o mesmo comando compilador que usamos antes:
d" Wi R I

% cd beerVl % javac -classpath

/Users/bert/Applications2/tomcat/common/lib/ servlet-api.jar:classes:. -d classes src/com/example/web/BeerSelect.java

Distribuindo e testando a aplicao


Agora hora de redistribuir o servlet. 1 - Mova uma cpia do arquivo .class do servlet para ../Beer-vlIWEB-INF/c1asses/comlexample/web/ (novamente, isto ir substituir o arquivo .class da verso dois anterior).

2 - Feche e reinicie o tomcat.

3 - Teste a aplicao via form.html.

Beer Recommendations

JSP

90 captulo 3

praticando com o MVC

Tudo bem, ento agora ele sabe fazer uma aplicao MVC, mas ele ainda no tem nenhuma idia de como usar a linguagem JSP ou JSTL. Ele no sabe nem usar uma tag customizada, nem um Itro. E eu o f1agrei escutando um CD do Weezer ... e isso foi DEPOIS daquele lbum verde. Ele aind tem MUITO o que aprender ...

Ait1da h tltuito

que apret1der.

A festa acabou. Voc teve trs captulos inteiros para curtir, escrever um pequeno cdigo e revisar tudo sobre solicitao/ resposta HTTP. Mas ainda existem 200 perguntas preparatrias esperando por voc neste livro. E elas comeam no prximo captulo. A menos que voc j esteja familiarizado com desenvolvimento e distribuio de servlets, voc no deveria virar a pgina antes de realmente jazer o tutorial deste captulo. No que estejamos tentando pression-Io, ou faz-Io se sentir culpado, ou algo parecido ...

voc est aqui ~

91

Sendo um Servlet
Ele usou uma solicitao GET para atualizar o banco de dados. A punio ser a mais severa ... sem aulas de "Ioga com Suzy" por 90 dias.

Servlets vivem para servir clientes. A funo de


um servlet

receber

uma solicitao do cliente e devolver

uma resposta. A solicitao talvez seja simples: "traga-me a pgina de Boas-vindas". Ou pode ser complexa: "Finalize o processo do meu carrinho de compras." A solicitao traz consigo dados cruciais e o cdigo do seu servlet tem que saber como encontr-Ias e utiliz-Ias. A resposta leva a informao que o browser precisa para montar uma pgina (ou baixar alguns dados) e o cdigo do seu servlet tem que saber como envi-Ias. Ou no ... em vez disso, seu servlet pode decidir encaminhar a solicitao adiante (para outra pgina, servlet ou JSP).

este um novo capitulo"

93

objetivos do exame oficial da Sun

Modelo de Tecnologia do Servlet


1.1 Para cada um dos Mtodos HTTP (como GET, POST, HEAD e assim por diante), descrever o propsito do mtodo e as caractersticas tcnicas do protocolo do Mtodo HTTP, listar triggers que possam levar o cliente (geralmente um browser) a usar o Mtodo e identificar o mtodo HttpServlet que corresponda ao Mtodo HTTP.

Notas sobre a Abrangncia:


Todos os objetivos desta seo so cobertos completamente neste captulo, com exceo da parte dos cookies, no objetivo 1.3. Grande parte do contedo deste captulo foi comentada no captulo dois, mas l ns dissemos: "No se preocupe em decorar isto. " Neste captulo, voc TEM que ir devagar, realmente estudar e memorizar o contedo. Nenhum outro captulo cobrir estes objetivos com detalhes; ento, esta a hora. Faa os exerccios, revise o material efaa seu primeiro teste preparatrio nofinal deste captulo. Se voc no conseguir pelo menos 80% das respostas corretas, volte para descobrir o que voc deixou escapar, ANTES de passar para o captulo cinco. Algumas das perguntas do teste preparatrio que fazem parte destes objetivos foram colocadas nos captulos 5 e 6, por requererem um conhecimento adicional de alguns assuntos que no explicamos at aqui. Isto significa que teremos um nmero menor de questes preparatrias neste captulo e maior nos prximos, evitando test-lo naquilo que voc ainda no viu.

1.2 Usando a interface HttpServletRequest, escrever o cdigo que retira da solicitao os parmetros do formulrio HTML, a informao do header da solicitao HTTP ou os cookies.

1.3 Usando a interface HttpServletResponse, escrever o cdigo que cria um header para a resposta HTTP, configura o tipo de contedo da resposta, recebe um stream de texto para a resposta, recebe um stream binrio para a resposta, redireciona uma solicitao HTTP para outra URL, ou adiciona cookies na resposta. *

1.4 Descrever o propsito e a seqncia de eventos do ciclo de vida de um servlet: (1) carregar a classe servlet, (2) instanciar o servlet, (3) chamar o mtodo initO, (4) chamar o mtodo serviceO, e (5) chamar o mtodo destroyO.

Nota importante: enquanto os trs primeiros captulos abordaram assuntos que servem de base, desta pgina em diante quase tudo o que voc ver est diretamente relacionado ou explicitamente parte do exame.

*No falaremos muito a respeito dos objetivos relacionados cookies at o captulo que trata das Sesses.

aos

94 captulo 4

solicitao

e resposta

Os Servlets so cot1trolados pelo Cotttaitter


No captulo dois ns vimos as funes completas do Container na vida do servlet: ele cria os objetos request e response, cria ou aloca uma nova thread para o servlet e chama o mtodo serviceO do servlet, passando as referncias de request e response como argumentos. Aqui vai uma rpida reviso ...

clica em um link que tem uma URL para um servlet.

o usurio

-,
Cliente

request

"v" que a solicitao para um servlet e cria dois objetos: 1) HttpServletResponse 2) HttpServletRequest

o Container

-Cliente

L'

o Container encontra o servlet correto baseado na URL da solicitao, cria ou aloca uma thread para a solicitao e chama o mtodo serviceO do servlet, passando como argumentos os objetos request e response.

voc est

95

Servlet no container

A histria cotttit'lua...

..)
Cliente doGet(request,


response)

serviceO descobre qual mtodo do servlet chamar, baseado no Mtodo HTTP (GET, POST, etc.) enviado pelo cliente. envia uma solicitao HTTP GET, para que o mtodo serviceO chame o mtodo doGetO do servlet, passando como argumentos os objetos request e response.

o mtodo

o cliente

..)
Cliente

request

servlet usa o objeto resposta para escrever a resposta para o cliente . A resposta volta atravs do Container .

Container

Quando o mtodo serviceO termina, a thread morre ou retoma para um pool de threads gerenciadas pelo Container. As referncias dos objetos solicitao e resposta saem do escopo e eles se do mal (prontos para virarem lixo). O cliente obtm a resposta.

96 capitulo 4

solicitao e resposta

Mas a vida do servlet t1o s isso


Ns fomos at o meio da vida do servlet, mas ainda existem perguntas: Quando a classe servlet foi carregada? Quando o construtor do servlet foi executado? Quanto tempo vive o objeto servlet? Quando o seu servlet deve iniciar os recursos? E quando ele deve limp-Ias?

o ciclo de vida do servlet simples: existe apenas um estado principal


- inicializado. Se o servlet no est inicializado, ou ele est sendo inicializado (rodando seu construtor ou o mtodo initO), sendo destruido (rodando seu mtodo destroyO), ou simplesmente no existe.

construtor initO

destroyO

Contain~r web

Classe

~ervlet
I

Objeto 1"ervlet

hd
:Carreoar classe

I:::~::J
AServl~t.class r

o CtJl1s-l-r'V-ftJI'7,Ri/I'';tl",J4
ser'lIle-lri/o. (lIc

sfla elas se i/el/e escrever Il'l1eclJ

IJt}O

fi"" CI1S-fl'fI-I-I'J vse ., po.i/I'';''


C1l'l ()

sev C"'f'lIfJ.i/ffJl').

Instanciar o servlet (o c~nstrutor roda)

Ct.41WJ.J apel1fJ.S UM
initO v"i/s.da

Vi2,i/Vt'4nfe
() set'lIi'ceO.

ti

sel'v'dj

deve c~,eff41'
ct.a~

r
A-3(1t ~ 4'1Je {; ~et'lIle+ p/J,ssa a I>\/J,'I' par-l-e
J..e:

lpe ti ~atl1f!l'

s(la IItJa.

serviceO

destrovO

o CffJl1-1-at"l'lf!t'ct.a1l'lfl.pal'R
set'vle-li/e iI'I<ll't'et' (~vel' dtjel'j

daI'

a<l

fliI'Ia cl.fJ.l1ce de Ii'""ftl.t' tl.l1hs fi!s+tJ.r'


IJ

pl'epfJ.Nl.diJ pal'tJ. I/t"ral" ''';ce). C"ljU:l

t"l'lr+oJ eJe . Ct.RiI'I4dlJ tJ.pfi!I1RS V1I'ItI. ve'],

voc est aqui

li>

97

o servlet AP!
IJ6-1-a:

..

IJlfo

ffJ1ff

lI\e1l\61't;41' -I-l/d6 i'S-I-6

h.J6NJ.!P,eJ1tJ.sSI.,,-I-4C611\6 a

IfPI -I-l'daI1.4

Seu servlet herda os Ifttodos do ciclo de vida

mter ace
Servlet ervice(ServletRequest, ServletResponse) nit(ServletConfig) estroyO etServletConfigO etServletlnfoQ

A interface Servlet (j avax. serv let. Servlet)

If l;,ffrf(J,ce Servle.-I- ~(t; 31/e-!-#das as se.l'vle-l-s P6SS(Jt'1I\t'SffS CI;'CfJ 1I\:-I-ad6s


(s -I-/es ell\ J1t'jrt-l- sa 1I\:-I-(jdfJS refel'el'JffS (J,(j ci'cl de VI"JfJ,).

I
Generic
serVIce ervletRequest, nit(ServletConfig) 'nitO destroyO getServletConfigO getServletInfoO getInitParameter(String) getInitParameterN amesO getServletContextO log(String) log(String, Throwable) A classe GenericServlet (j avax. servlet. GenericServ let) be'lel'i'cSel'vle.f: 1~/e~e'l-l-a (JII\IJ. classe ds-I-I'IJ.-I-a ~I/e

a /illifJ.tfJrta dfJS /iIIi:-I-6dtfJS lJ:siC6S dll

3",e Vtlcepreclsar~ 1;'c/"'I;,dIJ fJ.1J",e1es I;,ffrlf;.ce Servle-l-. I4c pr""valle/~eJ1ff MUMC/lr lar: "'11\ exff'ld l'Jesh classe. 11 /1 /illiatarl"IJ. d(j ciJh'iffJr-l-o.lI\eJ1-!-IJ sel'lIle+ dl!Ji sel/ serllle-l- lIell\ daZ"'i'.

Http ervlet ttp erv et equest, ttp erv et


service(ServletRequest, ServletResponse) doGet(HttpServletRequest, HttpServletResponse) doPost(HttpServletRequest, HttpServletResponse) doHead(HttpServletRequest, HttpServletResponse) doOptions(HttpServletRequest, HttpServletResponse) doPut(HttpServletRequest, HttpServletResponse) doTrace(HttpServ letRequest, HttpServletResponse) doDelete(HttpServletRequest, HttpServletResponse) etLastModified(HttpServletRequest)

A classe HttpServlet (j avax. servlet.http .HttpServlet) (+fJ.~!J:/iIIi",~a classe ,~/e/illie'l-!-a as


fJ

-tl AlAlHu JlA.. se rl/le-!- de


4J1-h5,,;
/illih.S (JJ\h. StfJli'cl-l-h.Stl e es,eclfiCa parti.

I/rrp'

A classe MyServlet (com.wickedlysmart.foo)


lJr lI\fJ.i"tfJrta das co.rac-/-eris-!-,cas
dtfJ

se",

servle-l- -I-rfJ.-I-adfJ. pelas ~-l-i!;d(js das

s(Jperclasses. 1[;dtl ti 1Jve J\:-!-lJdIJS

e a'lvlar I/,)S

I/rrp

1J(Je

98 caplitulo4

solicitao

e resposta

Os

rrs

G-randes MotMetttos do Ciclo de Vida

(GET, POST, etc.) da baseado ele no mtodo HTTP Quando chamado estabelecer uma conexo Possivelmente. Este mtodo analisa aUM voc mtodos estar em dizendo outros Quando ele ou do chamado inicialize seu servlet para Se voc inicializao tiver cdigo (como solicitao cliente, o Ele Para pode que serve doGetO doPostO ser anulado? manualmente o mtodo Voc NO deve anular deles! (doGetO ou doPostO) comea! Este o mtodo No. Dificilmente. solicitaes do cliente. o mtodo HTTP(GET, Possibilita que voc objetos, no que aplicao esperamos anular FAA. claro, o doPostO, que porm sua antes de tratar quaisquer pode chamar outros solicitao, determina responsvel por tudo POST, respectivo etc.) e doGetO, chama Por ao tudo Container exemplo, comea daqui. que se voc este aqui que seu cdigo doPostO, etc. no servlet. ir informar ao Container Aquele que voc anular anular os mtodos doGetO e/ou doPostO e deixar serviceO. Seu trabalho SEMPRE, pelo menos, depois naOsolicitao. instncia servlet classe serv let. mtodo correto. objetos), ento anula o mtodo initO na sua que voc suporta. serviceO do HTTPServlet solicitaes HTTP POSTo se preocupe emvoc chamar o

com umno banco de dados ou registrar-se em outros servlet d suporte s que a implementao

voc est

99

servlet threads

o mtodo service() sempre chamado em sua prpria pilha...


Inicializao do Servlet Solicitao do cliente 1 Solicitao do cliente 2

Thread A
O Container chama o initO na instncia servlet depois que esta criada, mas antes que o servlet atenda alguma solicitao do cliente. Se voc tiver cdigo para inicializao (como estabelecer uma conexo com um banco de dados ou se registrar em outros objetos), ento voc anula o mtodo initO na sua classe servlet. Do contrrio, o mtodo initO do GenericServlet roda.

Thread B
Quando a primeira solicitao do cliente chega, o Container inicia (ou localiza) uma thread e induz o mtodo serviceO do servlet a ser executado. Voc normalmente NO anular o mtodo serviceO, e o mtodo do HttpServlet que rodar. O mtodo serviceO descobre qual mtodo HTTP (GET, POST, etc.) est na solicitao e chama o respectivo mtodo doGetO ou doPostO. O doGetO e o doPostO dentro do HttpServlet no fazem nada, ento voc ter que anular um ou ambos. Esta thread morre (ou colocada de volta em um pool gerenciado pelo Container) quando o serviceO finalizado.

Thread C
Quando a segunda (e todas as outras) solicitaes do cliente chegam, o Container novamente cria ou encontra uma outra thread e induz o mtodo serviceO do servlet a ser executado. Ento, a seqncia do mtodo serviceO -->doGetO ocorre cada vez que existe uma solicitao do cliente. Em um determinado momento, voc ter ao menos, tantas threads sendo executadas, quantas solicitaes de clientes houver, limitadas pelos recursos ou polticas/ configurao do Container. (Voc pode, por exemplo, ter um Container que permita especificar a quantidade mxima de threads simultneas, e quando o nmero das solicitaes do cliente ultrapass-Ia, alguns clientes tero apenas que esperar).

100 captulo 4

solicitao

e resposta

Cada solicitao roda etlt utMathread separada!


Voc talvez j tenha ouvido algum dizer coisas como: "Cada instncia do servlet...", mas isto est errado. No existem mltiplas instncias de nenhuma classe servlet, exceto para um caso especial (chamado SingleThreadModel, de natureza perversa). Porm, ainda no estamos falando desse caso especial.

o Container

roda vrias threads para processar as vrias solicitaes para um nico servlet.

E cada solicitao do cliente gera um novo par de objetos request e response .. Container
sotiCif.cro

Hn-p

Cat1a
1I1tlQ

dte~-h f'cebe
Sf!p4f'at1o.

+I.f'eaJ

pQ.f'a caJI! SlJli'ct/-af'i4 e

C4/'J+fJ1Pitf'

IJlifjCIJ.

/'J4V4$

tjff<JS sll'ct+0-j4 e

t't!sf'cs+a.

f:

f eth'untas Idl9tas
Isto est confuso ... na figura acima voc mostra dois clientes diferentes, cada um com sua prpria thread. O que acontece se o mesmo cliente fizer vrias solicitaes? uma thread por cliente ou uma thread por solicitao?

N9 ex'lst~m

f:

E se o Container usar cluster e distribuir a aplicao em mais de uma JVM?

f:

Eu notei que o HttpServlet est num pacote diferente do GenericServlet... quantos pacotes servlet existem?

1\: Imagine que a figura

1\: Uma thread

por solicitao. O Container no se importa com quem fez a solicitao - cada solicitao que chega significa uma nova thread/pilha.

acima para uma simples JVM e que cada JVM tenha a mesma figura. Ento, para uma aplicao distribuda, existiria uma instncia de um determinado servlet para cada JVM. Porm, cada JVM ainda teria apenas uma nica instncia daquele servlet.

1\: Tudo relacionado a


servlets (exceto o que se refere ao JSP) est emjavax. servtet ou em javax.servlet. http. E fcil ver a diferena ... o que se refere a HTTP est no pacote javax.servlet.http e o restante (classes genricas de servlet e interfaces) est em javax.servlet. Veremos captulos que tratam do JSP mais adiante. voc est aqui ~

101

nca/zao do Servlet

No COi\1eo: carregat1do

e it1icializat1do

nasce quando o Container encontra o arquivo de classe servlet. Isto acontece quase sempre quando o Container inicia (por exemplo, quando voc roda o Tomcat). Quando o Container inicia, ele procura por aplicaes distribudas e ento localiza os arquivos de classe servlet. (No captulo sobre Distribuio, ns entraremos em mais detalhes de como, por que e onde o Container procura os servlets.) . Encontrar a classe o primeiro passo. Carregar a classe o segundo passo. E isso acontece na inicializao do Container ou na primeira utilizao do cliente. Seu Container talvez lhe possibilite escolher qual classe carregar, ou talvez carregar a classe sempre que ele quiser. Independentemente de o seu Container preparar o servlet antes ou exatamente no momento que o cliente necessita, um mtodo serviceO do servlet no rodar at que o servlet seja inteiramente inicializado.

o servlet

Seu set'l et

sempte canegad9 e
'lnlclallzc1d 9 ANTES

de

o init() sempre

termina antes da primeira chamada ao service()

EXERCITE SUA MENTE


Por que existe um mtodo initO? Em outras palavras, por que o construtor no suficiente para inicializar um servlet? Que tipo de cdigo voc deveria colocar no mtodo initO? Dica: o mtodo initO usa um argumento de referncia ao objeto. O que voc acha que seria o argumento para o mtodo initO e como (ou por que) voc o usaria?

lJr . esh\tl CiJl'.>tA CiJ . tAresfcs+tA iJHHf.serv!e+/t.esf~PSe

tlcresceP+a . +IJJt:>s3ve serIJ lfl'ftlr+fl.PffS VSfl.'1JtlH.,-.,-? 102 eI"N;s) c(u;J.les e ~e4Jers.

se viJc es-hvel"

solicitao

e resposta

A lt1icializao do Servlet: quat1do UtM objeto

toma-se

UtM

servlet

o momento mais orgulhoso da minha vida quando o Grande Mestre Container me transforma em um servlet, criando um ServletConfig para mime chamando meu initO. At ento, eu sou apenas um mero objeto. Mas como um servlet, eu tenho privilgios especiais (alm do handshake secreto), como a capacidade de logar eventos, entregar referncias para outros recursos e armazenar atributos para outros servlets ...

Um servlet vai do no existe para inicializado (que na verdade significa pronto para servir s solicitaes dos clientes), comeando com um construtor. Mas o construtor cria apenas um objeto, no um servlet. Para ser um servlet, o objeto precisa adquirir padro de servlet. Quando um objeto toma-se um servlet, ele recebe todos os privilgios que se tm quando se um servlet, como a capacidade para usar sua referncia ServletContext para obter informaes do Container.

Porque em algum lugar entre o construtor e o mtodo initO, o servlet est no estado servlet Schroedinger*. Voc pode possuir um cdigo para inicializao do servlet, como receber informao de configurao da aplicao web, ou procurar por uma referncia em outro trecho da aplicao, que ir dar erro se voc execut-Ia muito cedo na vida do servlet. Contudo, muito simples se voc se lembrar de no colocar nada no construtor do servlet! No h nada que no possa esperar at o initO.

* Se sua parte mecnica est um pouco enferrujada, no 800gle totalmente por "Schroedinger's referimos ao estado Schroedinger,

talvez voc queira fazer uma pesquisa morto, nem

Cat" (cuidado: se voc ama animais, no a faa). Quando nos nos referimos a algo que no est nem totalmente

vivo, mas em algum lugar estranho entre ambos.

voc est

103

ServletConfig

e ServletContext

Quanto vale para voc "ser um servlet"?

o que acontece quando um servlet vai daqui:

para c?

o
No confunda os parroetros do ServletConfig coro os parroetros do ServletContextl

Um objeto ServletConfil: Um objeto ServletConfig por servlet. Use-o para passar informaes de tempo de distribuio para o servlet (um banco de dados ou a pesquisa do nome de um enterprise bean, por exemplo) que voc no queira fazer hardcode no servlet (parmetros init do servlet). Use-o para acessar o ServletContext. Os parmetros so configurados no Deployment Descriptor.

veja 'lst.

Ns realmen~e .no fal~~~o~~:f: que isso at o proxlmo capl, s fundem, vamo tantas pessoas se con ra' preste plantar uma semente ago . ateno nas diferenas. lh d Pelos nomes: Comece o . an o " nfi" Palavra co g O ServletConfig tem a N" me que lembra "configuraao . no no , d t po de Ele lida com valores ~ eO~~gurou para o . 'b' o que voce c dlStrl til I t) Aquilo que seu servlet (um por serv e . voc rvlet pode querer acessar e que se d mo o nome no quer fazer hardco e, co I dum banco de dados, por exemp NO. e I tC nfig nao armetros do Serv e o . Os P N desde que este servlet esteja mudarao, d ndo Para alter-Ios, distribudo e ro a I voc ter que redistribuir o s~rv et. O ServletContext dever-se-la I NOnos cdhamar eram AppContext (mas e es na N ) pois h somente um por ate~aoN' NO um por servlet. De aphcaao .e . ' traremos neste qualquer jeito: n.os en 'tulo _ isto s assunto no proxlmo capl um alerta.

Um ServletContext Um ServletContext por aplicao. (Eles deveriam t-Io chamado de AppContext.) Use-o para acessar parmetros da aplicao (tambm configurado no Deployment Descriptor) . Use-o como se fosse um quadro de avisos da aplicao, onde voc pode escrever mensagens (conhecidas como atributos) que as outras partes da aplicao possam acessar (mais sobre isto no prximo captulo). Use-o para obter informaes do servidor, incluindo o nome e a verso do Container e a verso da API que suportada.

104

captulo 4

solicitao e resposta

Mas a VERU AUEIRA fut1~o de

UiM

Servlet tratar solicitaes.

a que a vida do servlet faz diferena.

No captulo seguinte estudaremos o ServletConfig e o ServletContext, mas por hora, estamos vendo em detalhes a solicitao e a resposta. Porque o ServletConfig e o ServletContext existem apenas para darem suporte nica e Verdadeira Tarefa do servlet: tratar as solicitaes do cliente! Portanto, antes de vermos como os seus objetos contexto e configurao podem ajud-Io em seus trabalhos, teremos que voltar um pouco e rever os fundamentos da solicitao e resposta. Voc j sabe que a solicitao e a resposta so passadas como argumentos para o mtodo doGetO ou doPostO, mas que poderes estes objetos request e response oferecem? O que voc pode fazer com eles e por que voc se importa com isso?

Coloque o nome nos Container Web trechos em branco (as caixas vazias) da linha do tempo do ciclo de vida. (Verifique suas respostas com a linha do tempo mostrada anteriormente neste captulo.) Acrescente tambm suas prprias anotaes para facilitar a memorizao dos detalhes.

Classe Servlet

Objeto Servlet

101201

Ionel
Hil.llU00010
11)101(; o

1.'1(11) 1
101.1)101

H,lOto!O 1001010101

est

105

solicitao e resposta

Solicitaeo e Resposta: a chave para tudo, e os argutMetttos para o service(}*

G avax.servlet.

Interface ServletRequest ServletRequest) interface ServletRe uest

getAttribute(String) : Objeet getContentLengthO : int getlnputStreamO : ServletlnputStream getLoealPortO : int getParameter(String) : String getParameterNamesO : Enumeration Ii MUITOS outros mtodos ...

Interface ServletResponse servlet. ServletResponse) interface ServletReslJonse getBujJerSizeO : int setContentType(String) : void getOulputLenght(int) : void getOutputStreamO : ServletOutputStream getWriterO : PrintWriter getContentTypeO Ii MUITOS outros mtodos ...
G avax.

G avax.serv

Interface HttpServletRequest let.http.HttpServletRequest) "mtertace

Interface HttpServletResponse G avax. servlet.http .HttpServletResponse) inte ace Htt S~rvletRes onse addCookie(Coolde) : void addHeader(String name, String value) : void encodeRedireetURL(String url) : String sendError(int) : void setStatus(int) : void Ii MUITOS outros mtodos ...

.flttpS~rvletB.~qlJ~st
getContextPathO : String getCookiesO : Coolde {] getHeader(String) : String getQueryStringO : String getSessionO : HttpSession getMethodO : String Ii MUITOS outros mtodos ...

*Os objetos solicitao e resposta tambm so argumentos para os outros mtodos HttpServlet que voc escreve: doGetO, doPostO, etc. 106 capitulo 4

solicitao

e resposta

..

f f:
L \.

.N9 eXIstem

eth'Untas d1'9tlS

que voc saiba servlets no-HTTP.

~:,~"'lU$ O exame no usando espera desenvolver

Quem implementa as interfaces para o HttpServletRequest e o HttpServletResponse? So aquelas classes na API?

Voc no precisa saber como usar servlets com um protocolo que no seja HTTP No : entanto, espera-se que voc saiba como a

das classes funciona. Logo, voc As c1a~ses na? esta o na. : hierarquia TEM que saber que o HttpServletRequest API, pOISfica a cargo dos fabncantes Implementa-:e o HttpServletResponseso extenses do Ias. A boa notcia que voc no precisa se :ServletRequest e do ServletResponse, e que preocupar com isso. Apenas creia que quando : a maior parte da implementao de um O mtodo serviceO chamado em seu servlet, : HttpServlet vem, de fato, do GenericServlet. ele receber referncias para dois excelentes : Mas isso. O exame entende que voc um objetos que implementam o HttpServletRequest e : desenvolvedor HttpServlet. o HttpServletResponse. Voc jamais se preocupa : com o nome e o tipo verdadeiros da classe envolvidos nesta implementao. Tudo que interessa que voc ter alguma coisa com todas as funcionalidades do HttpServletRequest e do HttpServletResponse. Ou seja, tudo o que voc precisa conhecer so os mtodos que voc pode chamar nos objetos que o Container oferece como parte da solicitao! A verdadeira classe na qual sero implementados no faz diferena - voc se refere aos objetos request e response apenas pelo tipo da interface.

P . N~o. _. O Contalner.

f:

Eu estou lendo esta UML corretamente? Essas interfaces esto estendendo interfaces?

1\: Sim. Lembre-se,

as interfaces podem ter sua prpria rvore de herana. Quando uma interface estende uma outra interface (e tudo o que elas podem fazer - pois interfaces no implementam interfaces), significa que quem implementar uma interface deve implementar todos os mtodos definidos na interface e em suas superinterfaces. Isto quer dizer, por exemplo, que aquele que implementar o HttpServletRequest deve prover mtodos de implementao para os mtodos declarados nas interfaces HttpServletRequest e ServletRequest.

r:
1\:

Eu ainda estou confuso com o porqu de existir um GenericServlet, um ServletRequest e um ServletResponse. Se ningum est fazendo nada, exceto os servlets HTTP ... qual a inteno?

Ns no dissemos ningum. Algum, em algum lugar, no sei, est usando o modelo de tecnologia servlet sem o protocolo HTTP. Mas nunca encontramos ou soubemos da existncia desse algum.

Alm disso, o modelo servlet possui flexibilidade para atender queles que queiram us-Io com, por exemplo, o SMTP, ou talvez um protocolo proprietrio customizado. Porm, a API s oferece suporte nativo ao HTTP, que o que quase todo mundo usa.

voc est aqui ~

107

mtodos HTTP

o ~todo de solicitao
ou doFost() que rodar

HffF defit'le se o dokt()


Mac os X Machxhtml+xmi,text ptain;q=:O.8,vid Accept: textlxm

HTTP/1.J WWW.WckedJysmartcom Host: lvIac OS en-US; rv:L4) Geckof User-Agent: (Macintosh; u; PPC . . ' X Mach-O; 9 MoZIJa/5.0 png,rmageJ lpeg,lmage/gif;q~O.2//*;q=o.1 Host:www.wicked~mart.(om 20030624 NetsG 20030624 Us~r-Agent: Netscape!7.1 Mozil en-us,en;q==o.5 Accept-I..anguage: xhtml+xml.textlhtml;q~.9,text! GET Iselect/selectBeerTaste. ' Plain;q=O,B,Video/x_mn9 im Iseleet!selectBeerTaste2.do eI . POST do? color~dark&taste~malty HTTP/1.1 Accept: text/xrnl,apPlicatfon/xml,apPJicationl

Lembre-se, a solicitao do cliente sempre inclui um Mtodo HTTP especfico. Se o Mtodo HTTP for um GET, o mtodo serviceO chama o doGetO, Se for um POST, o mtodo serviceO chama o doPostO.

Voc continua mostrando


o doGetO e o doPostO como se eles fossem os nicos... mas EU SEI que existem oito mtodos no
HTTP 1.1.

bem capaz de voc no se importar com os outros mtodos HTTP, exceto o GET e o POST
Sim, existem outros Mtodos HTTP 1.1 alm do GET e POSTo Temos tambm o HEAD, TRACE, OPTIONS, PUT, DELETE e CONNECT. Todos, exceto um, tm um mtodo doXXXO na classe HttpServlet. Ou seja, alm do doGetO e doPostO, temos o doOptionsO, doHeadO, doTraceO, doPutO e doDeleteO. No existe nenhum mecanismo na servlet da API para tratar o doConnectO, ento ele no faz parte do HttpServlet. Mas, enquanto os outros Mtodos HTTP talvez sejam importantes para, digamos, um desenvolvedor web, um desenvolvedor servlet raramente usar outro alm do GET ou do POSTo Na maior parte do desenvolvimento servlet (provavelmente todo), voc usar o doGetO (para solicitaes simples) ou o doPostO (para aceitar e processar dados de formulrios), e no ter que se preocupar com os outros.

108 captulo 4

sol/citao

e re:::posta

Na verdade~ possvel que algum outro Mtodo HffP faa uma (rpida) apario no exame ...
Se voc est se preparando para o exame, deve ser capaz de reconhecer todos eles e ter pelo menos uma idia de suas funes. Mas no perca muito tempo aqui! No mundo servlet de verdade, s interessam o GET e o POSTo Para o exame, vai interessar tambm um pouquinho dos outros Mtodos HTTP.

GET

Pede para obter a coisa (recurso/arquivo) requisitada.

na URL

POST

Pede para o servidor aceitar a informao do corpo anexada na solicitao, e a entrega para aquilo que consta na URL solicitada. como um GET com mais calorias ... um GET com informao extra enviada com a solicitao. Pede apenas a parte do header daquilo que o GET vai retomar. como um GET sem corpo na resposta. Informa a URL requisitada sem, de fato, retomar a coisa. Solicita um loopback da mensagem de solicitao, para que o cliente veja o que est sendo recebido do outro lado, para teste ou troubleshooting. Diz para colocar a informao anexada (o corpo) na URL requisitada. Diz para apagar a coisa (recurso/arquivo) requisitada. na URL

HEAD

TRACE

PUT

DELETE

OPTIONS

\
\
\

Solicita uma lista dos mtodos HTTP para os quais a coisa na URL requisitada pode responder.

CONNECT Diz para conectar no caso de tunneling.

voc est

109

GETe POST

A diferet1a etttre tEr e posr

o POST

tem um corpo. Essa a dica. Ambos podem enviar parmetros, mas com o GET, o parmetro
fJr VE'I"S4I:J d6 I:JS

limitado ao que voc pode colocar na linha de Solicitao.

O bl1-cd

O CQbli;'t."

fQI"tJ.

<[J

bl

tlill'la SIJli'ci1-aglJ bt;

ifrrp ~ fJr li;,l.a de ~

I"fCtlI"S6 ~
GET

#1':> ... S.fl"Vld. C.I".. ~ S4':>a#1E'xad.:>S ~ fJJe.L 1.4 ."'" I"fSili'Si1-adtJ. /select/;electBeerTaste.dO?C~:;-

I',r"',ir (S'

";".J

HTTP/

S ""'+ '"
':>iCI tJ.tJ.4\]

Host: www.wickedlysmart.com . en-US; rv:l.4 Gecko/20030624 Netscape/7.1 User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; html;q=0.9,text/plain;q=O.8,video/x-mng,image/png,image/ Accept: text/xml,application/xml,application/xhtml+xml,text/

Ost.etJ.dE'~Sda /
Shc/~actJ. J

AJAJHfJ

cal'fIJ Connection: keep-alive

",.Accept-Language: jpeg,image/gif;q=O.2,*/*;q=O.1 en-us,en;q=0.5

Accept-Charset: Keep-Alive: 300 ISO-8859-1,utf-8;q=0.7,*;q=O.7 Accept-Encoding: gzip,deilate

I'f'f#1tJ.StJ. i"PIIIJI'ill'ltJ.f4iJ ~ dIJ

..JIJllci-rajtl;)-r

~ ~:;,~a d': ~

'"..POST

/ advisor /selectBeerTaste. do HTTP/1. 1 ~ Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X

Os t.eo.del"S JII. S<tJh(;/~tJ.4(j.

Mach-O; en-US; rv:l.4) Gecko/20030624 Netscape/7.1 Accept: text/xml,application/xml,application/ xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/xmng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deilate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive beS1-a VE']; 6S fal"~f!1-I""S

O C61"f6 dO.ill'lel1s~e~
tl;ljVill'lIi.S vf}es Ct.li.bI!i.J de ffJ.j'(JfJ.J.

[. color=dark&taste=malty

eSha a~l/l ebl!laix6 116 e fI:J1" i'SS6 #144 eSh6 liill'li~4daS; C(JbllJeS1-al"l4b1 se l/s:ssf!blas (j bre 1-tvssebls ca';f~:-

I(ls 11{(1t"PIt.tI; de

110 capiitulo 4

solicitao

e resposta

o tl

No, no se trata s do tatManho


Ns falamos de outros problemas do GET no captulo U1l1, lembra? Quando voc usa o GET, os dados do parmetro aparecem na barra de endereos do browser, logo aps a URL (e separados por um "1"). Imagine uma situao em que voc no quisesse que os parmetros fossem exibidos.

Ento, segurana pode ser outro problema. Outro problema poderia ser se voc precisasse ou quisesse que os visitantes fizessem um bookmark da pgina. As solicitaes GET aceitam bookmark; j as POST, no. Talvez seja realmente importante que sua pgina, digamos, permita aos usurios especificar critrios de busca. Os usurios podem querer retomar uma semana depois e fazer a mesma busca novamente, quando existiro novos dados no servidor. Mas alm de tamanho, segurana e bookmark, existe outra diferena crucial entre o GET e o POST: a maneira como devem ser usados. O GET deve ser usado para obter coisas. Ponto. Simplesmente receber. Claro, voc deve usar os parmetros para ajudar a descobrir o que enviar de volta, mas a questo : voc no est fazendo nenhuma mudana no servidor! O POST deve ser usado para enviar dados para serem processados. Isto pode ser to simples como pesquisar parmetros usados para descobrir o que ser enviado de volta, assim como no GET. Mas quando voc pensa em POST, voc pensa em atualizao. Voc pensa: usar os dados do corpo do POST para mudar alguma coisa no servidor. E isso traz um outro problema ... se a solicitao idempotente. Se no for, voc pode estar diante de um problema que aquele pequeno comprimido azul no resolver. Se voc no est familiarizado com a maneira com que o termo "idempotente" usado no mundo web, continue lendo ...

voc est

111

a solicitao no-dempendente

A histria da solicitao . o-idetMpotettte


Diane tem uma necessidade. Ela est tentando desesperadamente comprar o "Use a Cabea Tric" na livraria on-line Wickedly Smart que, sem que ela saiba, ainda est na fase de testes. Ela tem pouco dinheiro - apenas o suficiente para comprar um livro. Ela pensou em comprar direto do Amazon ou do Q'Reilly.com, mas decidiu que queria uma cpia autografada, disponvel apenas no Wickedly Smart. Deciso que ela futuramente viria a se arrepender ...

Diane c1ica em CHECKOUT. (Ela j havia enviado os dados de sua conta corrente.)

o browser envia uma solicitao HTTP para o servidor com as informaes da compra do livro e o nmero da ID da cliente.

o Container envia a solicitao para o servlet Checkout para processamento.

o servlet faz um dbito eletrnico da conta bancria da Diane.


dbito

eo

servlet atualiza o banco de dados (tira o livro do estoque, cria um novo pedido de entrega, etc.). atualiza

Servidor remoto da conta bancria

O ~ervlet NAO envia uma respos' bvia, Diane v a mesma pgina do carrinho de compras e pensa ...

o browser envia uma solicitao HTTP para o s.ervidor com as informaes da compra do livro e o nmero da ID da cliente.

112 captlJ.lo4

solicitao

e esposta

Nossa histria eottlit1ua...

o Container envia a solicitao


para o servlet Checkout para processamento.

o servlet no quer saber se


Diane est comprando o mesmo livro novamente

o
Servidor/Container da Wickedly Smart
C;

oo

servlet faz um dbito eletrnico da conta bancria da Diane, pela segunda vez. dbito

oo

banco de Diane aceita o dbito, mas cobra uma tarifa por ultrapassar seu limit

Servidor remoto da conta bancria Servidor remoto da conta bancria

Por fim, Diane acessa a pgina de Verificar Status do Pedido e percebe que tem DOIS pedidos para o livro de tric ...

est

113

HTTP mtodos

Quais dos mtodos HTTP voc acha que so (ou deveriam ser) idempotentes? (Baseado em seu prvio entendimento da palavra e/ou na histria da compra duplicada de Diane que voc acabou de ler.) As respostas esto no final desta pgina. DGET DpOST DpUT DHEAD (Deixamos o CONNECT de fora de propsito, visto que ele no faz parte do HttpServlet.)

EXERCITE SUA MENTE


o que houve
de errado com a transao da Diane? (E no foi apenas UMA coisa ... provavelmente, o desenvolvedor ter que consertar diversos problemas.)

Quais seriam algumas formas do desenvolvedor reduzir riscos como esse? (Dica: talvez elas no sejam todas solues de programao.)

qGAGI~IT) O h02.1 Url0 ~ Com:l~qGwqo ~qGmbo~Gu~GbG1IT G2bGqgcITcrlO H.1.1h 1"1" drrG AOC~h022V G2CIGAGI rrm mQ~oqo qOOG~O urlo-~qGmbo~Gu~G 20S~UJIO(mIT2 Url0 V G2bGc~l!cITCrlO H.1.1h I I qGC1ITW OE.1' HEVD G hD.1 como ~qGmbO~GU~G2' IT~uqIT 114

capitulo 4

solicitao

e re~,post8

Ser idem potente

BOM.

Significa que voc

pode fazer a mesma coisa repetidamente, sem os indesejveis efeitos colaterais!

Idempotente

_~e::;:~>

Cliente

lf~... O servlet ~nyia de volta uma resposta /servlet .;::,.. com uma pagma gerada em HTML

NO Idempotente

O servlet usa os dados do POST para atualizar o banco de dados.

voc est

115

conseguir coisas e no deve mudar nada no servidor. Ento um GET , por definio (e de acordo com a especificao HTTP), idempotente. Ele pode ser executado mais de uma vez, sem causar qualquer efeito colateral danoso. O POST no idempotente. Os dados submetidos no corpo de um POST podem ser destinados a uma transao que no pode ser desfeita. Portanto, tenha cuidado com a funcionalidade do seu doPostO! GET idem potente. O POST, no. Cabe a voc ter certeza de que a lgica da sua aplicao pode lidar com casos como o de Diane, em que o POST aparece mais de uma vez

o posr no idetltpotente o HTTP GET usado apenas para

o GET sempre
considerado idempotente no

HTTP1.l ...
voc encontre cdigos ...mesmo que m parmetroS GET . , Ou no exa me que use laterals .Feitos co . que causem eJ:idem atente de acordo seja, o GET ~ : HTTP. Mas com a especijica ssa impedi-Ia no existe nada que p~ todo doGet() de- implementartumno~:u servlet. A 'd mpoten e nao-l e _ GET dos clientes deve solicitaao . da ue a SUA ser idempo~ente, a:Fadosq cause um efeito manipulaao dos re em mente a negativo. Tenha sem? d HTTP GET e O di.(. ren a entre o meto o IJ; do Ge t')do seu servlet. metodo J

N~""4: "

1!

I.

/"4 V4ri"aS (U:fpUM!.S 1'41"4 ti p41IJ.Vr4 " ,J

"

,."

liifll!lpfrh"ff

AJs t.sh."'tJS

tlslJ."JtJ-a

IItJl-I-o.J4 paro. I) Hr.,-p! serllle-l- ptJ.ra #';6S Jel,~tr &tlt. IJ. "'es""a s6Ilcl-l-tl{" p6Je ser

lel-l-a titlas vejes) se", "e"l.tI",a C6"S~;';~d4 "e<:a-l-lvfJ. parfJ. fi () servliifJr. AJ~s *"tl6 tlSIJ."'tJS IIV Mell!lptJff"ff p4rIJ. til;er ~tle a ",es",a StJllct-l-IJ.ftl6sell!lpre re-l-,u'J1fJ.fJ.-'\eSIM resp6s-l-a e AJJ,( p4rtl '-3er !tlf tI-'\4 s6li'cl-l-aftl6 AJi.AJHuJ,( eler-l-6 c6laffr4/.
"tliJI

ff'"

116

solicitao

e res:posta

o que detenMit1a se o browser ettviar utMa


solicitao tEr ou POSr?

<A HREF= http://www.wickedlysmart.com/index.html/ >click here</A>

POST

<form method="POST" action="SelectBeer.do"> Select beer characteristics<p> <select name="color" size="l"> <option>light <option>amber <option>brown <option>dark </select> <center> ~ <input type="SUBMIT"> </center> </ form>

Se

!lc J)ISSlf

eXf1i'cl-/-4it1el1-1-e t!11.f.<"J) ele seI': PfJSr

itle+-t.t.ld"'PfJSr; ClIl'iaSaitlewh:J

i:. 1 "" 12 1/ 6S UflltJ.l1dDD lISl/M't6 c/lctJ.116bC+l'AtJ Sth;;MI-r; "" _, ~ J J '" _ J_ flJ.l'l'Al/1\f["'f'"1'6S SfJ.(), e'I1Vtl1t&llr6S 1 1'16C61'f6 &llrfJ. StUlCI-r"fJ.CfJ.iJ J
p{)Sr:AJes-k: exeitlf/t.l; tofJ. sitlel?-k: lIit1ftl.I'~e+NJ; Ct.ftitlfJ.dt'JCt.lll!il' e lIa!(J1" ti. <(Jrfl61?> l'eleN!I?-I-e , 1 ti C61' da cel"v~tI. ~lIe c l/SlIal"lt:. se!ecI6I?tJl/ (c!fJ.I'fJ.; ... fJ.l/1\bfJ.l'; itll1ll'l'()Wi 4V escl/I'a).

o que acot1tece
?I

Yf!s-/-a vej) I1tU'J t.a I1el?t.VII11I1e+t,(),d = <form action="SelectBeer.do"> Select beer characteristics<p>
<select name="colorH size="l">

se voc NO disser tMethod=~~POSr~~ t10seu <foYiM>?


""I

IIp
os-r

1/ 41l'1l

<option>light <option>amber <option>b:r;own <option>dark </select> <center> <input type="SUBMIT"> ~ </center> </form>

!JrtfJlf!Jr; DN VSV:1'16

., 3l/e (wm-k:ce
cli'Co. lIWi

C.,1I1 "S f(J,I'~e+-1'6S

3l/4I?d"

114lJ flJS SlIl

I1lJ 96htJ 11 sv$K4.I-r;1/ lI1e+t.6d= PfJS-r

se

lJ

1(JI'II1V':l'i6

voc est aqui

!o'

117

formulrios

e HTTP

o vosr

NO

O padro!

Se voc no colocar method="POST" no seu formulrio, o padro ser uma solicitao HTTP GET. Isso quer dizer que o browser envia os parmetros no header da solicitao, mas este o menor dos seus problemas. Em virtude de a solicitao chegar como GET, significa que voc estar com um problemo no momento da execuo, se voc tiver no seu servlet apenas um doPostO e no um doGetO'

Se voc fizer isto:

<form

no
IJeP1t.VII1 1I1e+t.fJtJ=rOsr

/
P1fJfef'lI1vllJ.l"to

Il rrrllA.L

action="SelectBeer.do">

E depois isto:
public class BeerSelect extends HttpServlet {

public

void

doPost(HttpServletRequest

request, HttpServletResponse response) throws IOException, ServletException

Ii

code here

Voc ter isto:


ERRO! Se o seu formulrio HTML usa GET em vez de POST, voc TEM que ter o doGetO na sua classe servlet. O mtodo-padro para formulrios GET.
I

r:

E se eu quiser suportar tanto GET como POST em um nico servlet?

I\:

Os desenvolvedores que querem dar suporte a ambos os mtodos geralmente colocam a lgica no doGetO, e fazem com que a implementao doPostO delegue poderes quela doGetO:
doPost() method delegate to the doGet() method if necessary. public void doPost( ... ) throws ... { doGet(request, response);

118 captulo 4

solicitao

e resposta

Etwiattdo e utilizattdo

UtMttieo partMetro

Formulrio HTML
<form method="POST" beer action="SelectBeer.do">

Select <select

characteristics<p> size="l">

name="color"

<option>amber <option>brown <option>dark <option>light </select> <center> ~

o 6r()wser

el'llll"ar:

1I11\D. tleS.f.D.S 1JlIfI..f.r6 6.Pces 1'10.

./ ,., S6IiCiT"lJ.jfJ.();D.SS()CI'"4tla C611\ 6 I'I()lI\e


eXell1lj>16;"C()IM' D.1I\6erll

U c616r IJ" nu' D

<input type="SUBMIT"> </center> </form>

Solicitao HTTP POST


POST /advisor/SelectBeer.do HTTP/l.l Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:l.4) Gecko/20030624 Netscape/7.1 Accept: text/xml,application/xml,application/xhtml+xml,text/htm1;q=O.9,text/ plain;q=O.8,video/x-mng, image/png, image/jpeg, image/gif ;q=O.2,*/*;q=O.1 Accept-Language: en-us,en;q=O.5 Accept-Encoding: gzip,deilate Accept-Charset: ISO-8859-1,utf-8;q~O.7,*;q~O.7 Keep-Alive: 300 Connection: keep-alive

L.eIil'l6re-se; "'"
Eor=~

() 6r()wser

311e5eNJ. es.f.fJ. s6Ite,..f.fJ.{;()~ , I t'1I\ cri't;.-IfJ..J IiI'IfJ.S e

V6Ce 1'146 frects4

se fN!lJclIffJ.r

O,ss"iJ\ SlIe elfJ.se fD.rece 311fMUi6lIelil'l

"4

ser'lti:((Jr

Classe servlet
public void doPost(HttpServletRequest request, HttpServletResponse throws IOException, response) ServletException

String //

colorParam mais cdigos

= request.getParameter(~color"); esclarecedores aqui... ~

Is.f.6

c6,-"cti:(e C61i1'1 ()

I'I()lI\e /'I() flJrll\lIlfJ.rii~

voc est aqui"

119

formulrios parmetros

Et1Viat1do e usat1do dois par'ltetros

Formulrio HTML
<form method~"POST" beer action~"SelectBeerTaste.do">

Select COLOR: <select

characteristics<p>

name=Ucolor"

size=fTl">

<option>light <option>amber <option>brown <option>dark </select> BODY: <select name="body" size="l">

<option>medium <option>light <option>heavy </select> <center> <input </center> </form>

:n"owst.r

'"

e'1VU~l'a "",a es-rfJ.S -r1'!f!S tJP5tiff.S

/I

Ir. i. J.... . '14 Sf:;lict..fajfJ.iJ) fJ.SSf:;cta(J, CO'" J f:; ii'1@"'t

N b@~;

type="SUBMIT">

Solicitao HTTP POST


POST ladvisorlSelectBeerTaste.do HTTP/l.l Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:l.4) Gecko/20030624 Netscape/7.1 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,textl plain;q=0.8,video/x-mng, image/png, image/jpeg,image/gif ;q=0.2,*I*;q~0.1 Accept-Language: eD~us,en;q=0.5 Accept-Encoding: gzip,defiate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive

Classe servlet
public void doPost(HttpServletRequest request, HttpServletResponse throws IOException, response) ServletException

String colorParam ~ request.getParameter{~color"); String bodyParam ~ request.getParameter(~body"); mais cdigo aqui

II

f}J.u'~: 1IfJ.l't';'vei
fJ.I'J::

ea

S..ft~t'15

h",

f) 110./01'

120

solicitao e resposta

Voc pode ter vrios valores para um nico parmetro! Isto significa que voc precisar que o getParameterValues() retorne um array, e no um getParameter() que retorne uma String.

Veja lst9!
Alguns tipos de entrada de dados, como um grupo de checkboxes, podem ter mais de um valor. Isso quer dizer que um nico parmetro ("tamanhos", por exemplo) ter diversos valores, dependendo de quantos boxes o usurio assinalou. Um fonnulrio em que o usurio possa selecionar diversos tamanhos de cerveja (indicando que ele est interessado em TODOS aqueles tamanhos) ser algo como:
<forrn rnethod=POST action="SelectBeer.do"> Seleet beer characteristics<p> Can Sizes: <p> <input type=checkbox name=sizes <input type=checkbox name=sizes <input type=checkbox name=sizes <br><br> <center> <input type="SUBMIT"> </center> </form>

value="12oz"> va1ue="16oz"> value="22oz">

12 oZ.<br> 16 oZ.<br> 22 oZ.<br>

No seu cdigo, voc usar o mtodo getParameterValuesO


String String one = request.getParameterValues(~sizes") [] sizes

que retoma um array:


[O];

= request.getParameterValues(~sizes");

Se voc quiser ver tudo no array, s por diverso ou teste, pode usar:
String [] sizes = request.getParameterValues(~sizes"); for(int x=O; x < sizes.length ; x++) { out.println(~<br>sizes: ~ + sizes[x);

(Considere que "out" um PrintWriter que voc obteve da resposta)

Voc

est aqui"

121

o objeto l-fttpSe!VletRequest

Alltt dos parlttetros,

O que Ittais eu pOSSO

obter de Ultt objeto Reques11


As interfaces ServletRequest e HttpServletRequest possuem uma tonelada de mtodos que voc pode chamar, mas voc no precisa memorizar todos eles. Sozinho, voc realmente deveria ver todas a API para javax.servlet.ServletRequest e javax.servlet.http.HttpServletRequest, mas aqui ns s veremos os mtodos que voc mais usar no seu trabalho (e que podem tambm aparecer no exame). No mundo real, voc estar com sorte (ou sem sorte, dependendo de sua perspectiva), se usar mais de 15% da API de solicitao. No se preocupe se no ficou claro para voc como ou por que voc usaria cada uma delas; ns veremos mais detalhes de algumas delas (principalmente os cookies) mais adiante.

Interface ServletRequest Gavax.servlet. ServletRequest) <. <.mterjace>> getAttribute(String) getContentLengthQ getInputStreamQ getLocalPortQ getRemotePortQ getServerPortQ getP arameter(String) getP arameter Values(String) getParameterNamesQ Ii MUITOS outros mtodos ...

A plataforma do cliente e a informao do browser


String client request.getHeader(~User-Agent");

Os cookies associados a esta solicitao


Cookie[] cookies request.getCookies();

Interface HttpServletRequest Gavax. servlet.http.HttpServ letRequest)


<: <:Tnterjace>>

..

HTTPServletReauest

A sesso associada a este cliente


HttpSession session request.getSession();

O Mtodo HTTP da solicitao


String theMethod

request.getMethod()

getContextPathQ getCookiesQ getH eader(String) getlntHeader(String) getMethodQ getQueryStringQ getSessionQ Ii MUITOS outros mtodos ...

Um stream de dados da solicitao


InputStream input request.getlnputStream();

122 captuo 4

solicitao

e res:posta

N9 exlst~m

Yetbuntas Idl9tas

r:
I\:

Por que algum dia eu iria querer obter uma InputStream da solicitao?

Com uma solicitao GET, no h nada alm da informao header da solicitao. Em outras palavras, no h corpo com que se preocupar. MAS ... com um HTIP POST, h informao de corpo. Na maioria das vezes, tudo o que interessa em relao ao corpo retirar os valores dos parmetros (por exemplo, "color=dark") usando o request.getParameterO, mas esses valores podem ser enormes. Se voc quer analisar a fundo tudo o que chega com a solicitao, voc pode usar o mtodo getlnputStreamO. Com ele voc pode, por exemplo, destrinchar todas as informaes do header e processar byte a byte o payload (o corpo) da solicitao, copiando imediatamente para um arquivo no servidor, talvez.

r:

Qual a diferena entre getHeaderO e get/ntHeaderO? Pelo que eu posso dizer, headers so sempre Strings! At mesmo o mtodo getlntHeaderO leva uma String representando o nome do header; ento, para que serve o int?

I\:

Os headers tm um nome (como "User-Agent" ou "Host") e um valor (como "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.4) Gecko/20030624 Netscapel7.1" ou .. www.wickedlysmart.com ..). Os valores retomados dos headers esto sempre no formato String, mas para alguns casos, a String representa um nmero. O header "Content-Length" retoma o nmero de bytes que compe o corpo da mensagem. O header HTIP "Max-Forwards", por exemplo, retoma um valor inteiro, indicando quantos hops (saltos de roteadores) a solicitao pode fazer. (Voc pode querer usar este header se estiver tentando fazer um trace da solicitao, que voc suspeite estar presa em um loop em algum lugar.)

Voc pode obter o valor do header "Max-Forwards"


string forwards int forwardsNum

usando o getReaderO:

request.getHeader(~Max-Forwards"); = Integer.parselnt(forwards);

E isso funciona perfeitamente. Mas se voc soubera valor que o header deve assumir como int, voc pode usar o getlntHeaderO como um mtodo de convenincia para poup-Io da etapa de converso da String para int:
int forwardsNum = request.getIntHeader(~Max-Forwards");

getServerPortO,

getLocalPortO

e getRemotePortO

so confusos!

deveria ser autoexplicativo ... at que voc se perguntasse para que serve ento o getLocalPortQ. Vamos comear pelo mais fcil.~ . getRemotePortQ. Primeiro v~ce vaz ?" perguntar "remoto em relaao a quem ... Neste caso, j que o servidor q~em so!zczta, remoto o CLIENTE. O cliente e remoto na . - do servzdor. Logo getRemotePortQ vzsao ".,,' significa "obter a porta do cltente . Ou se~a, o nmero da porta do cliente de ~nde partm a solicitao. Lembre-se: se voce for um servlet, remoto significa cliente.

o getServerPortQ

A diferena entre getLocalP~rtQ e getServerPortQ mais sutzl: o getServerPortQ diz "para qual porta a " solicitao foi inicialmente ENVIADA? , enquanto que o getLocalPortQ diz "em qual RAR?" S tem porta a solicitao FOI PA ., ~n:, _ uma diferena, porque emb?r.a as so!zcztaoes sejam enviadas para uma umca porta (a qual o servidor est escutando), o servzdor encontra uma porta local diferente para cada thread, para que a aplicao possa atender a vrios clientes ao mesmo tempo.

reviso do cicio da vida

Reviso: Cielo da vida do servlet e API

Container inicializa um servlet carregando a classe, invocando o construtor-padro do servlet e chamando o mtodo initO do servlet. initO (que o desenvolvedor pode anular) chamado apenas uma vez no ciclo de vida do servlet, e sempre antes do servlet atender a qualquer solicitao do cliente.

inter ace avax.servlet.Servlet service(ServletRequest, ServletResponse) init(ServletConfig) destroyO getServletConfigO getServletInfoO

o mtodo

j avax.servlet.GenericServlet
service(ServletRequest, ServletResponse) init(ServletConfig) initO destroyO getServletConfigO getServletInfoO getInitParameter(String) getInitParameterN amesO getServ letContextO log(String) log(String, Throwable)
.~.

o mtodo

initO d ao servlet acesso para os objetos ServletConfig e ServletContext, que o servlet precisa para conseguir informaes sobre a configurao do servlet e a aplicao web.

o Container o servlet

termina com a vida de um servlet chamando seu mtodo destroyO. passa a maior parte da sua vida rodando um mtodo serviceO para uma solicitao do cliente. Cada solicitao para um servlet roda em uma thread separada! S existe apenas uma instncia para qualquer classe servlet. Seu servlet quase sempre estender o javax. servlet.http.HttpServlet, do qual ele herda uma implementao do mtodo serviceO, que traz um HttpServletRequest e um HttpServletResponse.

I
j avax.servlet.http.HttpServlet
service(HttpServletRequest, service(ServletRequest, HttpServletResponse) ServletResponse) doGet(HttpServ IetRequest, H ttpServ IetResponse) doPost(HttpServletRequest, doHead(HttpServletRequest, doOptions(HttpServletRequest, doPut(HttpServletRequest, doTrace(HttpServletRequest, HttpServletResponse) HttpServletResponse) HttpServletResponse)

HttpServletResponse)

doDelete(HttpServletRequest,

o HttpServlet estende o javax.servlet.GenericServlet - uma classe abstrata que implementa a maioria dos mtodos bsicos do servlet. o GenericServlet
implementa a interface Servlet.

getLastModified(HttpServletRequest)

As classes servlet (exceto aquelas relacionadas aos JSPs) esto em um dos dois pacotes: javax. servlet ou javax.servlet.http. Voc pode anular o mtodo initO e deve anular pelo menos um mtodo de servio (doGetO, doPostO, etc).

com.wickedlysmart.examples.MyServlet doPost(HttpServletRequest, HttpServletResponse) myBizMethodO

HttpServletResponse) HttpServletResponse)

124

capitulo 4

solicitao

e re::;posta

Reviso: HffF e HttpServletRequest

Pontos de bala

Os mtodos doGetO e doPostO do HttpServlet levam um HttpServletRequest e um HttpServletResponse. O mtodo serviceO determina se o doGetO ou o doPostO rodar, baseado no mtodo HTTP (GET, POST, etc.) da solicitao HTTP. As solicitaes POST tm um corpo; as solicitaes GET, no, mas as solicitaes GET podem ter parmetros anexados VRL da solicitao (algumas vezes chamada "query string"). As solicitaes GET so idempotentes por herana (de acordo com a especificao HTTP). Elas devem ser capazes de rodar vrias vezes, sem causar nenhum efeito colateral no servidor. As solicitaes GET no devem mudar nada no servidor. Mas voc pode escrever um mtodo doGetO no-idempotente e maldoso. . O POST no-idempotente por herana e cabe a voc projetar e codificar sua aplicao, de forma que, se o cliente enviar uma solicitao duas vezes por engano, voc possa cuidar disso. Se um formulrio HTML no diz explicitamente "method=POST", a solicitao enviada como um GET e no como POSTo Se voc no possui um doGetO em seu servlet, a solicitao falhar. Voc pode receber parmetros da solicitao com o mtodo getParameter("paramname"). O resultado sempre uma String. Se voc tem mltiplos valores de parmetros para um determinado parmetro, use o mtodo getParameterValues ("paramnane") que retoma um array de Strings. Voc pode obter outras coisas do objeto solicitao, como headers, cookies, uma sesso, a query string e um stream de dados.

Interface ServletRequest
Uavax.servlet. ServletRequest)

<<interfaee> > ServletReaesL getAttribute(String)

IgetContentLengthO
getInputStreamO getLoealPortO getRemotePortO getServerPortO getParameter(String) getParameter Values(String) getParameterNamesO MUITOS outros mtodos ...

Ii

Interface HttpServletRequest Gavax.servlet.http. HttpServletRequest)

t
I

<<interfaee> > HTTPServletReauest getContextPathO getCookiesO getHeader(String) getIntHeader(String) getMethodO getQueryStringO getSessionO MUITOS outros mtodos ...

Ii

voc est

125

o objeto HttpServletResponse

Etrl'o,essa foi a Solicitao ... vejatMos agora a Resposta


A resposta o que volta para o cliente. Aquilo que o browser recebe, analisa e retribui ao usurio. Tipicamente, voc usa o objeto response para conseguir um stream de sada (geralmente um Writer), e voc usa este stream para escrever o HTML (ou outro tipo de contedo) que retoma para o cliente. Contudo, o objeto response tem outros mtodos alm do IIO output. Veremos alguns deles com mais detalhes.

yoce usa a apenas pata envIal- dad9s de volta 9 Voc chama resp9sta: setConte.nf7jpei) e
gef\VdtetD.

interface ServletResponse Gavax.servlet. ServletResponse) <<interface> > ServletResonse etBuiferSizeO setContentTypeO


---_

..

_----------------.-.-----.-----_.--------.-----

. __ ... _

.....

__

.... _.,

l/I#itJ.ts

etWriterO ~etoutputStreamo etContentLengthO 'IMUITOS outros mtodos ...

DepoIS dIss9>v9c estadt ttZendo sImplesmente pata escl"evet o alg9 mms) no ]\tlas \9c tamlJm pode a resposta pm-a outt9sheadets. ettOS

addCookieO addHeaderO encodeURLO sendErrorO setStatusO sendRedirectO 'IMUITOS outros mtodos ...

126

capitulo 4

solicitao

e resposta

Espere um momento ... Eu pensei que no amos enviar HTML de um servlet, porque horrvel format10 para o stream de sada ...

Usando a resposta para o I/O


Tudo bem, deveramos estar usando JSPs em vez de enviar HTML de volta no stream de sada a partir de um servlet. Formatar um HTML para enfi-Io no mtodo prntlnO do stream de sada penoso. Mas isso no significa que voc nunca ter que trabalhar com um stream de sada do seu servlet Por que? 1) Seu provedor de hospedagem pode no suportar JSPs. Existem vrios servidores e containers mais antigos por a que suportam servlets, mas no JSPs, ento, voc fica "preso". Voc no tem a opo de usar JSPs por algum outro motivo, como um gerente chato que no permite usar JSPs porque em 1998 seu cunhado lhe dissera que os JSPs eram ruins. Quem disse que HTML era a nica coisa que voc poderia enviar de volta em uma resposta? Voc pode devolver outras coisas em vez de HTML ao cliente. Algo para o qual um stream de sada faa sentido.

2)

3)

voc est aqui"

127

enviando bytes na resposta

ItMagit1eque voc queira mviar UtMJAR para o cliet1te...


Digamos que voc tenha criado uma pgina para downloads onde o cliente pode baixar cdigos a partir de arquivos JAR. Em vez de enviar de volta uma pgina HTML, a resposta contm os bytes representando o JAR. Voc l os bytes dos arquivos JAR e os escreve no stream de sada dos dados da resposta.

Diane est desesperada para fazer o download do J AR com um cdigo do livro que ela est usando para aprender servlets e JSPs. Ela acessa o site do livro e c1ica no link "cdigo jar", que se refere a um servlet chamado "Code.do".

envia uma solicitao HTTP para o servidor com o nome do servlet requisitado ("Code.do").

o browser

o Container envia a solicitao para o servlet CodeReturn (mapeado para o nome "Code.do" no DD) para processamento.

o J AR inicia

o download na mquina do cliente. Diane est satisfeita.

o servlet os bytes resposta os bytes


A resposta HTTP contm agora oS bytes que representam o J AR.

CodeReturn recebe para o J AR, recebe da um stream de sada e copia representando o J AR

resposta

128 captulo 4

solicitao

e resposta

o cdigo servlet
Ii
um monte public class

que faz o dowt1load do JAR


aqui

de imports

CodeReturn

extends

HttpServlet

public

void

doGet(HttpServletRequest

request, throws

HttpServletResponse IOException,

response)

ServletException

~
response. setContentType ("application/jarU)
;

IJ:S 3Vfl'fll>\aS ~ve a/l'tJwsel' I'fccl'Jt.e5Q 3Vf is+o e ClII>\

IA;e'" Ji..-r;!ilAJ JN Vf"(, J I114Q ClII>\ rr 1Vl.l-; '" 1'J-ra<1l;


Ct:Jl'Jft'iClNI.JMSti +ib{J Je C<1lI'J#tJJe. pP.N. ~F QppltcU.-hl1{jal'

ServletContext InputStream is

ctx = getServletContext();

r, n

ctx.getResourceAsStream("/bookCode.jarU);

It. ~
int read = O; byte[] bytes = new byte[1024];

.s..S+e. .lI'; apfl'JlJ.S FI Je-lI>\e VII>\

-r'

s+reall>\ Je el'J+l'aJIJ. pQrlJ.

(J

I'f!CClI'S ct.all>\aJa bQ/<:CI,lJe,jO:I'


OutputStream os = response.getoutputstream();)

os.write(bytes, = while read os. flush(); os. close ();

is. read 0, read); (bytes !=


a PfAl'#
S4~el1#

-1)

,J >
bj#s

1.s+a

fVI1Jfi.lI>\e~aIJ

1I>\4S apel1t1.s ClII>\

xl

tJ S{"II>IpI<!s!

I
tJ

lJaJa espectal)

l tiS

J JI}Je

e 4S escreve

PfU'Q

s+l'efi.J'l, de sa;Ju. ~(le l1:s Cl'Jse.5V{"'II1tlS de tJtje.+tl resps+a.

No ex'lst~m

f:

YerguntLls Idl9tlS

Onde estava localizado o arquivo JAR "bookCode.jar"? Em outras palavras, onde o mtodo getResourceAsStreamO PROCURA para localizar o arquivo? Como voc lida com o caminho?

I\:

O getResourceAsStreamO requer que voc inicie com uma barra ("t'), que representa a raiz da sua aplicao. J que a aplicao foi chamada de JarDownload, ento a estrutura de diretrios semelhante figura. O diretrio JarDownload est dentro de webapps (o diretrio-pai para todos os outros diretrios da aplicao), e dentro do JarDownload ns colocamos o WEB-INF e o cdigo JAR em si. Assim, o arquivo "bookCode.jar" est situado no nvel raiz da aplicao JarDownload. (No se preocupe, ns entraremos em maiores detalhes sobre a estrutura de diretrios de distribuio quando chegarmos no captulo que trata da distribuio.)

web.xml

voc est

129

tipo de contedo

Opa. Qual

problettta COttto tipo do cot1tedo?


;

Voc deve estar surpreso com esta linha:


response.setContentType(~application/jar")

Ou pelo menos deveria. Voc tem que dizer ao browser o que voc est devolvendo, para que ele possajazer a coisa certa: abrir uma aplicao "assistente", como um leitor PDF ou um player de vdeo, criar um HTML, salvar os bytes da resposta como um arquivo de download, etc. E j que voc est a se perguntando, sim, quando ns dizemos tipo do contedo, queremos dizer a mesma coisa que tipo MIME. O tipo do contedo um header HTTP que deve ser includo na resposta HTTP.

Caramba, obrigado Servidor. gentil de sua parte me informar que tipo voc est enviando de volta. Voudeixar o Quicktime player pronto para o vdeo...

D o

Tipos MIME comuns:


text/html application/pdj video/quicktime application/java image/jpeg application/jar appl ication/octet-stream application/x-zip

Servidor/ Container

Voc no precisa memorizar um monte de tipos do contedo. o Voc deve saber o que o setContentTypeO jaz e como us-lo, mas voc no precisa saber nem mesmo os mais comuns tipos de contedo, exceto o text/html. O que voc precisa saber sobre o setContentTypeO geralmente de senso comum ... por exemplo, no ser bom para voc mudar o tipo de contedo DEPOIS de ter escrito o que vai para o stream de sada da resposta. bvio. Isso quer dizer que voc no pode configurar um tipo de contedo, escrever algo e, em seguida, mudar o tipo de contedo e escrever outra coisa. Pense um pouco: como o browser lida com isso? Ele s pode tratar um tipo de COISA da resposta de cada vez.
o

.laxe

Para ter certeza de que tudo junciona bem, o que voc deveria jazer (e em alguns casos um requisito) sempre chamar o setContentTypeO primeiro, ANTES de chamar o mtodo que gera o stream de sada (getWriterO ou getOutputStreamO). Isto garantir que voc no ter conflitos entre o tipo de contedo e o stream de sada de dados.

130

solicitao

e res:po,sta

N.9 eXIstem

ferh'untlS idl9tlS

r:

Por que voc tem que definir o tipo de contedo? Os servidores no podem descobrir do arquivo?

r:

isso a partir da extenso

Espere um segundo ... por que voc precisaria usar um servlet para enviar de volta aquele arquivo JAR, quando voc pode ter o servidor enviando-o como um recurso? Em outras palavras, por que no fazer com que o usurio clique em um link que v para o JAR em vez do servlet? O servidor no pode ser configurado para enviar o JAR diretamente sem sequer PASSAR pelo servlet?

1\:A maioria dos servidores pode, para contedo


esttico. No Apache, por exemplo, voc pode configurar os tipos MIME mapeando a extenso do arquivo (.txt, .jar, etc.) para um tipo de contedo especifico, e ele usar isso para configurar o tipo de contedo no header HTIP. Mas estamos falando sobre o que acontece dentro de um servlet quando NO H nenhum arquivo! voc quem est enviando de volta a resposta; o Container no tem idia do que voc est enviando.

1\: Sim. Boa pergunta.

r:

E com respeito ao ltimo exemplo onde voc l um arquivo JAR? O Container no pode ver que voc est lendo um JAR?

Voc PODERIA configurar o servidor de forma que o usurio dique em um Iink HTML que o leve, digamos, ao arquivo JAR localizado no servidor (assim como qualquer outro recurso esttico, como JPEGs e arquivos de texto), e o servidor simplesmente o enviaria na resposta. Mas ... estamos considerando que voc tenha outras coisas que queira fazer no servlet ANTES de enviar de volta o stream. Voc pode, por exemplo, precisar que a lgica no servlet que defina qual arquivo JAR a enviar. Ou voc pode estar devolvendo bytes que voc esteja criando ali mesmo, na hora. Imagine um sistema em que voc recebe parmetros do input do usurio e os usa para gerar dinamicamente um som que voc devolve. Um som que no existia antes. Ou seja, um arquivo de som que no se encontra em lugar algum no servidor. Voc acaba de cri-Io e agora est enviando-o na resposta. Ento voc est certo, talvez o nosso exemplo de enviar apenas um JAR localizado no servidor seja meio manjado, mas por favor ... use sua imaginao e enfeite-o com tudo aquilo que voc puder adicionar para torn-Io um servlet de verdade. Talvez seja algo to simples como inserir um cdigo no seu servlet que - junto com a devoluo do JAR - escreva alguma informao no banco de dados sobre este usurio em particular. Ou talvez voc tenha que checar para ver se ele est liberado para fazer o download deste JAR, baseado em alguma coisa que voc tenha detectado no banco de dados.

1\: No. Tudo o que fizemos

do servlet foi ler os bytes de um arquivo (por acaso era um arquivo JAR), e escrever de volta esses dados para um stream de sada. O Container no faz idia do que fazamos quando lamos aqueles bytes. Pelo o que ele saiba, ns estvamos lendo a partir de um tipo de informao e escrevendo algo completamente diferente na resposta.

r:

Como eu posso descobrir tipos comuns de contedo?

quais so os

Faa uma busca no Google. Srio. Novos tipos MIME esto sendo adicionados todo o tempo, mas voc pode encontrar facilmente listas na Web. Voc tambm pode dar uma olhada nas suas preferncias do browser por uma lista daqueles que foram configurados para seu browser, e tambm pode checar seus arquivos de configurao. Novamente, voc no precisa se preocupar com isto para o exame e provavelmente no lhe causar muito estresse no mundo real tambm.

1\:

voc est

131

printWriter

e OutputStream

Voc tetM duas opes para sada: caracteres ou bytes


Isto apenas um simples java.io, exceto pela llterface ServletResponse que oferece apenas duas opes de streams para escolher: ServletOutputStream para bytes ou PrintWriter para dados em caracteres.

~ Printwriter
Exemplo:
PrintWri ter wri ter = response

.AnUtmm

writer.'.ff''''p(''sorne
Usado para:

text

and HTML");

Voc DEVE memorizar estes mtodos


Voc tem que saber isso para o exame. E uma armadilha. Repare que para escrever para um ServletOutputStream voc writeO,porm, para escrever para um PrintWriter voc ... printlnO! comum considerar que voc escreve para um escritor, mas no. Se voc j usa o java.io, j passou por isso. Se no, lembre-se: printlnO para um PrintWriter writeO para um ServletOutputStream E no se esquea de que os nomes dos mtodos para obter o stream ou o escritor perdem a primeira palavra, conforme segue:
ServletOutputStream response.getOutputStream()
Pr:intWriter

Exibir dados de texto para um stream de caracteres. Embora voc ainda possa exibir dados em caractere usando o OutputStream, ele que voc utilizar para tratar seus dados em caractere.

~ OutputStream
Exemplo:
ServletOutputStream getOutputStream() outCiiIII(aByteArray) out response.

Usado para: Escrever qualquer


outra coisa!

response.getWriter()

Voc precisa reconhecer nomes FALSOS, como:


er() "\

ream ()

er ()

s.f.es AJj,O exts.f.elPof

Para 5va Ii1{tif'lrla{it:;; 5ef'lI!e+ov.fpv.f.5.frealrl. pua


til

f) fi,i'IWf'i+ef'

PIaverdade e~ac{j.fa

{j

Ov s!i"J t:;f1.1),Wrl.f.et'

+elrl vlrla t'e{et'~ IrlQS(j

Set'lIle+ov.fpv.f.5.ft'ealrl

e de1eja t:;s ct.alYladaspat'a ele.

trpei1tJ.s vJl1. s.frefJ.1Pl de sfJ.fdade "adas v"l.f.a para a c1te~J

PrI),-ANt't.f.et' (J elYlbe1ejatkdlct<;I1QJ1da lYI.f.ad()sde 4/.f.<;J1:vel Ctlf4j'!S de .f.t'l'J..f.fJ.t' as Cl'J.f'ac+eres,

132

soliCitao

e res.:posta

Voc pode configurar headers de resposta, voc pode adicionar headers de resposta
E voc pode querer saber qual a diferena. Mas pense nisso por um segundo e faa o exerCcio. Correlacione a chamada ao mtodo com o seu comportamento
response. setHeader (ftfoo", ftbar");

Trace uma linha do mtodo HttpResponse para o seu comportamento. Ns fizemos o mais bvio para voc.

Adiciona um novo header e um novo valor na resposta, ou acrescenta um outro valor para um header existente. Um mtodo de convenincia que substitui o valor de um header existente por seu valor integral, ou acrescenta um novo header e um novo valor na resposta. Se um header com este nome j existir na resposta, o valor alterado por este. Ou ento, acrescenta um novo header e um novo valor na resposta.

response.addHeader(ftfoo",

ftbar");

response. setlntHeader

(ftfoo", 42);

Bem fcil quando voc os v todos juntos. Mas para a prova, voc deve memoriz-Ios, pois se na prxima tera-feira o cara no final do corredor perguntar: "Qual o mtodo de resposta que me permite acrescentar um valor para um header existente?", voc possa dizer, sem pestanejar: " o addHeader, e ele possui duas Strings, para nome e valor." Assim mesmo. O setHeaderO e o addHeaderO acrescentaro um header e um valor na resposta, se o header (o primeiro argumento para o mtodo) ainda no estiver l. A diferena entre configurar e adicionar aparece quand o header est l. Nesse caso: setHeaderO sobrescreve o valor existente addHeaderO adiciona um novo valor Quando voc chama o setContentType ("text/html"), voc est configurando um header como se dissesse: setHeader("content-type", "text/html"); Ento, qual a diferena? Nenhuma ... considerando que voc digite corretamente o header "content-type". O mtodo setHeaderO no vai reclamar se voc escrever errado o nome dos headers - ele simplesmente acha que voc est adicionando um outro tipo de header. Porm, algo dar errado l na frente, j que agora voc no configurou corretamente o tipo de contedo da resposta! voc est 133

redrecionando

Mas

algutMas vezes voc tMestMO no quer

lidar COtMa resposta ... Voc pode decidir que algo diferente trate a resposta para a sua solicitao. Voc pode ou redirecionar a solicitao para uma URL completamente diferente, ou despach-Ia para algum outro componente da sua aplicao (geralmente um JSP).

Redirecionando

O cliente uma URL no browserdigita ...

A solicitao vai para o servidor/Container

O servlet decide que a solicitao deve ir para uma URL completamente diferente.

e e
O browser recebe a resposta, v o cdigo de status "301" e procura por um header "Location"

/
na

O servlet chama o sendRedirect(aString) resposta e pronto

i i I I! .... : .,.{ . y.

A resposta HTTP possui um cdigo de status "301" e um header "Location" contendo uma URL como valor

li

134

solicitao

e resposta

oo

browser faz uma nova solicitao usando a URL que representava o valor do header "Location" na resposta anterior. O usurio pode notar que a URL na barra de endereos do seu browser mudou...

No h nada de exclusivo na solicitao, ainda que ela tenha sido ativada por um redirecionamento

o
O servidor recebe o que consta na URL solicitada. Nada de e?pecial
aqUi

o
Cl

A resposta HTIP igual a qualquer outra resposta ... exceto pelo fato de que ela no vem do local que o cliente ~ digi!ou O browser exibe a nov pgina. O usurio fica maravilhado

Ifr
voc est

135

redirecionamento

do serviet

o redireciotlatltettto
o redirecionamento
if

do Servlet faz o browser trabalhar

deixa o servlet completamente aliviado. Aps perceber que ele no poder desempenhar o trabalho, o servlet simplesmente chama o mtodo sendRedirectQ:
(worksForMe) { trata a solicitao else { response.sendRedirect{ http://www.oreilly.com

Ii

);

I Ir f//t.L
3l1e' vc alieI' 3l1e' ~ ;;1'i)wst:1' lIse piAl'a a slir+#.fia.

., clte"h v

lssa

Usatldo URLs relativas tiOsetldRedirectO


Voc pode usar uma URL relativa como um argumento para o sendRedirectO, em vez de especificar o endereo completo ''http://www ...''. As URLs relativas vm em dois sabores: com ou sem a barra ("/") inicial. Imagine que o cliente digitou primeiramente:
http://www.wickedlysrnart.com/rnyApp/cool/bar.do

f) C"+fJ,IPf!1' sde
chama o sendRedirectO com a URL relati a que NtO inicia com a barra: I Quando sendRedlrect{"foo a solicitao chega ao servlet Cha'tadO "b~.dO", ele 'I I stuff.htrnl'); I
le s.:;llCl+fJ.jilJi
ItJ Ct:iJJ'l/Pt...:;

lJil'lj'Pt:!

~fJrpplca6/~
se ve..c "ie.. lIStAl' tA

ptll'+rt,,,+tI;
" J

blJ,l'l'IJ" f!S+fJ.PIJ,I'+t tia

o header "Location" que ele coloca na res10sta H TP), O Container constri a URL completa relativa URL da solicitao inicial:

IU::I'f!sce,,+aJa

Je

(elI preCisr'dela
INICIAR

para

http://www.wickedlysrnart.com/rnyApp/cool/foo/ stuff.htrnl

Mas se o argumento com a barra:


sendRedirect

para o sendRedirectO

("/foo/stuff .htrnl");~

fJr

1141'1'1II;" CIl'lf!j
1'11I;1'5

O Container constri a URL completa relativa ao container web em si, em vez de relativa URL original da solicitao. Assim, a nova URL ser:
http://www.wickedlysrnart.com/foo/stuff.htrnl

l'eItJ.+ivlJ. ~

I
JIJ ti.fllca-hV6

"fila" e illI'I Ilpllct!l.-hVf)

WebJ sep4N.J

web "~fJrpp".

136

C81PtlJlo4

solicitao

e resposta

Voc no pode fazer um sendRedirectO depois de escrever a resposta!


Isto provavelmente bvio, mas a LEI e ns estamos apenas ratificando. Se voc procurar o sendRedirectO na APL voc ver que ele envia uma IllegalStateException se voc tentar cham-Io depois "da resposta j ter sido criada". Eles querem dizer com "criada" que a resposta foi enviada. Isso significa que os dados foram enviados para o stream. Na prtica, significa que voc no pode escrever na resposta e depois chamar o sendRedirectO! Mas um professor exigente diria que, tecnicamente, voc pode escrever no fluxo de dados sem que haja o flush, e o sendRedirectO no geraria uma exceo. Mas isto seria algo completamente estpido e, por isso, no vamos tocar no assunto. (Se bem que ... acabamos defalar. ..) No seu servlet, decida, pelo amor de Deus! Ou trate a solicitao, ou faa um sendRedirectO para que OUTRA entidade a trate. (Alis, este papo de "uma vez enviada, j era" tambm se aplica configurao de headers, cookies, cdigos de status, o tipo de contedo e assim por diante ...)

'RL oa uma Str' . . A questo . o zng que E uma rrega um objet' se,!dRedirectO NA-O ssap ara ele um o ttO tzpo U'RL Vr C' a Dtrzng . oce completa ou l' que e uma re atzva . S.e o Container -, P Utter trans+orm '.Jl ar uma U'RL nUma URL I.Z complet. a, e l e manda relativa legalStat E l e Xceptzon O uma embrar que ISTO" que confunde send'Red'zrect/T T'RL e errado' . ! v, nova("htt 'P.//www.oreilly. IL Com '')11 :/
A

o sendRedirecto Carrega um o . String e N bJeto URL' O uma em l , e e carreo:

137

requesf dispatch

o request

dispateh aeottteee no lado do servidor

E esta a grande diferena entre um redirecionamento e um request dispatch - o redirecionamento faz o cliente executar o trabalho, enquanto que o request dispatch faz com que outro componente no servidor execute o trabalho. Ento, lembre-se: redirecionamento = cliente, request dispatch = servidor. Ns falaremos mais sobre o request dispatch mais adiante, porm, estas duas pginas devero dar a voc uma noo dos pontos mais importantes.

o Request

Dispatch

O usurio digita a URL do servlet no seu browser ..

A solicitao vai para o servidor/Container

O servlet decide que a solicitao deve ir para outra parte da aplicao . (neste caso, um JSP)

O browser recebe a resposta normalmente e a entrega ao usurio. . J que a barra de endereos do browser no mudou, o usurio no sabe que foi o JSP que gerou a resposta.

RequestDispatcher view ~ request.getRequestDispatcher(~result.jspn); view.forward(request,response);

O servlet chama

e o JSP cuida da resposta

f
f

r .
I

,t.~,
i

138

solicitao

e res:J)osta

RedirecionatMet1to

X Request Uispateh

Redirecionamento

Oi Kari, aqui o Dan... Eu quero a sua ajuda com um cliente. Vou encaminhar para voc os detalhes de como retornar para ele, mas eu preciso que voc cuide disso agora. Sim. eu SEI que voc tambm tem suas necessidades ... sim, eu SEI como a View importante para o MVC ... no, eu no creio que consiga outro JSP como aquele ... o qu? No entendi? A ligao est ruim . desculpe ... eu no consigo ouvir nada . perdendo pacotes ...

Quando um servlet faz o request dispatch, como se pedssemos que um colega de trabalho cuidasse de um cliente. O colega de trabalho acaba respondendo ao cliente, mas o cliente no se importa, desde que algum o responda. O usurio nunca sabe que outra pessoa assumiu o controle, pois a URL no browser no muda.

Request Dispatch

Quando um servlet faz um redirecionamento, como se pedssemos que o cliente ligasse para outra pessoa. Neste caso, o cliente o browser, e no o usurio. O browser faz a nova chamada em benefcio do usurio, depois do servlet que foi originalmente requisitado dizer: "Desculpe, chame este cara aqui. ../1 O usurio v a nova URL no browser.

voc est

139

reviso do HttpServietResponse

Reviso: HttpServletRespo"se

Voc usa a Resposta para enviar dados de volta para o cliente. Os mtodos mais comuns que voc chamar no objeto response (HttpServletResponse) so o setContentTypeO e O getWriterQ. Tome cuidado - muitos desenvolvedores acreditam que o mtodo seja getPrintWriterO, mas getWriterO. O mtodo getWriterO permite fazer I/O por caractere para criar o HTML (ou algo mais) para o stream. Voc tambm pode usar a resposta para configurar headers, enviar erros e adicionar cookies. No mundo real, voc provavelmente usar um lSP para enviar a maioria das respostas HTML, mas voc ainda poder usar um stream de resposta para enviar dados binrios (como um arquivo lAR, talvez) ao cliente. O mtodo que voc chama na sua resposta para receber um stream binrio getOutputStreamO. O mtodo setContentTypeO diz ao browser como tratar os dados vindos na resposta. Os tipos de contedos mais comuns so "text!html", "application/pdf' e "image/jpeg". Voc no precisa memorizar os tipos de contedos (tambm conhecidos como tipos MIME). Voc pode configurar headers de resposta usando o addHeaderO ou o setHeaderO. A diferena depende de o headerj fazer palie da resposta. Se j fizer, o setHeaderO ir substituir o valor, mas o addHeader acrescentar um valor adicional resposta existente. Se o header ainda no fizer parte da resposta, ento o setHeaderO e o addHeaderO comportam-se exatamente do mesmo modo. Se voc no quiser responder a uma solicitao, voc pode redirecionar a solicitao para outra URL. O browser encarregar" se- de enviar a nova solicitao para a URL que voc fornecer. Para redirecionar uma solicitao, utilize o sendRedirect( aStringURL ) na resposta. Voc no pode chamar o sendRedirectO aps a resposta ter sido gerada! Ou seja, se voc j escreveu alguma coisa para o stream, muito tarde para fazer um redirecionamento. Um redirecionamento de uma solicitao diferente de um dispatch. O request dispatch (mais detalhado em outro captulo) acontece no servidor, enquanto que um redirecionamento ocorre no cliente. No caso do dispatch, a solicitao entregue para outro componente no servidor, geralmente na mesma aplicao. Um redirecionamento simplesmente informa ao browser para ir para uma URL diferente.

interface ServletResponse (javax.servlet.ServletResponse) <<interface> > ServletReslJonse getBujJerSizeO getOutputStreamO setcon.tentTypeo getWriterO setContentLengthO II MUITOS outros mtodos,,,

I"faee ll,,!rvle'RcsPonsc
Oavax.servlet.http. HttpServletResponse)
~~. < < ~interjace .~ > >

addCookieO addHeaderO encodeURLO sendErrorO setStatusO sendR.edirectO l/MUITOS outros mtodos ...

140 captulo 4

solicitao e feSJIIllII

fausa pata 9 caf 7e4tep~-e~4

1Como o cdigo do servlet de um mtodo service (por exemplo, doPost () ) obteria o valor do
header "User-Agent" da solicitao? (Escolha todas as que se aplicam.)

[J [J [J [J

A. String B. String C.String D.String

userAgent = request.getParameter(~User-Agent") ; userAgent = request.getHeader(~User-Agent"); userAgent = request.getRequestHeader(~Mozilla"); userAgent = getServletContext() .getInitParameter(~User-Agent");

2 Quais so os mtodos HTTPusados para mostrar ao cliente o que o servidor est recebendo?
(Escolha todas as que se aplicam.)

[J [J [J [J [J

A. GET

B.PUT C. TRACE D.RETURN E. OPTIONS

3 outra Qual mtodo do HttpServletResponse URL?


[J [J [J [J [J
A. sendURL () B. redirectURL () C. redirectHttp () D. sendRedirect() E. getRequestDispatcher

usado para redirecionar uma solicitao HTTP para

()

voc est aqui"

14

teste

4 Quais

os mtodos

HTTP

que NO

so considerados idempotentes? (Escolha todas as que se

aplicam.)

o
O O O

A.GET B. POST C.HEAD D.PUT

Sendo req um HttpServletRequest,

qual das alternativas recebe um

stream de entrada de

dados binrios? (Escolha todas as que se aplicam.)

o
O

A. BinaryInputStream B.ServletInputStream C.BinaryInputStream D.ServletInputStream

s s s

= =

req.getInputStream(); req.getInputStream();

O O
6

req.getBinaryStream();

s = req.getBinaryStream();

Como

voc configuraria um

header chamado

"CONTENT

-LENGTH"

no objeto

HttpServletResponse?

(Escolha todas as que se aplicam.)

o
O O

A.response.setHeader(CONTENT-LENGTH,"1024"); B.response.setHeader(~CONTENT-LENGTH","1024"); C.response.setStatus(1024); D. response.setHeader(~CONTENT-LENGTH",1024);

Escolha o trecho do cdigo do servletque recebe um imagem,

stream binrio para escrever uma

ou outro tipo binrio,no HttpServletResponse.

o
O

A. java.io.PrintWriter B.servletOutputStream C. java.io.PrintWriter

out out out

response.getWriter(); response.getOutputStream();

O O

new PrintWriter(response.getWriter(; D.ServletOutputStream out

response.getBinaryStream();

142

solicitao e respQSia

8 Quais mtodos so usados por um servlet para tratar os dados do formulrio vindos de um cIieoIe?
(Escolha todas as que se aplicam.)

o
O
O O

A. HttpServlet.doHead() B. HttpServlet.doPost() C.HttpServlet.doForm() D. ServletRequest.doGet() E.ServletRequest.doPost() F.ServletRequest.doForm()

O O

9 Quais dos seguintes


ServletRequest?

mtodos so declarados no HttpServletRequest (Escolha todas as que se aplicam.)

ao contrrio do

o
O O O O

A. getMethod () B. getHeader () C. getCookies () () D. getInputStream() E. getParameterNames

10

Como os desenvolvedores de servlet devem tratar o mtodo service () do HttpServlet quando estenderem o HttpServlet? (Escolha todas as que se aplicam.) A. Eles devem anular o mtodo service B. Eles devem chamar o mtodo service C. Eles devem chamar o mtodo service () na maioria dos casos. () do doGet () ou doPost () . () do mtodo init () .

o
O O O

D. Eles devem anular pelo menos um mtodo doXXX () (como um doPost () ).

voc est aqui ~

143

respostas do teste

'fausa pata 9 cat


e~-~4

1Como o cdigo do servlet de um mtodo

service (por exemplo, doPost () ) obteria o valor do header "User-Agent" da solicitao? (Escolha todas as que se aplicam.)

A. String userAgent = request.getParameter("User-Agent"); B. String userAgent = request. getHeader ("User-Agent") ;


C. String userAgent =

-If

p{i<I!J lj lfJ!<l!Js.f.I"GI.

a chalfJ!tl.Ja ct:Jl"l"e-/-a at:J

request.getRequestHeader("Mozilla");
D. String userAgent =

II'\~.f./J#(~~ye passa "76<9\e 6 t.eaJel" C"1fJ!6 tlII'\ p41"~e.f.l"fJ S.f.I"I~5'

getServletContext().getlnitParameter("User-Agent");

:2 Quais so os mtodos HTTP usados para mostrar ao cliente o que o servidor est recebendo?

o
~

(Escolha todas as que se aplicam.) A. GET B. PUT C. TRACE D.RETURN E.OPTIONS

(C.~. I

tJ,

J <9\e.f."J(J$

Ii.o. r.J rrrr

O O O

<9\~.f.(JJ(J ~ lISfJ.Je.hpi4<9\ft"7.f.ep4NJ.

e "7';" pIJ.NJ.PI"(JYj';'"

.3

Qual mtodo do HttpServletResponse outra URL?

usado para redirecionar uma solicitao HTTP para

o
~

O O
O

A. sendURL () B. redirectURL () C. redirectHttp () D. sendRedirect() E. getRequestDispatcher

cl"l"e+a
"76

e d6$

1fJl~.f.(Jt'I$

l1#pSel"'il1e+/Cesp6i'1$f!.

()

144 car)ituio 4

solicitao e resposta

4 Quais os mtodos HTTP que NO so considerados idempotentes? (Escolha todas as que se


aplicam.)

o
~

O
O

A.GET B. POST C.HEAD D.PUT

- ~r

esijl'lJ

c posrJeve

cc~Jvt/t. as Scli'c'-hs':es ftu'a

fl.fva/ljfJ.r" AI

es..f.fl.tl.16 serlll6r. ,

", 5era/; fi."'es"'t< a.+VfJ.li'jti46

~ac eve ser apllcaa.varias vejes.

5 Sendo req um HttpServletRequest,

qual das alternativas recebe um stream de entrada de dados binrios? (Escolha todas as que se aplicam.) A.BinaryInputStream s = req.getInputStream(); B. ServletInputStream s = req.getInputStream(); -1Jr ep{i6 ~ eSfect/tca C. BinaryInputStream s = req.getBinaryStream(); ",.fcJc e c+ipc Je re+iJrl'l" D.ServletInputStream s = req.getBinaryStream();C6rre+cs.

o
!iir

O
6

Como voc configuraria um header chamado "CONTENT-LENGTH" no objeto HttpServletResponse? (Escolha todas as que se aplicam.)

o
!iir

(A-PI)
IJ,

A. response. setHeader (CONTENT-LENGTH,"1024") ; - A- "f54" ~ II'!tls..f.ra

O O

B. response. setHeader ("CONTENT-LENGTH" ,"1024") itfI41'1elra C6rre..f.a leCI'1/i5t1Na.r C. response. setStatus (1024) ; VIPo t.eo.ler C"1Po J!)l); D. response. setHeader ("CONTENT-LENGTH" ,1024) ; po.rlJ.lPof:'"f"NJS .._ J. .s-rr1I'1jS; J VII'!

I/rrp

represel'1+lIIl'1tl" ., 1'1t1lPoe Je. t.ef<er) e ., llv+r<!J) <!J valer.

1
~

Escolha o trecho do cdigo do servlet que recebe um stream binrio para escrever uma imagem, ou outro tipo binrio, no HttpServletResponse. A. java.io.PrintWriter out = response.getWriter(); B.ServletOutputStream out = response.getOutputStream(); C.java.io.Printwriter out = new PrintWriter(response.getWriter(; D.ServletOutputStream out = response.getBinaryStream();

o
O O

-AfS+: l"'cl:Jl"re+a)
p(Jl"~ve e/fi.lisa II~ fi.1.,,-PNl"l+er 4rren+o.JIJ f6r C4f'itc+ere.
j>

145

respostas do teste

8 Quais mtodos so usados por um servlet para tratar os dados do formulrio vindos de um cliente?
(Escolha todas as que se aplicam.)

o
~

A. HttpServlet.doHead() B. HttpServlet.doPost() C.HttpServlet.doForm() D. ServletReques


F. ServletRequest.

O
O

- A-s fj';eS C e F es-l-';c er;'fJ.dUJ frafJe es-hs Irt:J.fi6S ,,';c exi's-hlrt.

t. doGet () doForm ()

O
O

E.ServletRequest.doPost()

Quais dos seguintes mtodos so declarados no HttpServletRequest servletRequest? (Escolha todas as que se aplicam.) A. getMethod () B. getHeader () C. getCookies () () D. getlnputStream() E. getParameterNames - A-s 6fj';eS A-;

ao contrrio do

8 e C relereli?lHrrp'

se QSclJIPIfl)'Ie"ffs

fie fJIi?I4 scltet-l-4j';6

10

Como os desenvolvedores de servlet devem tratar o mtodo service () do HttpServlet quando estenderem o HttpServlet? (Escolha todas as que se aplicam.) A. Eles devem anular o mtodo service B. Eles devem chamar o mtodo service C. Eles devem chamar o mtodo service () na maioria dos casos. () do doGet () ou doPos t () . () do mtodo

o
-~

O O
~

ini t

() .

D. Eles devem anular pelo menos um mtodo doXXX() (como um dopost(. I)f]'; b es-I-~ crN~-I-tJ.. Os Je.se"vlJlveJares 6S lrt-l-6fis dbe+o e J6fAS-I-().

-I}

5erl3.lli?Ie,,-h fJSO,Irt

146 capitulo 4

Sendo uma Aplicao Web


Voc tem que entender como as partes de uma aplicao interagem e deve respeitar as threads. Se voc se sair bem nos testes preparatrios deste captulo, eu pouparei a sua vida.

/
Nenhum servlet vive sozinho. Nas aplicaes web atuais, vrios componentes trabalham em conjunto por um objetivo. Temos os modelos, os contraladores e as views. Temos os parmetras e os atributos. Temos as classes helper. Mas, como juntar os pedaos? Como permitir que os componentes compartilhem informaes? Como voc oculta informaes? Como voc toma uma informao thread-safe? Sua vida pode depender destas respostas. Portanto, certifique-se de que voc tenha bastante ch quando for ler este captulo. E que no seja aquela erva descafeinada detestvel.

este

um

novo cai'Jftl1Io~

147

objetivos do exame oficial da Sun

o~
o Modelo
do Cotttait1er Web
3.1 Para os parmetros de inicializao do servlet e do ServletContext: eserevero cdigo servlet para acessar os parmetros de inicializao e criar os elementos do deployment descriptor para declarar os parmetros de inicializao. 3.2 Para os atributos de escopo bsicos do servlet (solicitao, sesso e contexto): escrever o cdigo servlet para adicionar, processar e remover os atributos; dado um determinado cenrio, identificar o escopo adequado para um atributo e as questes relacionadas a multi-threading em cada escopo.

Notas sobre

a Abrangncia:

Todos os objetivos desta seo sero totalmente abordados neste capitulo, exceto o 3.3, que ser abordado no capitulo que trata dos Filtros. A maioria dos assuntos deste capitulo aparecer em outras partes do livro, mas se voc for fazer a prova, AQUI que esperamos que voc aprenda e memorize os objetivos.

3.3 Descrever os elementos do modelo do container para o procf:ssamf:nto de<; solicitaes: Filtro, cadeia de Filtros, wrappf:rs para solicitao e resposta e recursos Web (sf:rvlet ou pgina JSP).

L___

./

XpliCf.d

111)

Cf.p':lvle.

Sue

.fr/J..f.ti.sbre I)S Fn.frfJs.

3.4 Descrever o ciclo de vida do Container para solicitaes, sesses e aplicaes web; criar e configurar classes de listener para o ciclo de vida do escopo; criar e configurar as classes listeners para o ciclo de vida de cada escopo e, dado um cenrio, identificar o atributo de listener adequado para o uso. 3.5 Descrever o mecanismo RequestDispatcher; escrever o cdigo servlet para criar um request dispatcher; escrever o cdigo servlet para encaminhar ou incluir o recurso desejado; e identificar os demais atributos do escopo request fornecidos pelo container para o recurso desejado.

148 captulo 5

atributos e fisteners

Eu quero que meu endereo de e-mail aparea na pgina das cervejas que o meu servlet cria ... mas acho que ele vai mudar e eu no quero ter que recompilar meu servlet s para alterar isso ...

o a
Kith quer co. figurar seu e-thail . 0 UU, e . o escrev-Io detttro da classe servlet
Eis o que Kim no quer em seu servlet:
PrintWriter out = response.getWriter(); out.println(Uplooper@wickedlysmart.comV);

melhor que ele coloque seu e-mail no Deployment Descriptor (arquivo web.xml), para que, ao distribuir sua pgina, o servlet possa, de alguma forma, "ler" o seu endereo de e-mail a partir do DD. Assim, ele no ter que fazer um hard-code do seu e-mail dentro da classe servlet. Quando quiser alter-Io, basta modificar apenas o arquivo web.xml, sem ter que mexer no seu cdigo servlet original.

voc est

I"

149

parmetros init

Os Partttetros lt1it do uttta for~


Voc j viu os parmetros de solicitao que podem vir no doGetO ou doPostO, mas os servlets tambm podem conter parmetros de inicializao.
Ao

~ce especi'fi'clJ. li"" pD.f'IJ.""-I/ID.""f!e li"" plJ.f'IJ.""-1I4Il1e.

No arquivo DD (web.xml):

Si'''''P1es; bas+1J.

J)lJr;eo

+er cef'+e;14 Je aye eS~14 d ele""elf+ <'sf!f'vle+> lfiJ J)J).


~

<servlet> <servlet-name>BeerParamTests</servlet-name> <servlet-class>TestlnitParams</servlet-class>

<init-param> <param-name>adminEmail</param-name> <param-value>likewecare@wickedlysmart.com</param-value> </init-param> </servlet>

No cdigo servlet:
out.println(getServletConfig()

.getlnitParameter(~adminEmail");

150

atributos

e lsteners

Voc t'lo pode usar os partMetros it'lit do servlet setMque ele teKha sido it'licializado
Voc acabou de aprender que seu servlet herda o getServletConfigO; portanto, voc pode cham-Io de qualquer mtodo do servlet para conseguir uma referncia ao ServletConfig. Uma vez que voc tenha uma referncia ao ServletConfig, voc pode chamar o getInitParameterO. Mas, lembre-se, voc no pode cham-Io direto do seu construtor! A vida do servlet est apenas comeando ... ele no ter toda a sua funcionalidade at que o Container chame o initO.

Q..uand9 9 C9ntalnet In'ldq11za um setvlet~ c9nstt91 um UnIC9 SetvletC9nllg Plttele. O C9ntVnel' ~le~'9S
"CJ

IJ/f/)/f de Set"v1e-!-CIJ'7fij
pt" e'71//lJ.dlJ. I4vt-l-6 eedIJ -----:::;

<ti

construtor

pltmett9s ln'lt d9 setvlet ti:ttvsd9 DD e 9S


destroyO PtSSt t9 SetVletC9nllg.

4'f.Vl 'f.lIe IJ . (S I C fi) set"vle-r li 1J1 ,,6-n::IJt I!. .. --7.lt erv et on 9

IJ sell 6!jdIJ Sel"vle-!-C6'7fij

Em seguldq~ passa 9 SetvletC9nllg plta 9

fi""'" se;V1e+

e f

sQ(
ele N9 ex'Istem

mt9d9 InltO do set,let.

t"IJd4t" IJSIJt-/-lJdlJs de sel"vi"]IJ~ (dIJbe+oJ dIJR.s+oJ de)J t"eeebe lIIJt Set"vle-!-ClJ'7flj

fetbuntlS dl9tl5

f:

L no captulo anterior voc disse que um servlet requer DUAS coisas para tornar-se um servlet vlido e fez-wearing. Voc mencionou o ServletConfig e um tal de ServletContext.

I\:

I\:

Tudo bem, sim, vamos falar sobre o ServletContext dentro de algumas pginas. Por enquanto, vamos ver s o ServletConfig, pois a que voc especifica os parmetros init do seu servlet.

Ns no dissemos que o initO carrega um ServletConfig porque aquele que voc anula no carrega um. Sua superclasse inclui duas verses do initO: uma que traz um ServletConfig e uma verso de convenincia que padro. O mtodo init(ServletConfig) que foi herdado chama o mtodo-padro initO. Assim, o nico que voc precisa anular o da verso-padro.

f:

Espere um pouco! No captulo anteror voc disse que podamos anular o mtodo initO e ningum disse uma palavra sequer sobre o argumento ServletConfig!

No h regra que o impea de anular aquele que carrega o ServletConfig, mas se quiser FAZER isso, melhor que voc chame o supero init(ServletConfig)! Porm, realmente NO h razo para que voc queira anular o mtodo init(ServletConfig), j que voc ter sempre o seu ServletConfig chamando o mtodo herdado getServletConfigO

voc est aqui ~

151

parmetros int do servlet

Os partltetros itlf do servlet so lidos apetlas UMA


VEZ: quatldo o Cotrtaitler itlicializa o servlet
Quando o Contaner cria um servlet, ele l o DD e cria os pares nome/ valor para o ServletConfig. O Contaner nunca l os parmetros init novamente! Uma vez que os parmetros esto no ServletConfig, eles no sero lidos novamente at que (ou a menos que) voc recrie o servlet. Pense nisso.

00 Container l Deployment Descriptor para este serv/et, incluindo os


O

eo eo

parmetros init init-param l


web.xml

Container cria uma nova instncia ServletConfig para este servlet new

80 Container cria um par de Strings nome/valor para cada parmetro init do


servlet. Considere que temos apenas um. ~ new

Container d ao ServletConfig as referncias para os parmetros init nome/valor

string

Lnew

eo

Container cria uma nova instncia da classe servlet

eo

Container chama o mtodo initO do servlet, passando a referncia para o ServletConfig

>c/new
>.

J~ontqihej r..... v. instncia de


MyServlet.class Servletstring ~ init(ServletConfig))
Config

instncia de MyServlet .class 152

atributos

e listenets

Mas bem melhor que coloc-Io na fonte do meu servlet. Tudo que eu tenho a fazer alterar o xml e pressionar o boto "redistribuir", e o novo e-mail estar no ServletConfig

o o

f ethuntas Idl9tas
r:
Ento, bem, onde est este tal boto "redistribuir" no Tomcat?

N() exlstliom

r:

claro que fcil encerrar e reinicializar o

inteiras sem reinicializ10. Em um ambiente de produo, assim que voc faria. Porm, para teste, mais fcil simplesmente reiniciar o Tomcat. Voc poder obter informaes sobre a ferramenta de gerenciamento em: http:/(jakarta.apaehe.org/ torneat/torneat-5. O-doei rnanager-howto. htrnl No mundo real, at uma redistribuio quente Importante. E tirar do ar uma aplicao, simplesmente por causa de uma mudana no valor de um parmetro init, pode ser uma pssima idia. Se os valores dos seus parmetros init forem mudar com freqncia, melhor que os mtodos do seu servlet obtenham os valores de um arquivo ou banco de dados, mas esta prtica resultaria em muito mais trfego sempre que o cdigo servlet rodar, em vez de uma nica vez na inicializao. voc est aqui ~

1\: O Tomcat no
possui uma ferramenta administrativa, que seja simples como um boto, para distribuio e redistribuio (embora exista, de fato, uma ferramenta administrativa que acompanha o Tomcat). Mas, pense comigo - qual a pior coisa que voc tem para fazer para alterar os parmetros init de um servlet? Voc faz uma rpida alterao no arquivo web.xml, fecha o Tomcat (bin/shutdown.sh) e o reinicia (bin/startup.sh). Na reinicializao, o Tomcat pesquisa seu diretrio webapps e distribui tudo o que ele encontrar l.

Tomcat, mas e quanto s aplicaes que estiverem rodando? Todas elas tm que ser encerradas?!

1\: Tecnicamente

sim. Encerrar suas aplicaes para que voc possa redistribuir um servlet

meio cruel, especialmente se houver demasiado trfego em seu site. Mas por isso que a maioria dos Containers de qualidade permite que voc faa uma

redistribuio quente, o
que significa que voc no precisa reiniciar seu servidor ou derrubar nenhuma outra aplicao. Alis, o Tomcat inclui sim uma ferramenta de gerenciamento que permite distribuir, desfazer e redistribuir aplicaes

153

usando ServletConfig

restat1do

seu ServletCot1fig

A principal funo do ServletConfig disponibilizar os parmetros init. Ele tambm pode fornecer um ServletContext, mas geralmente obtemos o contexto de uma outra forma e o mtodo getServletNameO raramente ajuda.

j avax. servlet. Serv letConfig <<interfaee> > ServletCon getlnitP arameter(String) Enumeration getlnitParameterNamesO getServletContextO getServletNameO

No arquivo DD (web.xml):
<?xml version="l.O" encoding="ISO-8859-1"?> <web-app xmlns~"http://java.sun.com/xml/ns/j2ee" xmlns:xsi~"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation~"http://java.sun.com/xml/ns/j2ee/web-app
version=rF2.4">

A-

1tIfJ,i"fJ!"l

Jas

peSSfJfJ,S

1'1111'1CfJ, lISfJ.

es.fe

1PI:-ftJJll

2 4.xsd"

<servlet> <servlet-name>BeerParamTests</servlet-name> <servlet-class>com.example.TestlnitParams</servlet-class> <init-param> <param-name>adminEmail</param-name> <param-value>likewecare@wickedlysmart.com</param-value> </init-param> <init-param> <param-name>mainEmail</param-name> <param-value>blooper@wickedlysmart.com</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>BeerParamTests</servlet-name> <url-pattern>/Tester.do</url-pattern> </servlet-mapping> </web-app>

Em uma classe servlet:


package com.example; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class TestlnitParams extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("test init parameters<br>"); java.util.Enumeration e = getServletConfig() .getlnitParameterNames(); while(e.hasMoreElements()) { out.println("<br>param name = " + e.nextElement() + "<br>");
}

out.println("main email is " + getServletConfig(). getlnitParameter("mainEmail")); out.println("<br>"); out.println("admin email is " + getServletConfig() .getlnitParameter("adminEmail");

154

cap,ftuJo

atributos e /isteners

JSP consegue

obter os

parlMetros

int do servlet?

foi feito para a configurao do servlet (no JSPConfig). Portanto, se voc quiser que outras partes da sua aplicao usem a mesma informao declarada nos parmetros init do servlet dentro do DD, voc precisar de algo mais.

o ServletConfig

Que tal a lManeira COlMO fizelMos COlM a

aplica~o da cerveja? Ns passalMOS a infortMa~o do lModelo para o JSP usando ~ se leW!bra? ()H,'ve~s UlMatributo de solicita~o...
. dentro do metodo doPost() ~~l'eJTl-eesc~tI String color = request.getParameter("color");
List result be ~ be.getBrands(color); BeerExpert ~ new BeerExpert ()

l\'l

CU"

Ii

JI"~S lia

;l "

""'" se.:tltJD., v J I1tJS I

Ii,S.f-tJ.I1CIfJ."'tI>S

e VStJ.",s

request. setAttribute

("s;tes'"
.
ti'" e/)",
J '"

result)

;ll4.tibLO
6bffl"
a
PN!C1"s4114"'S

ptU'tJ.

Na selP J,SP;

"J"ciD. es-tabe1ece"'S

/I IJ.-tf'i'bv-f-

,,)

114 sDlict-rC.fjfJ.

li,fl"hlaii6
ptJ.NJ.a

1If! I"ecebe :.s-tr;.

sucr-tafl.l'J)

f'f!cebe-1D Ns poderamos ter feito assim. O objeto request nos permite criar atributos (considere-os como sendo o par nome/valor, onde o valor pode ser qualquer objeto) que qualquer servlet ou JSP que receba esta solicitao conseguir us-Io. Isto significa que para qualquer servlet ou JSP para o qual a solicitao enviada, usa-se o RequestDispatcher. Vamos falar em detalhes sobre o RequestDispatcher no final deste captulo. Por enquanto, nossa preocupao passar os dados (neste caso, o endereo de e-mail) para os trechos da aplicao que deles necessitam, e no apenas para um nico servlet.
ctJl"Isejfli'tI

voc est aqui,",

155

(imitaes do nt parameter

Criar Utlt atributo de solicitao futtciotta ... tltas s para o JSP que recebe a solicitao
No exemplo da cerveja, fez sentido armazenar as informaes do modelo para a solicitao do cliente no objeto solicitao, pois o prximo passo foi encaminhar a solicitao ao JSP responsvel por criar a view. Como o JSP precisava dos dados do modelo e estes eram relevantes apenas para aquela solicitao especfica, tudo funcionou. Mas isso no nos ajuda no caso do e-mail, pois podemos precisar us-Io em toda a aplicao! Existe uma forma de fazermos um servlet ler os parmetros init e armazenlos em um lugar onde outras partes da aplicao possam us-los. Mas, neste caso, precisaramos saber qual servlet seria sempre o primeiro a rodar no momento da distribuio da aplicao, e qualquer alterao na aplicao poderia estragar tudo. No, isso tambm no funcionaria.
Mas eu quero mesmo que TODAS as partes da minha aplicao aceSsem o endereo de e-moi!. Com os parmetros init, eu tenho que configur-Ias no DD para cada servlet e, em seguida, fazer com que todos os servlets disponibilizemnos para os JSPs. Que chato, no?! E pouco prtico. Preciso de algo mais global.

c' o

156 captulo 5

atributos

e Iisteners

Os partRetros itlit do cotttexto do UtRafora


Os parmetros init do contexto funcionam como os parmetros init do servlet, exceto pelo fato de que os parmetros do contexto ficam disponveis para toda a aplicao, e no apenas para um nico servlet. Isso significa que qualquer servlet e JSP da aplicao automaticamente tm acesso a eles. Portanto, no precisamos nos preocupar em configurar o DD para cada servlet, e quando o valor for alterado, voc ter que mud-Io em um s lugar! Jefl:hiQvei'VIi~S () elehie'l.f.6 <.i;'i-l--pIJ.1"4hi> uft No arquivo DD (web.xml): ufe,,-fl"lJ uf4 elehif!l1-ftl <,stl"vle-f>
<servlet> <servlet-narne>BeerPararnTests</servlet-narne> / ~ </servlet> <servlet-class>TestlnitPararns</servlet-class> <context-param> <param-name>adminEmail</param-name> <param-value>clientheaderror@wicked1ysmart.com</paramvalue> </context-param> ~ ~c ct}lacavw.I'fi.I"fJ.w.-"ahie e lJw.pfJ.rlJ.w.-vaivf!,j ufa O <.ct}PI+-ex-l----""""'" w.fSWtfJ. lal"w.4 ~ve v6c Ia'] caw.6Spal"~e_f1"6S I."t.f. Ja

(
, )
f

IIU.POJerp,.lJrf./!

pfJ.l"aw.>vale pfJ.l"Q. rODA

sfrll/Hj

fiJ\b"l"IJ.tles-fo. Ve'] eles eS~IJ.iJ\ tle".f.I"EJJ., fw. vej Je <.i;'l-l--pfJ.N~hi>

al'licag'ij 1'61"'S S{j ele J1"ii tJ.l1i."t.fJ.Jtl fi.l1e"t.Yhi elew.f!I1+a <'Sfl"vlf..f..>!! CcllJ3ve (j ptJ.l"tJ.hI> de".f.1"6 ufI/J <.we!rapp>; hilJ.SFOJeA- de 3Vlai:SaVfr tleclal"4jCeS <.serllleh

elew.e".f.t:; <'U#t+e*pal"aw.>;

No cdigo servlet:
out.println(getServletContext().getInitParameter(~adminEmail");

Cada sfl"llle-f

"'trila

Vw.w.e+aJEJ

1';

f) iJ\:+6tllJ 5e_fSel"vie+ClJ",ffx+O
1"e-fIJI"PI!J.; cvri'SIJ.iJ\tl1+-e; li'" t>tJe+6 Sel"lIie-I-Ctm-l-ex+. VIrI d6S sevs w.&adJS ~ a 5e+IPli..;..pfJ.r!J.lYle+-eI"O.

5e..f..Servit-I-C"".fex+D {f~4S JSPs ..f..alrlb~iJ\ .fe"w. IJ.CeSS6 especlo.i 1M C/J,,+ex..f..6).

ou:
ServletContext context = getServletContext();

\ A3l1l ,,:s dillitll",s (J c:d~a tw. J)fJ As par.fes - I"f!cf!be"il 4 l"elel""tJ. da Sel"lIle-I-Ctm+-ex+ e Ct.fllYl!J.Plda Sf!lI w.+'~Ja 5e-l- Il1l+Pal"tJ.lrle.ferO. voc est aqui.. 157

out.println(context.getlnitPararneter(~adminErnail";

para/natras init do contexto

X parmentros nit do servlet

Lel\tbre-se da diferett9a ettlre os parl\tetros ittit do servlet e os parl\tetros ittit do COtttexto


Aqui est uma reviso das principais diferenas entre os parmetros init do contexto e os parmetros init do servlet. Preste bastante ateno ao fato de que nos referimos a ambos como parmetros init, ainda que apenas os parmetros init do servlet recebam a palavra "init" na configurao DD.

parmetros init do Contexto


Deployment Descriptor Dentro do elemento <web-app>, mas NO inserido em um elemento especfico <servlet>
<web-app ...> <context-param> <param-name>foo</param-name> <param-value>bar</param-value> </context-param> <!-- outros comandos, declaraes do servlet </web-app> incluindo -->

parmetros init do Servlet

Dentro do elemento <servlet> para cada servlet especfico


<servlet> <servlet-name> BeerParamTests <servlet-name> <servlet-class> TestlnitParams </servlet-class> <init-param> <param-name>foo</param-name> <param-value>bar</param-value> </init-param> <!-- outros </servlet> comandos -->

1Je.+e &Ue

i'1fJ

tl1t.f ftU'tA e.S

Cim+ex.fe.;

CfJ"""

flJ.l'~e.frds

tl1i.f tl.1J
Cdigo do Servlet

getServletContext()

.getlnitParameter(~foo");

getServletConfig() .getlnitParameter(~foo");

Disponibilidade Para quaisquer servlets e JSPs includos nesta aplicao. Somente para o servlet para o qual o <init-param> foi configurado. (Embora o servlet possa decidir aumentar sua abrangncia armazenando-o em um atributo.)

158

CBt)tulo 5

atributos

e iisl!eflIE.!

ServletCotlfig Utft por servlet ServletCotttext Utft por aplicao


Existe um nico ServletContext para toda a aplicao e todas as partes da aplicao compartilham-no. Porm, cada servlet na aplicao tem seu prprio ServletConfig. O Container cria um ServletContext quando uma aplicao distribuda, disponibilizando-o para cada Servlet e JSP (que se transforma em servlet) na aplicao.

Inicializao da aplicao web:


O Container l o DD e cria um par de String nome/valor para cada <context-paratn>. O Container cria uma nova instncia do ServletContext. O Container d ao ServletContext uma referncia a cada par nome/valor dos parmetros init do contexto. Cada servlet e JSP distribudo como parte de uma nica aplicao tem acesso quele mesmo ServletContext. S/~ "s JSPs S6 +rfJ.l1sf6r4'\fJ.tl6s e"'"

ClJl1ffx-l-"" tia o.pllcai'i" ~ ClJ4'\ tiS pfJ.r~e+r6s

~a6s

r:- servle+s
servletCo'<' ~

s. ....

ervletCOf'

s..

ervletCo'<'

~ \ s.ervletCOf' . ~

c/use

tle prl'vlefra e +fJ.".bi'l'\


I

par~e+Js 1"111+ para " Servle+ fJr l"i-tserM""s

11 \ rbar~e-l-"'6s p(J.r~e';""'i:Js l"i-tt-..j. t"i-tt+ para D

recebei'l'\ seils pr6p"'las Servle+C"l1f~

para"" Servle+ l"i-tse""aDS

Servle+ C l"i-tserMs

No confunda parmetros ServletConfig com parmetros

Se a aplicao for distribuda, existir um ServletContext porJVM!

ServletContext!

VeJa st9!
S~ ~ua aplicao for distribuda por varros s~rvidores (provavelmente em um a~bIente de cluster), ela at PODE ter maIS que um ServletContext. O Servl~tContext nico por aplicao ~~s so se a aplicao estiver em uma' ullIcaJVM! Em um ambiente distribudo voc ter um Servl~tC~ntext por JVM. at possvel que nao.de problemas, mas se voc tiver uma. aplIcao distribuda, melhor avalIar as conseqncias de possuir contextos diferentes para cada JVM.

Veja ist9!
Voc realmente tem que saber isso para o exame, mas confunde. Voc TEM QUE saber que tanto o ServletConfig, como o ServletContext possuem parmetros init e ambos usam o mesmo mtodo getter - getlnitParameterO MAS ... voc tambm tem que saber_ que os parmetros init do contexto ..sao criados com <context-param> (e nao dentro de um elemento <sen:le.t, enquanto que os parmetros mlt do servlet usam <init-param> dentro das declaraes <servlet> no DD.

voc est aaui

159

servlet

e o contexto do parrnetros init

N9 exJst~m

feth'untas Id'i9tas

campo de reteno magntica, deslizar at o centro da Terra e destruir o planeta. Ou talvez nada, porque no existe nenhum conflito de nomes, visto que voc obteve os parmetros atravs de dois objetos diferentes (ServletContext ou ServletConfig).

r: o

que acontece com a nomeao inconsistente do esquema? Como podem os elementos do DD serem <context-param> e <init-param>, porm no cdigo servlet, AMBOS usam o mtodo getlnitParameter()?

r:

Se voc modificar o XML para alterar o valor de um parmetro init (ou servlet ou context), quando o servlet, ou o resto da aplicao, reconhecero a mudana?

1\: Eles no nos solicitaram

para ajud-Ias a proporem um nome. Se eles tivessem pedido, claro que ns teramos dito que deveriam ser getlnitParameterO e getContextParameterO, para coincidir com os elementos XML no DO. Ou, eles poderiam ter usado diferentes elementos XML possivelmente <servlet-init-param> e <context-initparam>. Mas no, isto teria absorvido toda a graa de tentar mant-Ias corretos.

1\:

APENAS quando a aplicao for redistribuda. Lembre-se de que ns falamos sobre isso antes- o servlet inicializado apenas uma vez, no comeo da sua vida, e isso acontece quando dado a ele o seu ServletConfig e o seu ServletContext. O Container l os valores pelo DO quando ele cria estes dois objetos e configura' os valores.

r:

De qualquer forma, por que eu usaria <init-param>? Eu no poderia sempre querer usar <context-param>, de modo que as outras partes da minha aplicao poderiam reutilizar os valores e eu no teria que duplicar o cdigo XML para toda declarao do servlet? de qual parte da sua aplicao supe-se que veja o valor. A sua lgica da aplicao talvez requeira de voc usar um valor que voc queira restringir a um servlet individual. Mas tipicamente, os desenvolvedores acham os parmetros init do contexto da aplicao inteira mais auxiliar, do que um dos parmetros init do servlet de um servlet especifico. Talvez o uso mais comum de um parmetro do contexto est armazenado no banco de dados dos nomes de procura. Voc gostaria que todas as partes da sua aplicao tivessem acesso ao nome correto, e quando isso mudasse, voc gostaria de mudar isso em apenas um lugar.

r:

Eu no posso fazer isso configurando os valores no runtime? Certamente existe uma API que me permite mud-Ios dinamicamente ...

1\: No, no existe.

1\: Tudo depende

Procure no ServletContext ou no ServletConfig e voc encontrar um getter (getlnitParameter()), mas voc no encontrar um setter. No existe nenhum setlnitParameterO.

r:
1\:

Isto terrvel.

Eles so parmetros init. Init do latim inicializao. Se voc consider-Ias simplesmente como constantes para o momento da distribuio, voc ter a perspectiva correta. Na verdade, isso to importante que ns falaremos sobre isso de um jeito mais ousado:

r:

O que acontece se eu der a um parmetro init do contexto o mesmo nome de um parmetro init do servlet na mesma aplicao?

Considere os parmetros init como constantes para o momento da distribuio! Voc pode obt-/os no runtime, mas voc no consegue configur-/os. No existe nenhum setlnitParameterO.

1\:

O buraco negro do tamanho de uma molcula criada milagrosamente em um centro de pesquisas em Nova Jersey vai se livrar do seu

160 captulo 5

atributos

e listeners

:
lm de GeladeIra
ExerccIos
Rea;rume os m~ p~ra formar um DD que declara um parametro que cOlllcIde com o cdigo servlet:
getServletContext() .getlnitParameter("foo");

Voc no usar todos os ms! (Nota: ~uan~o voc encontrar <web-app ...>, d~ ~ue ISSO~ o_nosso ata!h0. para economizar pagllla. Voce nao pode dIstnbuir um arquivo me~os que a.tag <web-app> possua todos os qUaISnecessIta.) lembre-se espao na web.xml, a atributos dos

I </servlet>I
</param-value> bar

Se voc se deparar com o "parmetro init" e no souber se significa parmetro init do servlet ou context, considere como servlef. Algumas pessoas usam "parmetro init" para se referirem a "parllletro init do servlet". E usam "parmetro de contexto", ou mesmo "parmetro de aplicao", para se referirem a "parmetro init do contexto". Portanto, ainda que AMBOS sejam parmetros de inicializao - e derivem do mtodo getInitParallleterO -, lembre-se de que apenas os parmetros init do SERVLET so listados no DD como parmetros init. Assim sendo, a expresso "parmetro init"

<servlet-name>

BeerTest

< /servlet-name>

significa "parmetro init do servlet" por padro.


Sabemos que, como desenvolve dor, voc ser gentil com as outras pessoas e sempre dir, explicitamente, se um parmetro init um

[:serVlet-param>]

parmetro init do servlet ou um parmetro init do contexto.

voc est

161

o ServletGontext

voc pode fazer co", o seu ServletCotttext?


Um ServletContext uma conexo de JSP ou de servlet com o Container e os outros trechos da aplicao. Eis alguns mtodos do ServletContext. Colocamos em negrito aqueles que voc dever saber para a prova.

o que ",ais

< <interjace> > ServletContext


getlnitParameter(String) getlnitParameterNamesO getAttribute(String) getAttributeNamesO setAttribute(String) removeAttribute(String) getMajor VersionO getServerlnfoO getRealPath(String) getResourceAsStream(String) getRequestDispatcher(String)
IJ

Db-#/tI 6S pal'~f..f-r6S .;,,.+ f. 4b-#','/espect!lca a.f-rl/;v.f-4S

Db-#/tI os p4r~e.f-r()s 1;'''+ e IJb+/tl/ especlli'cli. li..f-rtbv+(;$

I.I. Db-r-e/tl

'" 1;'!6r/tllJ.f,IJes

slJbre 6 U),,+IJ.I;,er.

screvf.

/'1(;

fJ.1'~VlV,IJ '""e

hlare/tl4S lJ."i"a"h "esh cap:.f-VIIJ sfJbre }e.e1Jve s+Pts pl4+cheI'

1:;--"0

sel'lIt"t'J1'(especlli'c/J 1'41'Idrl'ca"h) t)V '76 Sjsh/tl.'JiI.f-.

log(String) // mais mtodos

162

atributos

ef

Voc pode obter o ServletContext de duas maneiras diferentes .


let sempre retm uma referncia let. Ento, no se engane caso

Um objeto ServletConjig do serv

para o ServletContext palratnesotee;~:eque diga: 'digo serv e tInitParameter () encontre um co


tservletContext() .ge getServletConfig() .ge

Alm de ser vlido, faz o mesmo que:


. I itparameter O tservletcontext() .get n

thJ.s . ge , PRECISARIA recorrer ao ,. vez que voce d Em um servlet, a UJ1lca letContext seria quan o voc ServletConjig para obt~r S~~t~::: no estendesse HttP~ervl~t oUd estivesse numa class; erv etServletContextO que voce ~er ou _o GenericServlet (o metodo g d ALGUM usar um metodo n~oGenericServlet). Mas a chan;eC e basta chamar seu prprio metodo HTTP praticamente zero. _ n ao, '+"so se voc encontrar um os nao jique conJ ~ getServletContext ,ma 1 C ifi para obter o contexto. a classe que NO seja um cdigo que utiliza o Serv et on gd as e se o cdigo estiver dentr~ . e. u.m or exemplo)? Algum pode ~r:let (uma classe assistente/utllztarw~~lasse e seu cdigo ter que ter passado um ServletConjig para e~er a referncia para o objeto usar o getServletContextO para rece ServletContext.

Y:

Como cada parte de uma aplicao consegue acesso ao seu prprio ServletContext?

1\: Hum,

1\:

no. A menos que voc tenha uma aplicao bem pequena mesmo. Existem formas de fazer logging bem melhores. O mecanismo mais popular e robusto de logging o Log4j. Voc pode encontr-Ia no site do Apache:

Para os servlets, voc j sabe: chame o seu mtodo getServletContextO herdado.

http://jakarta.apache.org/logj4j
Voc tambm pode usar a API logging do java. util.logging, acrescentada ao J2SE na verso 1.4. legal usar o mtodo ServletContext logO para experincias simples, mas em um ambiente real de produo voc provavelmente vai querer usar algo diferente. O livro Java Servtet & JSP CookBook, da Q'Reilly, explica muito bem sobre logging de aplicaes com e sem o uso do Log4j.

~Para JSPs um pouco diferente - os JSPs tm o que chamamos de "objetos implcitos", e o ServletContext um deles. Voc ver exatamente como o JSP usa o ServletContext quando chegarmos aos captulos sobre JSP.

Y:

Ento temos um logging ativo atravs do contexto? Parece MUITO til!

O logging no faz parte dos objetivos do exame, mas importante. Felizmente, as APls so fceis de usar.

voc est

aqui..

163

limitaes do parmetro de contexto

Detesto estragar a festa do seu ServletContext, mas estes parmetro~ init no passam de STRINGS! E isso! E se eu quiser inicializar minha aplicao com um banco de dados DataSource, que todos os servlets podem usar?

se voc quiser Uift pariftetro it1it t1a

D o

aplica9o que seja Uift l1afaSource de bat1co de dados?


Os parmetros do contexto no passam de Strings. Afinal, voc no pode inserir direito um objeto Dog em um deployment descriptor XML. (Na verdade, voc poderia representar um objeto serializado em XML, mas no h nenhum recurso para isso na especificao do servlet atualmente ... talvez no futuro.) E se voc realmente quiser que todas as partes da sua aplicao tenham acesso a uma conexo com um banco de dados compartilhado? Com certeza, voc pode colocar o nome de loolmp do DataSource em um parmetro init do contexto. Este , provavelmente, o uso mais comum dos parmetros de contexto hoje em dia. Mas ento quem faz o trabalho de transformar o parI1letro String em uma referncia real ao DataSource que todas as partes da aplicao possam compartilhar? Voc no pode mesmo colocar este cdigo no servlet, pois qual servlet voc escolheria para ser Aquele Que Pesquisa No DataSource E O Armazena Em Um Atributo? Voc gostaria mesmo de tentar garantir que um determinado servlet rodasse sempre primeiro? Pense nisso.

EXERCITE SUA 1WENTE


Como voc solucionaria este problema? Como voc conseguiria inicializar uma aplicao com um objeto? Considere que voc precise da String parmetro init do contexto, a fim de criar este objeto (imagine o exemplo do banco de dados).

164

Poxa, se ao menos existisse uma forma de ter algo como um mtodo principal para minha aplicao toda. Algum cdigo que sempre rodasse antes de QUAISQUER servlets ou

JSPs ...

o o

o que ela realtMettte

quer

UtMlistetler

Ela quer escutar um evento de inicializao do contexto, de forma que ela possa obter os parmetros init do contexto e rodar um cdigo antes que o resto da aplicao possa servir um cliente. Ela precisa de algo que possa estar situado l, esperando para ser avisado que a aplicao foi iniciada. Mas qual parte da aplicao poderia fazer esse trabalho? Voc no iria escolher um servlet - j que esta no uma tarefa dele. No h nenhum problema com uma aplicao lava simples standalone, pois voc tem o mainOl Mas, se for com um servlet, o que voc faz? Voc precisa de algo diferente. No um servlet ou lSP, mas algum outro tipo de objeto lava cujo nico propsito na vida seja inicializar a aplicao (e, possivelmente, no inicializ-la tambm, limpando os recursos ao perceber que a aplicao foi encerrada ...).

voc est aqui ~

165

context listener

Ela quer Ul\t ServletCotttextListet1er


Podemos criar uma classe separada, no um servlet ou JSP, que possa escutar os dois eventos principais na vida de um ServletContext - a inicializao (criao) e a destruio. Essa classe separada implementa o javax.servlet.ServletContextListener.

<: <:interfaee> >

~ ServletContextListener eontextlnitialized(s, eontextDestroyed(s:rvletContextEvent) rvletContextEvent) Javax.servlet S . ervletContextL lstener

Precisamos de um objeto parte que possa:


Ser notificado quando sendo distribuda).

o contexto

inicializado (a aplicao est

Conseguir os parmetros init do contexto atravs do Serv letContext. Usar o nome de lookup do parmetro init para fazer uma conexo com o banco de dados. Armazenar a conexo com o banco de dados como um atributo, para que todas as partes da aplicao possam acess-la. Ser notificado quando o contexto destrudo (a aplicao retirada do ar ou cai). Encerrar a conexo com o banco de dados.

f) Ils-fePlf!1'

JiJ CiJPI-feX+tJ t"'Y'leJr;fi!PI-I-ati

s""'Y'les:

Sel'lIle.fC6P1-k x+t-i's-kl1el'

public

class

MyServletContextListener

implements

ServletContextListener event) de dados {

public

void

contextlnitialized(ServletContextEvent

l/cdigo para inicializar a conexo com o banco l/e armazen-la como um atributo do contexto

l.sf..
(J

iltS SI!l6 4,S j

'"

<f.Vft

u <ICe l'eceJ,e
{

m;VI4S

"'6

1,1" '" rIT1CtJ.t:.t'JeS

.J

v~ Sf!I'V1e.fC.L ~as eX"J,eJr; <lI1"1f': xrive ",Ipublic void contextDestroyed(ServletContextEvent para encerrar a conexo com o banco event) de dados l/cdigo

166 captulo 5

Tudo bem, eu tenho uma classe listener. O que eu fao agora? Onde a coloco? Quem a instancia? Como eu passo a aparecer nos eventos? Como o listener especifica o atributo no ServletContext correto?

EXERCITE SUA :MENTE


Qual o mecanismo que voc acha que usado para fazer com que um listener seja parte de uma aplicao especfica? Dica: como voc informa ao Container sobre outros trechos da sua aplicao? Onde o Container pode encontrar seu listener?

voc est

aqui..

151

usando um ServletContextListener

rufarial:

UtMServletCatttextListetler

sitMples

Agora ns iremos construir e executar um ServletContextListener. Trata-se de uma simples classe de teste, para que voc veja como todas as partes funcionam juntas. No iremos usar o exemplo da conexo com o banco de dados, pois voc precisaria configurar um para faz-Ia funcionar. Mas os passos so os mesmos, independentemente do cdigo que voc colocou nos mtodos de callback do listener. Neste exemplo, transformaremos um parmetro init String em um objeto real - um Dog. A tarefa do listener conseguir o parmetro init do contexto para a raa do co (Beagle, Poodle, etc.) e usar esta String para construir um objeto Dog. O listener insere o objeto Dog no atributo ServletContext, de forma que o servlet possa recuper-Io. A questo que agora o servlet tem acesso a um objeto compartilhado da aplicao (neste caso o Dog), sem precisar ler os parmetros do contexto. Se o objeto compartilhado um Dog ou uma conexo com o banco de dados, no importa. O importante usar os parmetros init para criar um nico objeto que todas as partes da aplicao compartilharo.

lJes.fe eJc(!~/{)J CfI/{)ctU"(!iI'I{)S ViI'I C., tl.f!I7.f.I' JtI! ViI'I

Sel'vle.fC~#1hx.f..

Nosso exemplo Dog:


O objeto listener pede ao objeto ServletContextEvent da aplicao. uma referncia para o ServletContext

O listener usa esta referncia para que o ServletContext consiga o parmetro init do contexto para "breed", que uma String que representa uma raa de co.

O listener usa a String da raa do co para construir um objeto Dog.

O listener usa a referncia para o ServletContext para configurar o atributo Dog no Serv letContext.

O servlet que faz o teste na aplicao recebe o objeto Dog do ServletContext e chama o mtodo getBreed().

168 captulo 5

atributos e liste"

Criat1do e usat1do o cotttext

Iistet1er

Talvez voc ainda esteja curioso para saber como o Container descobre e usa o listener ... Voc configura um listener da mesma forma que voc informa ao Container sobre o resto da sua aplicao - atravs do Deployment Descriptor web.xml!

fatl escutat 9sevent9S


Crie uma classe listener
<<interfaee> > ServletContextListener

SetVletC9ntext7 escteva uma classe l1stenel"

eontextlnitialized(ServletContextEvent) eontextDestroyed(ServletContextEvent)
Li"

'jpe lmplemente

Setvle:tC9ntextLlstenet. c919'Lue-an9 dltet9l"19 WEBt~classes e lnt9tme a9 C9ntllnel", c919clnd9 um


1 . element9

MyServletContextListener contextInitialized(ServletContextEvent) contextDestroyed(Serv letContextEvent)

< l::.'tenel">n9
10

Depl9)'ment

Descl"lpt9l".

e Coloque a classe em WEB-INF/classes


"'"'

/
'tljai" paN. 411deela p"de e flJifldel1+l'f! Jiflfll+as Ifl5tJ.l'es
1"1"

(Sff l1a6 e 6 uAJIC{) wf.I;-IAJFlcllA.sses

C"I1+atl1f.i" p60le pi"CflN.1'pe1u clfJ,sses.

ttl,lli,i"eJifl6S sobi"e as oleJifllJ.is PI" ctJ.p{+fllas6~re blS+i"l~flija)

Coloque um elemento <Iistener> no Deployment Descriptor web.xml


<listener> <listener-class> com.example. MyServletContextListener </listener-class> </listener>
UJifltJ. Pf!1'5f/11+tJ. plJ.r. Vct; e'Jifl 3f1e p(J,rff d@bb el1+ra if} elel'i';f!I1+6
<:.l" +e

fS ~l1ei". e I1f/Jifl e e'''''e <:sel'vle+> t>{,I s/~/esil'!e",ff aba/xi!


.l

>7

,,+.~

voc est

BUU!

169

tutoria I ServletContextUstener

Precisatltos

de trs classes

e Utlt 1111

Para o nosso teste com o listener de contexto, precisaremos escrever as classes e o arquivo web. xml. Para facilitar nosso teste, colocaremos todas as classes no mesmo pacote: eom.example <<interfaee> > ServletContextListener
.L:::,.

I I
I

O ServletContextListener

MyServletContextListener eontextlnitialized(ServletContextEvent) eontextDestroyed(ServletContextEvent)

MyServletContextListener.java
Esta classe implementa o ServletContextListener, recebe os parmetros init do contexto, cria o Dog e o configura como um atributo de contexto.

Dog

A classe atributo
Dog(string) getBreedO

Dog.java
A classe Dog simplesmente uma classe Java simples. Sua funo ser o valor do atributo que o ServletContextListener instancia e configura no ServletContext para alimentar o servlet.

<<interfaee> > ServletContextListener

O Servlet

GenericServlet

ListenerTester.java
Esta classe estende o HttpServlet. Sua funo verificar se o listener funcionou atravs do recebimento do atributo Dog oriundo do contexto, chamando o getBreedO no Doge exibindo o resultado para a resposta (portanto, isso que veremos no browser). HttpServlet

doGet(HttpServletRequest,HttpServletResponse)

170

atributos e listeners

Escrevetldo a classe listetter

<<interfaee> >

ServletContextListener Ela funciona como qualquer outro tipo de listener que 4'I I voc j deve estar familiarizado, como os tratadores de eventos GUl Swing. Lembre-se, tudo que precisamos MyServletContextListener fazer obter os parmetros init do contexto para descobrir a raa do co, criar o objeto Dog e coloc-lo eontextlnitialized(ServletContextEvent) dentro do contexto como atributo.
eontextDestroyed(ServletContextEvent)

paekage import publie

eom.example; javax.servlet.*;

IlI!iflelVle~.f4 4j4V4Jf.serv1e.f.Serv1e-!-C4"iex.f!-lsie'fer

~
elass MyServletContextListener implements ServletContextListener

publie

void

contextInitiali.zed

(ServletContextEvent

event)

( a

ServletContext

se = event. getServletContext

(); ~altclflA

Servle-!-Ca"ffJf+

IA"eve".f".
String dogBreed

= se.getlnitParameter("breed");~

Dog d = new Dog (dogBreed);<--

erl4 UIVI
'fava Da,;

US4" c()"iexfIJ par..efra I;'''.f

pfJ.NJ. IJbier iJi

.
se.setAttribute("dog", d),~

U.1'4a c()"ieX+a 1'41"4especilicfl.r UIVI 4.fribu.fa (UIVI 1'.1" "alVle!a!de.faJ Daj. A'jara; aufl"cs .fl"ect,cs JfI. 4pli"cfJ.j';asel"a CIAj>4jeS Je receber

a V4/al" Ja fl.fl"l6u.fa (iJiDiJij)


publie void contextDestroyed(ServletContextEvent event) (

Ii

nada

a fazer

aqui

lJ';fJ preciS41V1t;$ Je "fl.J4 fJ.3Ui. () DfJj ~()pl"ectsfJ. ser Illfl{>fJ 3UfJ.'fJfJ fJct>"ieJf.ffJ ierlVll;'a., slj'flli'cfJ. 3ue .ffJJ IAj>llc4jt> v4ll,;'alijfJ.I"J ,;'clt,,;'JfJ a

voc est aqui ~

171

o atributo c/ass

Escrevet1do a classe atributo (Uog)


Naturalmente, precisamos de uma classe Dog - a classe que representa o objeto que armazenaremos no ServletContext, depois de ler os parmetros init do contexto. Dog(string) getBreedO
package com.example;

Dog

public class Dog { private String breed;

Alada de especl'al 4~V". A-pel7fJ.S vltla classe Java sl"Ify>les

public

String

getBreed()

return

breed;

"" Al6SSI.i

Sfrvle-f. recebel": 6])65 d6

clurhJ6
111

V.])65

3Vf!"

Its-h:~r

C617115Vl"4 C61tl1.i a+l"tbv+~)

et.41t'>A1": 1"4j4 174

" ltl+ad65e-f.8I"eell!O

"6])65 e (;6f"4r:
I7D

resp'cs+a.,ftJ.1"4 3ve f6SS41t\6S v-/4

br6wser

f:

Eu achei que tivesse lido em algum lugar que os atributos do servlet tinham que ser Serializveis ...

1\:

Pergunta interessante. Existem vrios tipos diferentes de atributos e se o atributo tem que ser Serializvel s interessa aos atributos Session. E apenas quando a aplicao est distribuda em mais de uma JVM que ele realmente importante. Ns falaremos mais sobre isso no captulo das Sesses. No existe nenhuma necessidade tcnica para que qualquer atributo (incluindo os atributos Session) sejam Serializveis, embora voc possa considerar criar todos os seus atributos Serializveis por padro. A no ser que voc tenha uma boa razo para NO faz-Ia. Pense nisso: ser que voc est mesmo seguro de que ningum jamais vai querer usar aqueles objetos como argumentos ou retornar valores como parte de uma chamada remota a um mtodo? Voc pode mesmo garantir que algum que use esta classe (Oog, neste caso) nunca rodar em um ambiente distribudo? Ento, embora tornar os atributos serializveis no seja uma exigncia, voc deveria sempre que pudesse.

172 caoi'tu}o5

atributos

e lstenelS

Escrevet1do a classe servlet


Esta a classe que testa o ServletContextListener. Se estiver tudo funcionando corretamente no momento em que o mtodo doGetO do Servlet rodar pela primeira vez, o Dog ser esperado como um atributo no ServletContext.

HtipServlet

ListenerTester
doGet(HttpServletRequest,HttpServletResponse)

package import import import

com.example; javax.servlet.*; javax.servlet.http.*; java.io.*;

Ai."" "e especta/ a-# aJlIl ~el74S lI~ sel'v/el- C6/t1l1/t1


extends HttpServlet request, throws HttpServletResponse response) IOException, ServletException

public

class void

ListenerTester doGet

public

(HttpServletRequest

response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("test context attributes set by listener<br>");

out.println("<br>");

.
Dog dog = (Dog) getServletContext(} .getAttr1bute("dog"};~U

lr.,.lIt 6!rk~6s
/

6
d{J

7\

\:.. Ai';6 eSJlIf.ja 6 c:/CY/6f!


is: " + dog. getBreed ());

//65 a-l-n.vf.s
6

SeI'VIe+e6~J.

Se

out. println ("Dog' s breed

/ls+el7f,F' -IlII1Ci611(J(Jj

.p
Se 4'56 17';6-IlIl1t:l611IJYj 1r~IJI JlIe tif.SC6bl""'e~6S Vfl.~6S recebel' lI/tI el7tJrhle AillIlRs,irhl'xcerlt'1I7 65e-l-8reetiO se +e17-1-'U'hlfJS ct.ahllJ.l' l"Jel"Jf"y~ !J65

" !J65 VIJ.tes-l-al' alt


IrAirS allf. () ~+()ti() serv,i:e sr.;tl ct.a~tlti6 pe/fJ. pl'lm.etl"fI.ve;

e l"J6t.6wer

retorna_ precisa fazer a conversao . " O orna uma String. Ou seja, voce Mas o getInitParameter retd o ge tAttributeO ' mas o retorno t resposta S .do precisa conver er a 'budo diretamente a uma trmg. getlnitParameterO pode ser atrl 1 s cdigos escritos noS exames que portanto, no seja iludi~o por aque e no usam uma tA conversao: ~ "b t ("dog"l' '" Dog d = ctx.ge ttrl U e /' (Considere ctx como um ServletContext.)
t:

o getAttributeO

un;.~~~~:;~:~C

1I '('''fl.d6

voc est aqui

il>'

173

configurando um Iistener no DD

Escrevet1do O Peploytltettt Pescriptor


Agora, informamos ao Container que temos um listener para esta aplicao, usando o elemento <listener>. Este elemento simples - s precisa do nome da classe. S isso.
<web-app

-s-h "
es+tJ.

tU'SVt"l6

wd.J(~J !'IU'6.
deJ1+,..1J

4p'tca{;6)

d6

web.xml

dl"'e+:"'k~ w8-IAlF

xmlns=''http://java.sun.com/xml/ns/j2ee''

xmlns:xsi~''http://www.w3.org/2001/XMLSchema-instance'' xsi:schemaLocation=''http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

<servlet> <servlet-name>ListenerTester</servlet-name> <servlet-class>com.example.ListenerTester</servlet-class> </servlet>

<servlet-mapping> <servlet-name>ListenerTester</servlet-name> <url-pattern>/ListenTest.do</url-pattern> </servlet-mapping> <context-param> <param-name>breed</param-name> <param-value>Great </context-param> <listener> <listener-class> com.example.MyServletContextListener </listener-class> </listener> Dane</param-value> CIJJ1S+f'lIt,..

Pl"ecisa",,,s Je
dI> C6I'IffJ(.f6

i"'",'i1t.f '" li'" !,((NA"',"


Jele
plJ.f'tI.

!,41't1. ti. fJ.p'tCIJ.{;(J. p,..esfJ.

t>

lls.fe"e'"

6 b65

</web-app>

174 captulo 5

atributos

e lsteners

1'11'\.9

e:x1stem

YerhUntels dl9ttS

r:

Espera a... como voc est informando ao Container que isso um listener para os eventos do ServletContext? No parece ser um elemento XML para o <Iistener-type>, ou algo que diga para que tipo de evento serve este listener. Porm, eu percebi que voc tem um "Serv\etContextUstener" como parte do nome da classe. assim que o Container entende? Pelo nome?

1\: No.

No h nenhuma conveno de nomes. Ns s fizemos assim para tornar mais bvio o tipo de classe que criamos. O Container descobre ao inspecionar a classe e notar a presena da interface listener (ou interfaces; um listener pode implementar mais de uma interface listener).

r:

Isto significa que existem outros tipos de listeners na API servlet?

I\..: Sim,

existem vrios outros tipos de listeners que falaremos em um minuto.

voc est aqui ~

175

compilando e distribuindo

o lsterner test

COtMpile e

distribua
..;-

L.eirJJI'f;"'Sf',

rubfj 1;veperhl7j4

40

Vamos fazer tudo funcionar. Eis os passos:

(caA/4VItI CDltl a .rev welJspps fica 41;1./1 SIIfJ. fl':'1"ifi. es+ro.Jw.fJ.,,(e Jll'el-f.I'4sJ

o Compile as trs classes


Elas esto todas no mesmo pacote ...

If I'fi.") ffJ.1'fJ.es.fa tJ.p'tca{i/J. s-h Jtl'e.ff.I'It> Jeve es.f41'


Jei'1.f1'6 JE) Ji'l'e.ff.I'It> webpfs
P(lJ 1;/II'IC4+

e Crie uma nova aplicao no Tomcat


Crie um diretrio chamado listenerTest e coloque-o dentro do diretrio webapps do Tomcat. Crie um diretrio chamado WEB" INF e coloque-o dentro do diretrio listenerTest. Coloque o seu arquivo web.xml diretrio WEBINF.
nO

Crie um diretrio de classes dentro do WEB-INF. Crie uma estrutura de diretrios dentro das classes, que coincida com a estrutura do seu pacote: um diretrio chamado com, que contm o exemplo.

Copie seus trs arquivos compilados para dentro da estrutura de diretrios da sua aplicao no Tomcat
listenerTest/WEB-INF/classes/com/example/Dog.class listenerTest/WEB-INF/classeS/com/example/ListenerTester.class listenerTest/WEB-IN~/Classes/com/example/MyServletContextListener.class

e Coloque o seu Deployment Descriptor web.xml no diretrio WEB-INF desta aplicao.


listenerTest/WEB-IN~/web.xml

e
176

Distribua a aplicao, desligando e reiniciando o Tomcat.


5

atributos

e Iitlatf.

VatBOS experitBetttar
Abra seu browser e vamos direto ao servlet. Ns no nos incomodamos em fazer uma pgina HTML. Por isso, iremos acessar o servlet, digitando a URL do mapeamento servlet no DD (ListenTest.do).

A raa do co : Great Dane

rroubleshootit1g
Se voc receber um NullPointerException, voc no recebeu um Dog do getAttributeO. Verifique o nome da String usado no setAttributeO e certifique-se de que ele coincide com o nome da String que voc est usando no getAttributeO. Verifique novamente seu web.xml e tenha certeza de que o <listener> est registrado. Tente olhar nos logs do servidor para descobrir se o listener est mesmo sendo chamado. Para complicar o mximo possvel, ns atribumos nomes sutilmente diferentes. Queremos ter certeza de que voc est atento a como estes nomes so usados e quando dar a eles o mesmo nome. difcil dizer Como os nomes afetam sua aplicao. Nome da classe Servlet: ListenerTester.class Nome do diretrio da aplicao: IistenerTest URL padro mapeada para o servlet: ListenTest.do

voc est aQui ~

177

atributos de sesso

X segurana

contra threads

A histria cot\1pleta ...


Eis o cenrio desde o incio (inicializao da aplicao) at o final (o servlet rodando). Voc ver no passo 11 que resumimos a inicializao do servlet em um grande passo.

O Container l o Deployment Descriptor para esta aplicao, inclusive os elementos <Iistener> e <context-param>.

O Container cria um novo ServletContext, que todas as partes da aplicao compartilharo. new

web.xml

ServletContext

O Container cria um par de Strings nome/ valor para cada parmetro init do contexto. Suponha que tenhamos apenas um.

O Container d aos parmetros nome/valor as referncias do ServletContext.

new

O Container cria uma nova instncia da classe MyServletContextListener. new instncia de

00 Container chama o mtodo


contextInitializedO do listener, passando em um novo ServletContextEvent. O objeto de evento tem uma referncia para o ServletContext, ento o cdigo que trata o evento consegue obter o contexto atravs do evento e consegue obter o parmetro init do contexto atravs do contexto.
ServletCon extEvent

MyServletContextListener .c1ass

.,j,. contextlnitialized(ServletContextEvent)

listener

178 captuo.5

atributos e Iistens8

A histria cottlittua ..!

oo

listener solicita ao ServletContextEvent uma referncia para o ServletContext.

eo

listener

solicita ao ServletContext init do contexto "breed".

parmetro

r getServletContext~
Iistener ServletContextEvent

~ getInitParameter("breed")

O listener usa o parmetro init para construir um novo objeto Dog.

O listener configura o Dog como um atributo no ServletContext.

/new
listener instncia de Dog.c1ass listener

'"

_ setAttribute("dog",

d) -"" ServletContext

CD O Container cria um novo Servlet (isto


, cria um novo ServletConfig parmetros uma referncia com init, d ao ServletConfig para o ServletContext

O servlet recebe uma solicitao e pede ao ServletContext o atributo "dog".

set Attribute(" dog") Servlet ServletContext

e chama o mtodo initO do Servlet).

O servlet chama o getBreedO (e exibe-o no HttpResponse). getBreedO

no Dog

voc est aqui ~

179

outro Jisteners

Acabo de pensar numa coisa ... j que os atributos podem ser configurados atravs de um programa (ao contrrio dos parmetros init), eu posso escutar os eventos do atributo? Como se algum acrescentasse ou substitusse o Dog?

o o

Listeners: no s para os eventos do contexto ...


Onde existe um momento do ciclo de vida, geralmente existe um listener para escut-1o. Alm dos eventos do contexto, voc pode escutar eventos relacionados aos atributos do contexto, atributos e solicitaes do servlet, e sesses HTTP e atributos da sesso.

Com exceo do ServletContextListener, voc realmente no precisa memorizar os mtodos de cada interface do listener. Mas ... voc PRECISA conhecer os tipos de eventos que voc pode escutar.
Os objetivos do exame so claros: voc receber um cenrio (o trabalho de um desenvolvedor numa aplicao) e voc precisar decidir qual o tipo certo do listener, ou se POSSVEL ser notificado sobre esse evento do ciclo de vida.
.........................................

Voc no precisa saber: lu. toda a APllistener. :

N "'I'Ma

'ala."elfllas
#'ti

IV se./;rf, se,SSaf!S

I_!. f/.-n;:

P":XtIVl6 C4,{.f1l16) pal'-h.".fa


oA.

"

l"Ia se PI'f!6ClIpe
N

se lIace' 4'-1"It!41"14a sabe

a 3l1f! e lIIrIa

ses sa"

1f"'t1Pali par 3l1e IIIJc 1"1''-4 3l1f!I'e'1' sdel'

180

captulo 5

atributos

e lisrefUI

Escolha o listener

E'){etclc19S J o

Correlacione o cenrio da esquerda com a interface do listener (no final da pgina) que suporta tal objetivo. Use cada interface uma nica vez. (Sim, ns SABEMOS que ainda no vimos essas. Veja como voc consegue descobrir apenas olhando os nomes. As respostas comeam nesta mesma pgina, ento no olhe!)

Cenrio
Voc quer saber se um atributo em um contexto da aplicao foi adicionado, removido ou substitudo. Voc quer saber quantos usurios concorrentes existem. Em outras palavras, voc quer rastrear as sesses ativas. Voc quer saber todas as vezes que uma solicitao chegar, para ento poder log-Ias.

Interface do Listener

Voc quer saber se um atributo da solicitao foi adicionado, removido ou substitudo. Voc tem uma classe de atributo (uma classe para um objeto que ser colocado em um atributo) e voc quer que objetos deste tipo sejam notificados quando eles forem associados ou removidos de uma sesso. Voc quer saber quando um atributo de sesso foi acrescentado, removido ou substitudo.

Selecione as interfaces abaixo. Use cada listener apenas uma vez.


HttpSessionAttributeListener Serv2etRequestListener HttpSessionListener Serv2etRequeStAttributeListeoer

Ht~SessionBindingListener Serv2etContextAttributeListener

voc est aqui...

181

listeners mais comuns

Os oito listetters Cenrio


HHpSessI6'JA-HI'lI;II.f.e~ve~j. AIAI ~

Interface do Listener
~

Tipo de Evento
'l+p5es s,,,,,,/Jrch-IIaft,,,,,,f.lle,../fJ1f. I.f

m poe s

ServletContextAttributeEvent ServletContextEvent eontextInitialized ServletContextAttributeListener attributeAdded javax.serv sessionCreated leLhttp.HttpSessionListener HttpSessionEvent valueBound j avax. serv let. ServletContextListener sessionDidAetivate javax.servlet.ServletRequestListener ServletRequestEvent avax.servleL ServletRequestAttributeListener ServletRequestAttributeEvent javax.servlet.http.HttpSessionBindingListener HttpSessionBindingEvent j let.http.HttpSessionActivationListener servleLhttp .HttpSessionAttributeListener (vt,tJ+ pal'a javax.servlet. HHpSesstlJ"A-Hl'tl;u.f.eL,"s.f.e'JIU' requestlnitialized valueUnbound attributeRemoved sessionWillPassivate sessionDestroyed requestDestroyed Voc quer saber se um atributo attributeReplaeed () e sobre IJ ;jlle vce espera (vce espera 1IJ>1 AJ-o eu/,/a" t'JC'JSI"s.f.e"'"lCl"a "e 'JJ>les!() forem uma sesso. associados ou removidos de es-l-a captulo.) detalhes sesses no prximo sejam notificados quando eles CJ>l eontextDestroyed attributeReplaeed Voc quer saber quando Voc quer saber todas as vezes

oto to ios

182 captulo 5

atributos

e liStel'lelS

o HttpSessiot1Jit1dit'gUstet1er
Voc pode estar confuso sobre a diferena entre um HttpSessionBindingListener e um HttpSessionAttributeListener. (Bem, no voc, mas algum que trabalha contigo.) Um HttpSessionAttributeListener simples apenas uma classe que quer saber onde qualquer tipo de atributo foi acrescentado, removido ou substitudo em uma Sesso. Mas oHttpSessionBindingListener existe para que o atributo em si possa descobrir quando ele foi adicionado ou removido de uma Sesso.
package import com.example; javax.servlet.http.*; HttpSessionBindingListener

public class Dog implements private String breed; public Dog(String breedJ this.breed~breed;

public String getBreed() return breed;

public void cdigo

Ii
Ii

valueBound(HttpSessionBindingEvent event) { para rodar agora que eu sei que estou em uma

sesso

public void cdigo sesso


}

valueUnbound(HttpSessionBindingEvent event) { para rodar agora que eu sei que eu no fao mais

//

nparte /I

de uma

les v/-;/tu", para n J a patavNJ. n nba(l"" e v"lIl:Iv,," n tltjer atllclimaila e re"'l:IvtiJa"e .


&li

f:

Tudo bem, eu entendi como funciona. Eu entendi que o 009 (um atributo que ser adicionado sesso) quer saber quando ele est dentro ou fora de uma sesso. O que no entendi POR QUE.

I\:

Se voc sabe algo sobre Entity beans ... ento pode imaginar esta capacidade como um "entity bean dos pobres". Se voc no conhece os entity beans, voc deveria correr para a livraria mais prxima e comprar dois exemplares do livro Use a Cabea! EJB (um para voc e outro para o seu amor, para que compartilhem momentos especiais discutindo sobre isso). Por enquanto, eis uma forma de pensar sobre isso: imagine que o Oog uma classe Cliente

com cada instncia ativa representando as informaes - de nome, endereo, pedido, etc. de cada cliente. A informao real armazenada em um determinado banco de dados. Voc usa as informaes do banco de dados para preencher os campos do objeto Cliente, mas a questo como e quando voc mantm o registro do banco de dados sincronizado comai( informao do Cliente? Voc sabe que sempre que um objeto Cliente for adicionado sesso. hora de atualizar os campos do Cliente nos registros do banco de dados, com os dados deste cliente. Ento, o mtodo valueBoundO como um gatilho que diz: "Carregue-me com dados recentes do banco de dados ... s para garantir; caso algo tenha mudado desde a ltima vez. que fui utilizado." Por sua vez, o valueUnboundO diz: "Atualize o banco de dados com os valores dos campos do objeto Cliente."

voc est aqui..

183

talela do lstener

Relembrando os listeners
Faa o possvel para preencher os espaos na tabela abaixo. Tenha em mente que as interfaces do listener e os mtodos seguem um padro consistente de nomes (a maioria). As respostas esto no final do captulo.

Listeners de Atributos

Outros listeners do ciclo de vida

Mtodos em todos os listeners de atributos (exceto binding listener)

Eventos do ciclo de vida relacionados s sesses (exceto eventos relacionados aos atributos) Eventos do ciclo de vida relacionados s solicitaes (exceto eventos relacionados aos atributos) Eventos do ciclo de vida relacionados ao contexto do servlet (exceto eventos relacionados aos atributos)

184

atributos

e listeners

o que l de fatol

UtM

atributo?

Ns vimos como o listener ServletContext criou o objeto Dog (depois de conseguir o parmetro init do contexto) e foi capaz de inserir (configurar) o Dog no ServletContext como um atributo, de for que as outras partes da aplicao pudessem ter acesso a ele. Antes disso, com o exemplo da cerv ns vimos como o servlet foi capaz de inserir os resultados da chamada para o modelo no objeto (geralmente o HttpServletRequest) da Solicita( como um atributo (para que o JSP/view pudesse conseguir o valor). Um atributo um objeto configurado (denominado bound) em um dos trs outros objetos daAPI servlet - ServletContext, HttpServletRequest (ou ServletRequest) e HttpSession. Voc pode consider-Io simplesmente um par nome/valor (onde o nome uma String e o valor um Objeto) el uma varivel da instncia do mapeamento. Na verda ns no sabemos - e nem nos importa - como isto implementado de verdade. Tudo que nos preocupa escopo no qual o atributo existe. Em outras palavras, quem pode v-Io e por quanto tempo ele vive.

5/lJehl ptJtle ver esh 3lJa.tlf"6tle tl.yi'slJs? 5/lJthl patle receber

e c411/ljvra.r 6S lI.+rl!;lJ+6s?

Um

C9m9

um

9bjet9 ptes9 em um 'Luadt9 de AJ,bum 9 atlx9u n9 'Luadt9 pata 'Lue 9utt9S p9sslm pe,b~19 As ,btandes petb'unt{l,')s9: 'Luem tem ae(~S5,9 a9 'Luadl"9 de aV1595e 'Lulnt9temp9 ele petmaneee

l? Em 9utl"aS

pahtvtas, 'LuQ1 9 e5C9p9 d9 ttl"lbut9?

voc est aqui..

185

atributos

X parmetros

Os atributos t1o so parlfletros!


Se voc um iniciante em servlets, talvez precise de mais tempo reforando as diferenas entre atributos e parmetros. Mas saiba que quando elaboramos a prova, ns gastamos um pouquinho mais de tempo para garantir que as questes que se referem a atributos e parmetros sejam as mais confusas possveis. *

Atributos
Tipos Application/context Request Session AJ';IJ

Parmetros
Application/parmetros init do contexto Parmetros da solicitao Parmetros init do servlet AJ';IJ exi'sffltl da ses s'iIJ/ Voc NO PODE configurar os parmetros init da Application e do Servlet - eles so configurados no DD, lembra? (Com os parmetros da Solicitao, voc pode ajustar a query String, mas diferente.) fal"M.,e+I"lJs

1.: "If!."IJ.lIIVta+I""/;lI+IJ
para
(J

espec{ltclJ

sel"vle+

(/;as+o. lIsal" lIIVtIJ. val",-:'ve.l da

I~S+V,Ct()
Mtodo para configurao setAttribute(nome da String, valor do Objeto)

Tipo de retorno

Objeto

String ~ bl'fJ."Ide dtlel"e"ljfJ.!

Mtodo para obteno

ServletContext.getAtribute se eSJlIega

(String name) IJS cIJ"IlIel"-f-,(Jl)sJ

ServletContext.getAttribyte(String

name)

de 3ve

develtl ser

dIJ I"e+IJI""IIJ

0fJe.+1)

* verdade. Se ns fizssemos uma prova simples e objetiva, voc no teria aquele orgulho e a sensao de realizao ao ser aprovado. Fazer um exame dificil o suficiente para garantir que voc precisaria comprar um guia de estudo para passar na prova nunca, EM ALGUM MOMENTO, passou pela nossa cabea. No mesmo. Ns s estvamos pensando em voc.

186

captulo 5

atributos

e listeners

Os rrs Escopos: Cotttextol Solicitao e Sesso Atributos do Contexto

set

Context Listener

JSP

Atributos de Sesso

servlet

Acessvel apenas para aqueles com acesso a um HttpSession

especfico

Atributos de SOLICITAO

set

get

Acessvel apenas para aqueles com acesso a um ServletRequest

especfico

voc est

187

escopo atributos - exercicios

Escopo Atributo
Faa o melhor possvel para preencher os espaos nesta tabela. Voc REALMENTE tem que entender o escopo atributo para o exame (e para o mundo real), porque voc tem que saber qual escopo a melhor opo para um determinado cenrio. A resposta encontra-se algumas pginas frente, mas no vale olhar! Se voc vai fazer o exame, confie em ns ... voc deve fazer o exerccio sozinho, com o tempo necessrio para pensar nas questes.

B')(etclc195 ~o

Acessibilidade
(quem pode ver)

Escopo
(por quanto tempo vive)

Para que serve

Contexto

HttpSession

Solicitao

(Ai6+ti.: vac deve levar

e"", cMstdertJ.{ilJ

4S i"lly>lic4f6es dI), c61e+4 a+ribll+as 1"I'i1J

de 11"/(6 3ua"td6 1I6c pe"tsfl.r serlJ ct:Jle+fJ.das AilJ

e"", esclJplJ alju"ts

a#

311e IlpllctJ.{ilJ S~fI. deslJ..ftvada fl'~e+t:J

<fJU /III(;I'+ti..

t.: PIlAdaPlIJeXIAJIleslJbre

ct:JJIl jerf!Plci'"4J1lePl+1Jde

, L_ .. /IIIeJll6rl e/lll JIlePl"n:; JIl4S IIlJce deve se pl'ecaver)

188 capitulo 5

atributos e lsteners

A API Atributo
Os trs escopos do atributo - contexto, solicitao e sesso - so tratados pelas interfaces ServletContext, ServletRequest e HttpSession. Os mtodos da API para atributos so exatamente os mesmos em cada interface. Object getAttribute(nome setAttribute(nome removeAttribute(nome da String)

da String, valor do Objeto) da String)

Enumeration getAttributeNamesO

Contexto
<<inteifaee> > ServletContext getInitParameter(String) getInitParameterNamesO getAttribute(String) setAttribute(String, Object) removeAttribute(String) getAttributeNamesO getMajor VersionO getServerInfoO getReaIPath(String) getResoureeAsStream(String) getRequestDispateher(String) log(String) Ii MUITOS outros mtodos ...

Requerimento
<<inteifaee> > ServletReq uest getContextTypeO getP arameter(String) getAttribute(String) setAttribute(String, Object) removeAttribute(String) getAttributeNamesO Ii MUITOS outros mtodos ...

Sesso
interfaee>> HttpSession getAttribute(String) setAttribute(String, Object) removeAttribute(String) getAttributeNamesO setMaxInaetivelntervalO getIDO getLastAeeessedTimeO Ii MUITOS outros mtodos ...

<<inteifaee> > HttpServletRequest getContextPathO getCookiesO getHeader(String) getQueryStringO getSessionO Ii MUITOS outros mtodos ...

voc est aqui..

189

attribute Sln'1ngieni9sS

o lado

negro dos atributos ...

Kim decide testar os atributos. Ele configura um atributo e, imediatamente, recebe o valor do atributo e o mostra na resposta. Seu doGetO se parece com o seguinte:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException

response.setContentType(~text/html"); PrintWriter out ~ response.getWriter(); out.println(~test context attributes<br>")"; ~22"); ~42");

getServletContext() .setAttribute(~foo", getServletContext () .setAttribute (~bar", out.println (getServletContext out.println(getServletContext()

() .getAttribute(~foo")); .getAttribute(~bar"));

Eis o que ele v na primeira vez que o executa. exatamente o que ele esperava.

teste os atributos do contexto


22 42

xa+a""e-rl-e"

Sve espera"""s".

190 captulo 5

atributos

e lsterlefJi

Mas algo d terrivelmente

errado ...

Na segunda vez que ele executa o comando, ele se choca ao ver:

teste os atributos do contexto

22 16

I\--. C"Ift" .SS/} p"l"cp.l"laac""./-ecev??? be ""t/e Vf!.16 esse 7(? Cai " 2?

ti

EXERCITE SUA MENTE


Observe o cdigo atentamente e imagine o que est acontecendo. Voc saberia explicar onde est o problema? Voc pode no ter informaes suficientes para solucionar o problema, por isso aqui vai outra dica: Kim colocou este cdigo em um servlet de teste que parte de uma aplicao teste bem maior. Ou seja, o servlet que possui o mtodo doGetO foi distribudo como parte de uma grande aplicao. Agora voc consegue descobrir? Voc saberia como ele poderia resolver isso?

voc est

aqui.

191

escopo do contexto

e thread-safe

o escopo do comexto

. o thread-safe!

Esse o problema. Lembre-se, todos na aplicao tm acesso aos atributos do contexto, e isso significa vrios servlets. E vrios servlets significam que voc pode ter vrias threads, j que as solicitaes esto sendo tratadas ao mesmo tempo, cada uma em uma thread separada. Isto acontece independentemente das solicitaes estarem chegando para o mesmo servlet, ou no.

~ I
pa! OU+i"
sei"lIle+ +t.i"ffJ.4If Sff4i"441f4, ."
Client C

~Uf h,'j f'fJ.i"+e

4Iftl. h\es.."a t<pllc4f4(J; i"4lfal'l4lfoe.." 1Ih\1J.

".. f>c4IfecCl'lli;:;Vi"{J.i" " <:l

~
i'sS<:l

.l-d!Ju+.

!J__ .
tJ

~4(J +v4IftJ tJ C(J~+llt~ei" p,,4Ife Sei"vle+ I-r; clrel'l-h

CJli"i"f54i" tJV.f.I"fJ.+t.l"eb.4If pll1"4 4 I'fII 4Ifea+e~4Ifel" v.." +el"celNJ

192 captulo 5

atributos

e listeners

o probletMa

etM etMera Iettta. ..

Eis o que aconteceu com o servlet de teste do Kim.

00 servlet A configura o atributo do contexto "foo" com o valor "22".

80 servlet A configura o atributo do contexto "bar" com o valor"42".


_set~

Thread A
String

Thread A
String

A thread B torna-se a thread que est sendo executada (a thread A retorna ao estado de Executvel-mas-noExecutando) e configura o atributo do contexto "bar" com o valor "16". (O 42 agora j era.)

A thread A torna-se a thread que est sendo executada novamente e recebe o valor de "bar", copiando-o na resposta.

_set~
Thread B
Strng

Thread A
String

;r/--re as e+~~s servle+ le ~ :,,,)


fJr

e""

ti

ctI"lij//I"IA ti V4/tlr

bar e ti rec//pera,; 1)//+1"4


e'" eiJ'l+r4 c,,'" //'"

getServletContext ().setAttribute ("foo", getServletContext() .setAttribute("bar",

"42")'

"22");

JI) servle+ ( -H.reu.J 4j'" e CIJ"lijUI"IA


\ ,_

.
out .prlntln (getServletContext out.println(getServletContext()

() .getAttribute("bar"; .getAttrlbute ( foo

lia/ti: Jilere"ff. );\l. ,,-fu.a Juf.//4"1JtI ti servlel""uJaJtI para

A I

extbe " lia/til" Je b4r,) e1ej./M

7t.

voc est aqui...

193

threads

e atributos

do contexto

Cot\to tomat\tos

OS

atributos do
CLARO que eles no sincronizaram os mtodos no ServletContext. Puxa ... Isto significaria que toda chamada para obter e configurar um atributo receberia toda a sobrecarga da sincronizao. Que grande desperdcio seria se voc no fosse precisar disso. No, proteger os atributos problema SEU ... no espere que a API ir ajud-Io. (Eu no posso acreditar que ela chegou a sugerir isto.)
C>

contexto thread-safe?
Vamos ouvir o que alguns desenvolvedores tm a dizer ...

Eu estou pensando que eu podia sincronizar o mtodo doGetO, mas isso no parece mesmo certo. Mas eu no sei mais o que fazer.

() o

194 cao!'tulo5

atributos e 1istenf8

Sittcrottizar o lIttodo de servio ullta PtSSIMA idia


Tudo bem, ento j sabemos que sincronizar o mtodo de servio vai detonar a nossa capacidade de processo simultneo, mas proteger a thread, certo? D uma olhada neste cdigo legtimo e verifique se ele evitaria o problema que o Kim teve com o atributo do contexto sendo trocado por outro servlet ...
public synchronized response) void doGet(HttpServletRequest throws response.setContentType(~text/html"); PrintWriter out ~ response.getWriter(); out.println(~test getServletContext() getServletContext() context attributes<br>"); ~22"); ~42"); request, HttpServletResponse ServletException

IOException,

.setAttribute(~foo", .setAttribute(~bar",

out.println (getServletContext out.println(getServletContext()

() .getAttribute(~foo"); .getAttribute(~bar");

o ave IItlc Qct.a?


,

IS+6 (I !>t'c!;leifltJ. dtJ ctl"stt'itJ.t': k;,"",,? c!;serlle "tJvQifltPrf-e c C(ldijtl

t 0.$ fijVt'4S)

CiJ,Sc"ac

-fe"t.a ctt'iejtJ..

voc est aqu

195

no sincronizar

o mtodo de servio

Sittcrottizar

tlttodo de servio tto

proteger Utltatributo do cotttexto!


Sincronizar o mtodo de servio significa que apenas uma thread de cada vez em uma classe do servlet pode estar rodando ... mas isto no impede outros servlets ou JSPs de acessarem um atributo! Sincronizar o mtodo de servio impediria outras threads do mesmo servlet de acessar os atributos do contexto, mas isto no far qualquer coisa para interromper um servlet completamente diferente.

X4.as lI<)ceI1tMlaNJ. #7aJaplv'a i'~eJi'1' tliS ()l.rr/t.O.5 sel'lIle.fs! I"Jepei"/Jel1ffll\tewH! J.

~,

",.-!-cJtlJs /tesel'lIlf" e~ tlJv.fI'IJS sel'vle-!-s eS-!-41 Client C SlI1CI'l:iI1i'~4JtJS t'Jl/ /i'$Sl:ijfJl/-!-l'tJs fl'ect.t!Js
..J(!

c..... V6ce

Si'#7Cl'tlJl1i'-;4r tJ ~e-rtJJ/J /e sel'vljtIJJ jltlJce


i/J

/J

..

Ir: IlI4.PfbI/t. tJf.I.fl'/J ~fl..i/J/tJ d.eJQl'ell\ tl.t!J sf!l'vle.f

Ci/Ji"/.ftl.I""el' I.."tele 3f.1t.t13l/er A-. PaI'.ft1.n.foJ I"$.f/J IJe.AJ6 c<)nffx.f<) Je sel'eW\

N fi:"" /";:0 tl.pIl'CtJ.j4fJ il,ces SfJ tl.fJ~ /{J ctJl1ffxf. afl'lbl/.fas

as i"//JjlU' stJltcl.f/lg';es 3l/E;

pl'<)feJel' 6S QcessQ,<)s P0l' W\Q,t"$ Je

f.I~4 ft.l'flJ. 1'<)4"'1016 6 "".f6J de sel'lItj" Sel'vle.f A-.

016

196

captulo 5

atributos e isteners

Voc MO precisa de UIM loek .,0 servlet ... Voc precisa do loek .,0 ootttexto!
A maneira tpica para proteger o atributo do contexto sincronizar NO prprio objeto contexto. Se todos que acessarem o contexto tiverem que primeiro receber o lock no objeto contexto, voc ter garantido que apenas uma thread por vez possa estar obtendo ou configurando o atributo do contexto. Mas ... ainda existe um se a. S funciona se todos os outros cdigos que manipulam os mesmos atributos do contexto TAMBM sincronizarem no ServletContext. Se o cdigo no solicitar o lock, ele ainda livre para alcanar os atributos do contexto. Mas se voc est projetando a aplicao, ento voc pode decidir fazer com que todos solicitem o lock antes de acessarem os atributos.
public void doGet(HttpServletRequest

Pt4l'a tJS a.frlbfrl-tJs

C417+ex.fa; 174av.,. .l.".f41' "t1.4 si"I7C1'4"lj4r p6is tJlI.fI'U

"4 SerlllffJ
4

pfJ.rffS

4p/'CfJ.jQtJ4''"114 ser44 c4p.jes e aces SI'U' " C4,,-fex+4!

request, HttpServletResponse response) throws IOException, ServletException (

response.setContentType("text/htrnl"); PrintWriter out = response.getWriter(); out.println("test context attributes<br>");

Ajara es.fa"'4s I"ecde,,a a 14CI: '''ffa da CM-hx+4!! 1..s+fJ. a "'4I7el"4

de pl"iJ-hjel'
a
1746ller

synchronized (getServletContext ( { getServletContext() .setAttribute("fo(~


getServletContext () .setAttribute out.println(getServletContext() out.println (getServletContext

~"es.faa
"42");

6
C6,,-hX.f4.

a+l"lbll+a ~ ".

("bar",

~ce

.getAttribute("foo)JJ; J _ S.e."C/,,1"417"'f.e( +/,,;-S)) () .getAttribute("bar";

J: 3ve -hJf1CS C IIJcl: dIJ cl"hx+c; es+aJf1S ca"sfiJerlll76 3ve lI"'tl Vej
e 6v-/-l'aS -/-/"I"f!!as a#

lle

"a bl6C4 SIi1CI"617lia,,; IJS e"+l'e"'4S 1J.-/-"i"bV-i-4S6 CM-hx+" esl-al"Qa safo"as


Vf!!S13.I"'al!Vlas da 1;14c6 II lf'I(Jf$ aV 1f'If!!"6S. Sall/as I $lof"11lc4 v $1.l1/1Jle IJlJ.lvel" aV+1"6 C6ij6 ve rAM.$z./Lt IaS. sPlcl'a""ja{(J Sf!!l"lIle-/-Cal7-hJc+ 176

Aguarde para ver muitos cdigos sobre segurana contra threads


No exame, voc ver vrios cdigos mostrando estratgias diferentes para criar atributos thread-safe. Voc ter que descobrir se o cdigo funciona, dado um determinado objetivo. O fato de o cdigo ser legtimo (compila e roda) no significa que resolver o problema.

J'VI.as es-rfJ. e a lf'Ielt.fJr IJPSIlIJIJe I/fJce vai C(J"Sf!!iV'" pal"lJ. +IJI'''o.l'' as o.:.J.l"lbv+IJS 6 CIJ,,-hx-/- +t.reo.d- sale.

li 4

I. I

IV

voc est aqui ~

197

atributos de sesso

e thread-safety

Os atributos de Sesso so thread-safe?


Pense um pouco. Ainda no falamos sobre as sesses HTTP em detalhes (falaremos no captulo Sesses), mas voc j sabe que uma sesso um objeto usado para manter o estado de conversao com um cliente. A sesso persiste por vrias solicitaes do mesmo cliente. Mas ainda estamos nos referindo a um nico cliente. Mas se um cliente - e um nico cliente s pode pertencer a uma solicitao por vez -, isso automaticamente j no significa que as sesses sejam thread-safe? Ou seja, mesmo que vrios servlets estejam envolvidos, seja qual for o momento, s haver uma solicitao de cada cliente ... ento, apenas uma thread estar rodando naquela sesso. Certo?

get

JSP View

Slicl-l-"'j!"

n.f'~o.tl8

Servlet B

Embora ambos os servlets possam acessar os atributos da Sesso em threads separadas, cada thread pertence a uma nica solicitao. Ento, parece seguro. A no ser que ... Voc seria capaz de pensar numa situao em que poderia existir mais de uma solicitao, no mesmo momento, do mesmo cliente? O que voc acha? Os atributos de sesso so threadsafe mesmo?

198 capitulo 5

atributos

e lsteners

o que REAlMENrE verdade sobre os atributos e a segura.,a comra threads?

Preste ateno em como.os nossos dois faixas-pretas discutem as questes sobre como proteger o estado dos atributos contra os problemas de multi-threading .

;. f,
Ji' :%,~-<

.
~~ ~

"l i j~;;o

Ns sabemos que os atributos de contexto NO so seguros por natureza, pois todos os trechos da aplicao podem acessar os atributos de contexto a partir de qualquer solicitao (leia-se, qualquer thread).

Sim, mestre. E eu sei que sincronizar o mtodo de servio no a soluo, pois embora evite que o servlet sirva a mais de uma solicitao por vez, ele NO ir impedir que outros servlets e JSPs na mesma aplicao acessem o contexto.

Muito bom. E sobre os atributos de Sesso. Eles so seguros?

Sim, mestre. Eles servem para apenas um cliente e as leis da fisica evitam que um cliente faa mais de uma solicitao por vez.

Voc tem muito o que aprender, gafanhoto. Voc no conhece a verdade sobre os atributos de sesso. Medite sobre isto antes de perguntar novamente.

Mas mestre, eu tenho meditado e ainda no sei como o cliente poderia ter mais de uma solicitao ...

Voc deve pensar alm do Container. Use a criatividade. Arrisque-se. Muito sbio conselho, mestre! Eu entendi! O cliente poderia abrir uma nova janela no browser! Ento o Container ainda poder usar a mesma sesso, embora venha de uma instncia diferente do browser? Sim! O Container pode ver a solicitao da segunda janela como se viesse da mesma sesso. Logo, os atributos de Sesso no so thread-safe e eles tambm devem ser protegidos. Meditarei sobre esta questo ... E como voc protege estes atributos de sesso contra o caos de vrias threads? timo! Sim, mas sincronizar o qu? Ah ... Eu devo sincronizar a parte do meu cdigo que acessa os atributos de sesso. Do mesmo jeito que fizemos para os atributos de contexto. Eu devo sincronizar o HttpSession!

voc est

sincronizar na sesso

Proteja os atributos de sesso si.,crot'tiza.,do o HttpSessio.,


Observe a tcnica que usamos para proteger os atributos de contexto. O que ns fizemos? Voc pode fazer a mesma coisa com os atributos de sesso, sincronizando o objeto HttpSession!
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

response.setContentType(~text/html") ; PrintWriter out = response.getWriter(); out.println(~test context attributes<br>"); HttpSession session = request.getSession();

lJes+a

ve")) It':s sl"ncI"IJltt")alYoas

;t)

al(je+a

synchronized(session)
session.setAttribute(~foo",

{
~22n);

session.setAttribute(~bar", ~42");
out.println(session.getAttribute(~foo"; out.println(session.getAttribute(~bar"

H#pses Si6ltJ PfJ.1"4 PI"()+e5el" 6S tJ.+d!JV+6S oie sess6

Nil9 ex1st~m

feth'untls

ld'9tas

r:

Isto no seria um desperdcio? Seria, de fato, possvel... que o cliente abrisse uma nova janela no browser?

r:

No ruim sincronizar cdigo, j que causaria muito overhead e afetaria o processamento simultneo?

1\: Claro que sim. Certamente,

voc mesmo j o fez sem pensar duas vezes - abriu uma segunda

1\: Voc deve SEMPRE

janela porque estava cansado de esperar pela resposta da outra, ou porque voc minimizou uma, ou colocou a janela em lugar errado sem perceber, etc. O fato que voc no pode arriscar quando precisar de segurana contra threads para as suas variveis de sesso. Voc tem que saber que perfeitamente possvel para um atributo do escopo sesso ser usado por mais de uma thread em um determinado momento.

pensar com cuidado antes de sincronizar qualquer cdigo, pois voc est certo - ocorrer algum acrscimo no controle, na aquisio e na liberao de locks. Se voc precisa de proteo, use o sincronismo, mas lembre-se da regra-padro para o uso de locks: mantenha o lock o menor tempo possvel para concluir sua tarefa! Em outras palavras, no sincronize aquele cdigo que no ir acessar o estado protegido. Faa com que seu bloco sincronizado seja o menor possivel. Consiga o lock, entre, obtenha o que for preciso e saia para que o lock possa ser liberado e outras threads possam rodar o cdigo.

200

captulo 5

Sit1gleThreadModel desigt1ado a proteger as variveis de it1stt1cia


Stv strvle.f tieve esfe"tier "

isto que a especificao do servlet diz sobre a interface H-rrPServlef f.'-sa parfe prl;,etpQI
SingleThreadModel (ou STM): ~ ter a garantia de que dois encadeamentos no HTTPServlet {fromjavax.servlet} interface SingleThreadMode, Assegura que os servlets lidem apenas MyServlet sero executados simultaneamente no mtodo de servico do servlet. O continer servlet cada nova solicitao a um servlet livre. um servlet implementar essa interface, voca pool de instncias do servlet e do enviando pode assegurar isso sincronizando o acesso

do

"'-

\.

~.""Ifl.jServle+

'''Y''e*lf"ftJ.

;) SrM.J a

!.~ Ctl""'T"l:/;,er dIA

Wtb

i'raI

Mas COlMO o cOt1tit1erda Web assegura que o servlet obter apet1as UIMa solicitao de cada vez?

ti.sstjvrar

ave esfe sf!rvlef


Ittlo,;' C"*1
Ch.dfl.

fe"t.fJ, ape"fJ,s alie


lI*ll st:./lci'ftJ.jl!Jtie

vejo

O revende dor do continer da Web tem uma opo. O continer pode manter um nico servlet, mas colocar em fila cada solicitao e processar uma solicitao completamente antes de permitir que a prxima solicitao prossiga. Ou o continer pode criar um pool de instncias do servlet e processar cada solicitao simultaneamente, um por instncia do servlet. Qual estratgia STM voc acha ser melhor? Coloque em fila todas as solicitaes

Ettvie solicifa9es atravs de

UtM

pool

.. e <l c<l,,~"'el' da

Wd f."fl'f!5fraS
(/*la

I.l

Request 1

,"'sf~Clf4."(j

Re uestl

C.a"4I'f.&vesf
a"i';:'-<:>"I4"fI

. ",,'2

~ 11IfI.

Request 2

k;-.}~"'"'" 3
c.tJ."as(JI,CI'fagI<:>
1I1J,i'

//

p41"tJ.

v~a l"'sf~ci'tJ. sepal"fJ.da Ja ~es~tJ sel"vlef voc est

request queueing ou serviet poofing

Qual

Ittelhor ilttplelttetttao

SfM1

Mais uma vez, devemos consultar nossos mestres. Os caras devem saber qual a melhor implementao STM. Iremos v-Ios lutando para tomar uma deciso ...

Coloque e'ft fila todas as solicitaes Colocar em fila as solicitaes em um nico servlet faz mais sentido. Implementa claramente o que os escritores da especificao pretendiam.

Ettvie as solicitaes

atravs de U'ft pool

Mas mestre, o desempenho no sofrer um impacto? Certamente, colocar em fila cada solicitao impedir que diversos usurios tenham acesso ao mesmo servlet? Sim, mas o nico modo de proteger as variveis de instncia do servlet. Mas mestre, o continer tambm pode criar um pool de instncias do servlet. Ento, o continer pode processar uma solicitao com uma instncia do servlet e outra solicitao com uma segunda instncia. Cada solicitao lidada paralelamente. Ah, voc v profundamente no biscoito da sorte, meu aluno, mas no v como poderia ser perigosa essa sorte ... Voc fala por charadas, mestre. O que poderia dar errado, possivelmente, com a estratgia do pool? A especificao do servlet define que uma nica declarao do servlet no descritor de distribuio toma-se uma nica instncia do objeto durante a execuo, mas agora usando a interface STM, essa definio no mais vlida. Voc pode imaginar uma situao onde ter diversas instncias do servlet falha? Hmm, e se uma das variveis de instncia for para registrar quantas solicitaes foram processadas. A varivel do contador teria diversas contagens diferentes e nenhuma delas seria correta ... apenas sua soma seria correta. SIM! Voc entrou profundamente no ardil que o pool de servlets. A semntica da definio de "uma instncia do servlet" perdida. O servlet perdeu a noo de realidade. 202 captulo 5

atributos

retgunttS
r:

l'li'l9 exlst~m

Id'i9ttS
Por que a especificao do

Qual o problema? servlet to inspida?

.........................

1\: Os escritores
revendedores

da especificao queriam dar aos : do continer a oportunidade de competirem: e flexibilidade.

Voc no precisa conheceras estratgias STM de continer para o exame.

entre si em termos de desempenho

r: r:

. b o SrM tenta protegI S preclsa sa er que 1 :as vanav ., eis da instncia do serv et.

Como sei qual estratgia

meu revendedor

usa?

1\: Bem, felizmente

est escrito em alguma parte da documentao para o continer da Web. Se no, voc deve encontrar em contato com ele e perguntar.

Como a estratgia

STM mudar como escrevo

o cdigo

de meu servlet?

1\: Se o continer usar uma estratgia de fila, ento, a semntica de "uma instncia
do servlet" ainda existir e voc. no precisar fazer nenhuma mudana no cdigo. Mas se o continer usar uma estratgia de. pool, ento, a semntica de algumas variveis de instncia poder mudar. Por exemplo, se voc tiver uma varivel de instncia que mantm um "contador de solicitaes", ento, essa varivel no poder mais ser contada quando diversas instncias do servlet forem criadas no pool. Neste caso, voc poder escolher tomar a varivel do contador uma varivel de classe.

Y: Mas as variveis
seguro?

da classe tm um encadeamento

1\: No, no tm e o mecanismo

STM no ajuda com as variveis da classe. Sim, ele protege as variveis de instncia contra o acesso simultneo, mas colocando no pool as diversas instncias, a semntica do servlet muda. E mais, o STM no ajuda com os outros escopos da varivel ou do atributo. Voc est sozinho ...

r:

Marque com um X as opes que NO so thread-safe. (Nos fizemos a primeira.) ~ Atributos Atributos Atributos Variveis do escopo contexto do escopo sesso do escopo solicitao de instncia no servlet

bom usar o SingleThreadModel?

1\: No, realmente.


desaprovado

por isso que o STM foi na API do servlet! "'" M.a.s lIac .iiul4 preCiSo.
saber pfJ.ra

D D D
D

Variveis locais nos mtodos de servio Variveis estticas no servlet

eXfJ.iJ'Ie.

voc est aoui .

21

atributos request so thread-safe

Apenas os atributos da Solicita~oe as variveis locais so thread-safe!


E pronto! (Ns inclumos os parmetros do mtodo quando dizemos "variveis locais".) Todo o resto est sujeito manipulao por vrias threads, a menos que voc faa algo para evitar.
NQ9

exJst~m

Terh'untels IdJ'9tl8

r:
I\:

Ento as variveis de instncia no so thread-safe?

r:

Mas se voc no vai usar o SingleThreadModel e nem sincroni~ar o mtodo de servio, como voc TORNA as variveis de instncia thread-safe?

Isso mesmo. Se voc tem vrios clientes fazendo solicitaes nesse servlet, significa vrias threads rodando o cdigo desse servlet. E todas as threads possuem acesso s variveis de instncia do servlet, portanto, as variveis de instncia no so thread-safe.

I\: No tem como. Observe

r:

Mas elas SERIAM thread-safe se voc implementasse o SingleThreadModel, certo?

um servlet bem escrito e pode ser que voc no encontre nenhuma varivel de instncia. Pelo menos no uma definitiva. (E sendo um programador Java, voc sabe que mesmo uma varivel definitiva ainda pode ser manipulada, a menos que ela seja imutvel.) Ento, no use variveis de instncia se voc precisar de segurana contra threads, pois as threads para esse servlet podem sobrepor as variveis de instncia.

I\: Sim, porque voc nunca teria mais de

uma thread para o servlet, ento as variveis da instncia seriam thread-safe. Mas claro que ningum mais aceitaria voc no clube dos servlets novamente.

r:

Ento, o que voc DEVE usar se precisar que vrias instncias do servlet compartilhem algo?

r:

Eu s estava dando um exemplo. Como, "se algum FOI estpido o suficiente para implementar o SingleThreadModel. ..". No que eu j tenha feito isso. Mas, j que estamos apenas levantando hipteses ... se eu tivesse um amigo que, digamos, sincroni~asseo mtodo de servio, isso TAMBM no tornaria as variveis de instncia thread-safe?

I\: Espera um pouco! Voc disse "vrias


instncias do servlel". Ns sabemos que voc no quis dizer isso, pois sempre haver apenas UMA instncia do servlet. Uma instncia, muitas threads. Se voc quiser que todas as threads acessem um valor, decida qual estado do atributo faz mais sentido e armazene o valor nele. H chance de voc resolver seus problemas de uma destas duas maneiras: 1) Declare a varivel como uma varivel local no mtodo de service, em vez de como uma varivel de instncia. OU 2) Use um atributo no escopo mais apropriado.

I\: Sim. Mas seu amigo seria um idiota. O


efeito de implementar o SingleThreadModel quase o mesmo que sincronizar o mtodo de servio. Ambos podem "arruinar" a aplicao sem proteger o estado da sesso e do atributo.

204

captulo 5

Atributos da Solicitao e Request dispatchittg


Os atributos da solicitao fazem sentido quando voc quiser que algum outro componente da aplicao assuma o controle de toda a solicitao ou de parte dela. Nosso exemplo simples e caracterstico uma aplicao MVC que inicia com um servlet controlador, mas termina em uma view JSP. O controlador comunica-se com o modelo e obtm os dados que a Yewnecessita para construir a resposta. No h nenhuma razo para colocar os dados em um contexto ou atributo de sesso, j que s vale para esta solicitao. Desta forma, o colocamos no escopo da solicitao. Ento, como fazemos para que outra parte do componente assuma a solicitao? Com um RequestDispatcher.

Cc,/c,3(1e6sdf4,J6S dt>~IJJeI6 ~6 esc6p6

cdigo em um doGet() J BeerExpert be = new BeerExpert(); ArrayList result = be.getBrands(c);

II

d4

SIJ,'iCi..fo'C'iilJ v.result);

request.setAttribute("styles",

C6~Sijo'

(I~

dlSpo'..fct.el' par4

RequestDispatcher11. vlew view = ~ request.getRequestDispatcher("result. jsp"); view. forward (request,

JSp' '--.

response);

Jl,{4~de () JSP ass(llVIll"

o.

SlJllcl+~i;lJ

eJ aI. Si~ 11.3(11" eSh., .,s


S6Ilcl+4j8.lJ

(Jt.;e..f.os

e JeesplJs+a.

O servlet Beer chama o mtodo getBrandsO no modelo, que retorna com alguns dados de que a view precisa. GetBrands( ) ~ "Moose Drool" objeto Modelo

O servlet configura um atributo para a Solicitao chamado "styles".


(Primeiro, ele coloca o "Moose Drool" em um ArrayList.) setAttribute("styles", results)

O servlet solicita ao HttpRequest um RequestDispatcher, passando em um caminho relativo para a view JSP.

O servlet chama o forwardO no RequestDispatcher para mandar o JSP assumir a solicitao. (No mostrado: encaminhada do escopo o JSP recebe a solicitao e obtm o atributo Solicitao.)

getRequestD ispatcher( uriTo View)

"styles"

Controller HttpRequest

forward(request

,response)

;;:)

Controller

voc est

o Requestdispatcher

o RequestUispatcher

revelado
<<interfaee> > RequestDispatcher forward(ServletRequest, include(ServletRequest, ServletResponse) ServletResponse)

o RequestDispatcher possui apenas dois mtodos - forwardQ e includeQ. Ambos levam os objetos solicitao e resposta (os quais o componente que voc est encaminhando precisar para terminar a tarefa). Dos dois mtodos, o forwardQ de longe o mais popular. muito improvvel que voc use o mtodo inc1ude de um servlet controlador; porm, por debaixo dos panos, o mtodo include est sendo usado por JSPs na ao-padro ~sp:include> (que ns revisaremos no captulo 8). Existem duas formas de conseguirmos um RequestDispatcher: atravs da solicitao ou do contexto. Independentemente de onde ele venha, voc deve informar a ele para qual componente web voc est encaminhando a solicitao. Em outras palavras, o servlet ou o JSP que assumir o controle.
RequestDispatcher view

Obtendo o RequestDispatcher atravs de um ServletRequest


~ request.getRequestDispatcher(~result.jsp");

O mtodo getRequestDispatcherO no ServletRequest usa um caminho String para o recurso o qual voc est encaminhando a solicitao. Se o caminho comear com uma barra ("/"),0 Container entende como "iniciar a partir da raiz desta aplicao".. Se o caminho NO iniciar com uma barra, ele

s-n,: e Vir! C41r!111t.(J relo.+,vl:I

L'

.~

l1ei11t.vlMo. barra ( ) l"i11i'clo.l). l1h{JJ l1esff C4SlJ (J Cl1l1+41"i11er 1'11ClIra e/i) f>, f> resvl+,:jSf> i11l1 ",eslMC IlISar IC5'cC ~(.Ie

u/"

<,1:11:5' 11.i1(J "'a

. "" ,

considerado como relativo solicitao original. fi. S6IiC{+4{;" es-h-lIel' 1"i11sf,rl41fl.. (lJf.s Mas voc pode tentar a olhar ~ raifJ.I'f:1M6S I' , li J J tI l. ()S ca""I1"'''s I . _ enganar o Container '. 1r!",ero.,,,,es S():TI't. para fora da aphcaao atual. Ou seja, so porque voce I I tem muitas " ..!..!..!", no significa que v funcionar I'ela+llll),s e I),S luSares 165'C()S i11(J ctJpll-ula se ele alcanar alm da raiz da sua aplicao atual!
s(JIJI'f! bi's+rtIJu1f/4(J)

Obtendo o RequestDispatcher atravs de um ServletContext


RequestDispatcher view = getServletContext() .getRequestDispatcher(~/result.jsp");

Assim como o mtodo equivalente no ServletRequest, este mtodo getRequestDispatcherQ usa um caminho String para o recurso o qual voc est encaminhando a solicitao, EXCETO se voc no puder especificar um caminho relativo ao recurso atual (aquele que recebe a solicitao). Isto significa que voc deve iniciar o caminho utilizando a barra!

~ce

"bf.v IJsar

fi.

barra

C{J'" (J

1M:+I:I41(J Se+Jt.etpesl-btsf>t1.+cl.erO 4lIJ ServleiC()i11+elc+.

Chamando o forward() no RequestDispatcher


view. forward (request, response);

Simples. O RequestDispatcher que voc obteve atravs do contexto ou da solicitao conhece o recurso que voc est encaminhando - o recurso (servlet, JSP) que voc passou como argumento para o getRequestDispatcherQ. Ento, voc est dizendo: "Ei, RequestDispatcher, por favor encaminhe esta solicitao para aquela coisa que eu disse anteriormente (neste caso, um JSP), quando nos falamos pela primeira vez. Eis a solicitao e a resposta, pois esta nova coisa vai precisar delas para terminar de tratar a solicitao."

206

capj;tuJo

o que h de errado COilteste cdigo? o que voc acha? O cdigo deste RequestDispatcher
que funcionar do jeito que voc esperava?
public void doGet(HttpServletRequest

parece

request, HttpServletResponse response) throws IOException, ServletException

response.setContentType(~application/jarff); ServletContext ctx ~ getServletContext(); InputStream is = ctx.getResourceAsStream(~bookCode.jarff); int read ~ o; byte[] bytes new byte[1024]; OutputStream os = response.getOutputStream(); whi1e (read ~ is.read(bytes)) !~ -1) { oS.write(bytes, o, read);
}

St/ftmkfJ.
1"$+"

t/E'

tt/"d""fJ,

os.flush(); RequestDispatcher view ~ request.getRequestDispatcher(~result.jspff); view. forward (request, response); os. close ();

Voc vai receber Uilt ettorilte lIIegalStateExceptiott!

Voc no pode transferir a solicitao se voc j submeteu uma resposta! E por "cubmeteu uma resposta" e~tend~ como, "enviou a resposta para o cliente . Observe o cdigo novamente. O grande problema :

r:

Como voc no falou sobre o mtodo includeO do RequestDispatcher?

1\: Um dos motivos

os .flush () ;
Esta a linha que jaz com que a resposta seja enviada ao cliente e, ,neste ponto esta respostajoi CONCLUIDA. TERMINADA. J ERA. Possivelmente, voc no poder encaminha~ a ." solicitao neste estgio, pOIS.ela ja, e histria! Voc j respondeu e ISSOso acontece uma vez. Ento, no seja iludido por. q~est~es do exame que enviam a solzcltaao DEPOIS da resposta ter sido enviada. O Container vai mostrar um IllegalStateException.

porque ele no est no exame. Outro: ns j mencionamos que ele no muito usado na vida real. Porm, para satisfazer a sua curiosidade, o mtodo includeO envia a solicitao para outro lugar (geralmente outro servlet), para realizar alguma tarefa e ento voltar para o remetente! Em outras palavras, significa que o includeO pede por ajuda no tratamento da solicitao, mas no chega a ser uma ajuda completa. apenas uma transferncia de controle temporria, e no, permanente. Com o forwardO, voc est dizendo: " isso a, eu no vou fazer mais nada para processar esta solicitao e esta resposta." Porm, com o includeO, voc est dizendo: "Eu quero que outra pessoa faa algumas coisas com a solicitao e/ou resposta, mas quando ela terminar, eu mesmo quero acabar de tratar a solicitao e a resposta (embora eu talvez queira fazer outro include ou forward depois disso ...").

voc est

respostas do exerccio istener

Relembrando os Listeners
RESPOSTAS

Exetcd9S
Listeners de atributos

5erllle+it-e3ve s+A-#ri"bv..feLi's..fel1er 5ervle+C~P1..fex+A-#rt!Jv+eLts+ePler H#p5es siiJl1tJr#rt!Jv+eLts..fel1er

Outros listeners do ciclo devida

Mtodos em todos os listeners de atributos (exceto binding listener)

a.ffrt!Jv+eA-Jt1etlO affrt!Jv+eit-ew.lJveJO affrt!tv..feit-epI4cet10

Eventos do ciclo de vida relacionados s sesses (exceto eventos relacionados aos atributos) quando a sesso criada e quando ela destruda

tJl1Je a. segalJ e cr''"4tltA; e IJ"'IJe e ses si"'lCrea+eJO ses st"l1lJes+rlJjeJO

Eventos do ciclo de vida relacionados s solicitaes (exceto eventos relacionados aos atributos) quando a sesso inicializada ou destruda

Eventos do ciclo de vida relacionados ao contexto do servlet (exceto eventos relacionados aos atributos) quando o contexto inicializado ou destrudo 208 capj!tulo 5

wt.e"'l +t.e ceu'rf-ex+l's ,.",.+lalljeJ e.r Jes+re.jeJ


CI1-hx+II'I,--I-l4't;f.JO

ctJ~x+lJes+r~jeJO

atributos e Isteners

Escopo Atributo
RESPOSTAS

S1I4r14 as varis lJ""Pru e

tA

/ C611+e1l.,(4 des+rv{,J<l Acessibilidade (por quanto tempo vive) Para "P"ca]"6 que serve .,(ls l'I"btll.,(lJ.. Escopo <il sel'vMIJi" <ilf.l Se N+,/ C~ IJ.CeSS6 aas sess46 .,(~4~.,./-e l';;clUll1dl.l c<J"Iex::es rela-h-ves ~ SesS4lJ apel1IJ.s lIi1'lIJ. lmclli. I'r V,",,4.,(aseSSM. !JadlJs e N!.CflI'SCS re3l1ef' lIi1'la <l C"'IIH!f'Sa .,(es+e clle#l-h!j e 114fJ CtliI'l li clltPJ+e, ti;;, 4ptiC444j I';;etvll'l.,(o (,I'" /;(J'" tM!it>f't.rJ. tllWJ. s eSS46 ~tfJr'54 seI' 6S l1I'JiI'les de I.u:,kllp 3t1e Sijl1l"1lca S6/il+o.544, 4 viii" .,(IJ. f4t' -h-..e-et,;+, ~INJS 1'itJ.6 PI'65I'4IWJ.iW Sl""f'eS~~ e-iI'laN; 46 d" /;a11C6.,(e Serv1e.fC6J?-h!X+j 6 +eit>f'IJ e+c dad4sJ de vlfia 3ue'"a Sve a f4t' ~14 de .,(esl-f'u!Ja Jt.eCIIf'SIJS Sve JAl!JI; eJ?.,(eresI'Js de I,;;.f-el"a CIJ""PIJ.f'-I-t"It.eJ 4pll,'i6 catrj f;{v#J?per f;{v4t311IY' sel'vle+ p4f'.f-e .,(4 <!li JSP

em

Solicitao
I'r vlfia da Scll'cl+IJ.!j'ifJj 3l1e s'j"ltli(;a servlce() a+: ti It", .,(6 Servle+.

Passar S6/;l'e

4 ;;'4.,(tl() .,)
pfJ.l'IJ. ti.

N /} .,(IJ. execujalJ dlJ ",erlJd 011S~4; .,(lIra~


Vlfia .,(a +t.I'ea.,(

c6"1+rlJlad4f' IlftW 41/ (J8I+I'4 .,(t!d4

a
(ptlt.l))

ptu'a ti
IJ/)\

de

f/"el' s/!I'vle+s d',el't


pat'1J. 61'1de a

tiS

3ve es+tver esh

+rtJ.+fJ.J?.,(4

cll"eI1-h!.

s()llct+a{l4.

I/' e"'lC41JlJ",t.a.,(1J, (,ISGl"ld"

s
relacicl'lti.,(6S S4Ilt+tUj'i"". ~

aqui

209

im de geladeira - respostas dos exerccios

m de Gelcidelt'l
RESPOSTAS
(configurando um parmetro de contexto no DD)

!<web-app

". >

I <servlet>

I
</servlet-name> I .
11

1---------------------1 <servlet-name> . I . BeerTest


I

<servlet-class>

II-c-o-m-,w-l-c-k-e-d-l-y-S-m-a-r-t-.B-e-e-rT-e-st-e--r </servlet-class>

I </ servlet> I
I <context-param> I

I <param-name>
I <param-value> I

I </param-name> I </param-value> I

!</context-param> !</web-app>1

No usados:

</init-param>

o <.t"r-l-pfJ.I"fJ.h\> (,ISfJ.tilJ
" <:'1;,t.f-PfJ.1"41f!l> tie"+l"fi tie <:.servle+>.
A1';1>
(,111I

pal"~d;l"lJs

,;"Y-

ti6 sel"lIl&; "';6 tilJ CIJ,,+eX+6.

e"c(m+l"fJ.

[<servlet-param>
CI>III

exish Ifo.tiaPl4l"tc"ti(J

<.servle+-pI4NJ.!!/I\>.

210

fausa pata 9 cat

1Usando um RequestDispatcher,
IllegalstateException? DA. read DB. flush DC.write Dn. getOutpuStream

o uso de qual dos mtodos pode nos levar a uma (Escolha todas as que se aplicam.)

DE. getResourceAsStream

2 Quais

declaraes sobre os parmetros de inicializao do ServletContext (Escolha todas as que se aplicam.) DA. Eles devem ser usados para dados que raramente mudam. DB. Eles devem ser usados para dados que freqentemente mudam. De. Dn. Eles podem ser acessados usando o ServletContext. Eles podem ser acessados usando o ServletContext. getParameter

so verdadeiras?

() . () .

getIni tParameter

DE. Eles devem ser usados para dados que so especficos de um determinado servlet. DF. Eles devem ser usados para dados que servem para toda a aplicao.

voc est

aqui..

211

teste preparatrio

3 Quais tipos definem os mtodos


aplicam.) elJ\.Httpsession elB. ServletRequest OCo ServletResponse elD. ServletContext DE. ServletConfig elE SessionConfig

getAttribute

() e setAttribute

() ? (Escolha todas as que se

Se um servlet for invocado usando-se o mtodo forward ou include do RequestDispatcher, quais mtodos do objeto solicitao do servlet podem acessar os atributos da solicitao configurados pelo container? (Escolha todas as que se aplicam.)

QJ\. getCookies
DE. elc. getAttribute

() () () () ()

getRequestPath

DD. getRequestAttribute DE. getRequestDispatcher

5' Quais chamadas oferecem informaes sobre os parmetros de inicializao que podem ser usados
por toda a aplicao? (Escolha todas as que se aplicam.) DA ServletConfig.getlnitParametersO

D B. Serv letContext.getInitParametersO Dc. uD. ServletConfig.getlnitParameterNamesO ServletContext.getInitParameterNamesO

DE. ServletConfig.getInitParameter(String) DE ServletContext. getInitParameter(String)

212

captulo 5

atributos

e listeners

Quais declaraes sobre os listeners so verdadeiras? (Escolha todas as que se aplicam.)

DA. O ServletResponseListener
do servlet foi enviada.

pode ser usado para executar uma ao quando uma resposta

DB. O HttpSessionListener
HttpSession.
De.

pode ser usado para executar uma ao quando der time-out no

O ServletContextListener pode ser usado para executar uma ao quando o contexto do servlet estiver prestes a ser encerrado.

DD. O ServletRequestAttributeListener pode ser usado para executar uma ao quando um atributo tiver sido removido do ServletRequest. DE. O ServletContextAttributeListener pode ser usado para executar uma ao quando o contexto do servlet tiver sido criado e estiver disponvel para servir sua primeira solicitao.

O que seria mais coerente de ser armazenado como atributo no escopo sesso? DA. A cpia do parmetro de uma query que o usurio digitou. DB. O resultado de uma query ao banco de dados para ser retomado imediatamente ao usurio. De. O objeto da conexo com o banco de dados usado por todos os componentes da aplicao.

DD. Um objeto representando um usurio que acaba de se logar no sistema. DE. A cpia do parmetro de inicializao recuperado de um objeto ServletContext.

voc est aqui

I!"

213

teste creparatrio

8 Dado o cdigo de um HttpServlet


ServletRequestAttributeListener:
10. pub1ic lI. 12. 13. 14. 15. void

vlido que tambm foi registrado como um


req, HttpServ1etResponse ServletException {

doGet(HttpServletRequest

res)

throws IOException, req.setAttribute(~a", ~b"); req.removeAttribute(~a");


}

req.setAttribute(~a", ~c");

16.

public void attributeAdded(ServletRequestAttributeEvent ev) { 17. System.out.print(~ A:" + ev.getName() + ~->" + ev.getValue()); 18. } 19. public void attributeRemoved(ServletRequestAttributeEvent ev) { 20. System. out .print (~ M:" + ev. getName () + ~->" + ev. getValue ()); 2I. } 22. public void attributeRep1aced(ServletRequestAttributeEvent ev) { 23. System.out.print(~ P:" + ev.getName(} + ~->" + ev.getValue()); 24.

Qual dos logs gerado? C)Pl.A:a->b P:a->b C)B. A:a->b M:a->c C)C. A:a->b P:a->b M:a->c C)D. A:a->b P:a->b P:a->null C)E.A:a->b M:a->b A:a->c M:a->c C)F.A:a->b M:a->b A:a->c P:a->null

9 Ao declararmos um listener no DD, quais subelementos do elemento <listener>


(Escolha todas as que se aplicam.) CJPl.<description> OB. <listener-name> CJC. <listener-type> CJD.<listener-class> CJE. <servlet-mapping>

so necessrios?

214

captulo 5

atributos e fsieners

10

Quais tipos de objetos podem armazenar atributos? (Escolha todas as que se aplicam.) 01\. DB. Oc. ServletConfig ServletResponse RequestDispatcher

OI>.HttpservletRequest OE.Httpsessioncontext

11 O que
DA

verdade? (Escolha todas as que se aplicam.) Quando uma aplicao est prestes a ser encerrada, o pedido de notificao do listener no garantido.

OB. Quando um evento que aceita um listener ocorre, o pedido de chamada do listener no previsvel. Oe. O container registra os listeners baseado nas declaraes do deployment descriptor.

DI>. 1\penas o container pode invalidar uma sesso.

12

Quais declaraes sobre o RequestDispatcher so verdadeiras (quando verdadeiras, considere que o RequestDispatcher no foi obtido via uma chamada ao getNamedDispatcher ()? (Escolha todas as que se aplicam.) 01\. DE. De. O RequestDispatcher pode ser usado para encaminhar uma solicitao a outro servlet. o forward (). no so

O nico mtodo na interface do RequestDispatcher

OS parmetros especificados na query string usada para criar o RequestDispatcher encaminhados pelo mtodo forward () .

DI>. O servlet para o qual uma solicitao encaminhada pode acessar a query string original, chamando o getQueryString () no HttpServletRequest. DE. O servlet para o qual uma solicitao encaminhada pode acessar a query string original, chamando o getAttribute("javax.servlet.forward.query_stringU) no ServletRequest.

voc est

215

teste preparatrio

13

Qual a maneira recomendada para lidarmos com segurana de servlets e threads?

DA. Fazer com que o cdigo do servlet estenda ThreadSafeServlet. DB. Fazer com que o servlet implemente o SingleThreadMode1. Dc. Logar todas as chamadas dos mtodos.

DD. Usar exclusivamente variveis locais, e se voc tiver que usar as variveis de instncia, sincronizar o acesso a elas.

14

Dados os seguintes mtodos:

- ggetCookies - getContexPath - getAttribute Coincida os mtodos acima com as seguintes classes ou interfaces. Note que cada mtodo pode ser usado mais de uma vez.

HttpSession ServletContext HttpServletRequest

15

O que verdadeiro sobre a interface RequestDispatcher?

(Escolha tudo que se aplica.)

DA. De seus dois mtodos, forward( ) usado com mais freqncia. DB. De. Seus mtodos tm os seguintes argumentos: recurso, solicitao e resposta. Dependendo da classe cujo mtodo cria um RequestDispatcher, a ser enviado mudar. o caminho para o recurso o caminho para o

DD. Independentemente da classe cujo mtodo cria um RequestDispatcher, recurso a ser enviado NO mudar. DE.

Se seu servlet chamar RequestDispatcher.forward, poder enviar sua prpria resposta para o cliente antes, mas no depois da chamada de envio.

216

atributos

e listeners

Pausa pata

o cat
'R~-~5

1Usando um RequestDispatcher,
IllegalStateException?

o uso de qual dos mtodos pode nos levar a uma (Escolha todas as que se aplicam.)

DA. read
litl"B. flush litl"c. write lJlj<j(4 IlIeiafS+a-hf.xce,-h..,,, , ti res,as+tJ.j4 lat Iftlst. 14; tsstJJ 'l.tla"da tllj<ja ti catlsada o ,

DD. getOutpuStream
DE. getResourceAsStream

Calj<je+M4 ,41"4 a ette,,+e

(6 lj<je+fJdfJ

e vac -h"+4 14;U'

tllj<j

lanli4rd,

2 Quais

declaraes sobre os parmetros de inicializao do ServletContext (Escolha todas as que se aplicam.) litl"A. Eles devem ser usados para dados que raramente mudam. DB. Eles devem ser usados para dados que freqentemente mudam. Dc. Eles podem ser acessados usando o ServletContext.getParameter().

so verdadeiras?

litl"D. Eles podem ser acessados usando o ServletContext.

getlni tParameter

() .

DE. Eles devem ser usados para dados que so especficos de um determinado servlet. litl"F. Eles devem ser usados para dados que servem para toda a aplicao.

A,

a'f"
N

$ es+:

'7CQN'e.f4.J f>(Jr'!JtlfQS'4r~e+ras

Sii:J sa" 'M(JS "4 /,(JNJ. flj<j A- c'f';c

/I i ' ';'icta't"f;tJ.dc. tl t..(J/I'f"f'fJ,I7er e

'7t+

da Serllfe+Caw!-ex+

A- af>S';(J es+: '7cal"l"e.fl;f>IJI"1Jtle s~ ei'u"s+e Vir! l6e+a Sel"lIfe+CIJ,,-hx+ apfif:4s';a.

C es+: l7cCI'I"e.fl; PIJI"3ve es-h Ir!:+IJd(J ,,'ia ex,"s-h. ,aI"

voc est

'"

217

teste preparatrio

3 Quais tipos definem os mtodos


aplicam.)
I\,;? I\,;?

getAttribute

() e setAttribute

() ? (Escolha todas as que se

A. HttpSession B. ServletRequest

OCo ServletResponse
I\,;?

D. ServletContext

DE. ServletConfig DF.sessionconfig

Se um servlet for invocado usando-se o mtodo forward ou include do RequestDispatcher, quais mtodos do objeto solicitao do servlet podem acessar os atributos da solicitao configurados pelo container? (Escolha todas as que se aplicam.) DA. getCookies
I\,;?

() ()

B. getAttribute

De. getRequestPath()
OD. getRequestAttribute DE. getRequestDispatcher
Ir IJpjlJ

() ()

8 apl"ese1'l.ffl.

" "",.fiJiJiJ CM'l"e.ftl.

C,,"'" ele; vlJc plJJe fl.cesstJ.1"

IJS 1J..fI",1;v.fIJS pl"ee"ct.MlJs jfl.vfl.x.se I"vle-J-.,;'c/vde.X.xxx. Irs

iJlJ CI:m.fo.ll1el"jfl.llf1.x.sel"lIlff./lJl"wtJ.I'J.x.xx

iJpj6eS C e lJ

se I"elel'el/ll

fi. l/II-I-iJiJiJS~ve

"iJ

exi's.fel/ll.

5 Quais chamadas

oferecem informaes sobre os parmetros de inicializao que podem ser usados por toda a aplicao? (Escolha todas as que se aplicam.) DA. ServletConfig.getlnitParametersO DB. ServletContext. getInitParametersO Dc.
I\,;?

Irs

iJPj6es

Ir e

ServletConfig.getInitParameterNamesO D. ServletContext.get1nitParameterNamesO Serv letConfig. getlnitParameter( String)


-

8 es.flJ

,;,clJl"I'ehs;

piJl"~ve es.fes Irs

l/II.fiJJiJS PJlJexts.fel/ll. e f. es.fQiJ ';'C6I"1'fffl.S;

iJpj6eS C
l(.

DE.
I\,;?

plJl"iVe

iJlel"ecel/ll fJ.ceSSIJfl.iJS

F. ServletContext.getInitParameter(String)

pfl.l'fI."'te-rl"lJs iJ6 sel"vle.f.

iJe ';'lci'fI.'i';fl.jfl.lJ espec,llclJS

,..;

218 captulo 5

atributos

e Isteners

Quais declaraes sobre os listeners so verdadeiras? (Escolha todas as que se aplicam.)


(5el"vle.f. V2.,

ti; p~. 80)

DA. O ServletResponseListener
do servlet foi enviada.

pode ser usado para executar uma ao quando uma resposta

fil E. O HttpSessionListener
HttpSession.

pode ser usado para executar uma ao quando der time-out no

fil c. O ServletContextListener

pode ser usado para executar uma ao quando o contexto do servlet estiver prestes a ser encerrado. pode ser usado para executar uma ao quando um atributo tiver sido removido do ServletRequest. O ServletContextAttributeListener pode ser usado para executar uma ao quando o contexto do servlet tiver sido criado e estiver disponvel para servir sua primeira solicitao.

fil D. O ServletRequestAttributeListener
DE.

If If

iJp{iJ

If

es-/-: ii'lcIJl"l"e-/-a; PiJl"1Jve ,,'i.iJ se I"elel"e

a v~a 'i1hl"iace

diJ

5el"vle-l-/t.espiJ"seL.i"sh"lel"

iJPf'i.lJ f. es-l-: ,i1cIJl't'e-l-tl; plJl"'/;ve vsal":alti\fJs Vlti\ 5el"vle.f.CfJ"hx-/-L,"sh"lf!1"

pal"ti. es-l-e pl"fJp:Sl-l-IJ.

ODA. que seria mais coerente de ser armazenado como atributo no escopo sesso? A cpia do parmetro de uma query que o usurio digitou. (5el"vle-l- V

, 2..,IJ I'fAj'
J

S"8J

DE.

O resultado de uma query ao banco de dados para ser retomado imediatamente ao usurio. da conexo com o banco de dados usado por todos os componentes da aplicao.

Dc. O objeto

fil D. Um

objeto representando um usurio que acaba de se logar no sistema. do parmetro de inicializao recuperado de um objeto ServletContext.

DE. A cpia

- If If
1"f

fJPf'i.fJ

If

es-/-: li1CiJl"l"e-l-a; I'fJl"'/;fle

IJ

pal"M"e+l"fJ

de Vlti\4 ~Vff!l"j

5el"allti\e,,-I-e lti\al"s flsadiJ ptt.NJ. I"eali,al" fJPf'i.fJ

Vlti\t.lfJPff!I"t.lf'i.fJ.

8 es-l-:

'i1CIJl"I"e-/-a;pIJI"3f1e -I-af dtJ.da 5ff!I"lJ.flti\f!I'rh

l'lti\edta-/-fl./I!\e,,+e
de VIti\IJ. CI)i'1+ex-l-fJ.

l"e-l-al""ItJ.JfJ iJfI tJ.1"1ti\fl.je'llJ.JfJ '14 eSCIJpfJSIJIi'ci"-I-af'i.fJ. A. IJPftJ.a ". C es-rtJ. I' li1CIJI"I"e-r~ - 1- p41"'/;ve 9tJ.3ve '". / especIllcIJ , '1aIJ e

Jehl"lti\/i1lJ.JIJ. sess'i.tJ.> ele Jevel"i"IJ. seI" IJ.1"1ti\tt.je'llJ.JIJ /'Ia esclJf"

If

fJPj'i.l)

es-/-: li1ClJl"l"e-l-~ plJl"'/;ve fJSptJ.I"M"e.f.1"6S J6 CM+eX-l-iJ Sf!I"VIe.f. '16 6tje-l-6 5el"vle-I-C61'1+ex-l-.

Jevel"lalti\ es .. hl"

voc est aQui..

219

teste preparatrio

8 Dado o cdigo de um HttpServlet


ServletRequestAttributeListener:
10. pub1ic 1l. 12. 13. 14. 15. void

vlido que tambm foi registrado como um


req, HttpServletResponse ServletException {

doGet(HttpServletRequest

(.sel"v'dv2..~p~. 799-2.00)
res)

throws IOException, req.setAttribute(~a", ~b"); req.setAttribute(~a"r "e")i req.removeAttribute(~a");


}

pub1ic void attributeAdded(ServletRequestAttributeEvent ev) { 17. + ~->" + ev.getVa1ue()); System.out.print(~ A:" + ev.getName() 18. } 19. pub1ic void attributeRemoved(Serv1etRequestAttributeEvent ev) ( 20. + ~->" + ev.getValue()); System.out.print(~ M:" + ev.getName() 2l. } 22. public void attributeReplaced(ServletRequestAttributeEvent ev) ( 23. + ~->" + ev.getVa1ue()); System.out.print(~ P:" + ev.getName() 24.

16.

Qual dos logs gerado? DA. A:a->b P:a->b DB. A:a->b M:a->c ~e.A:a->b P:a->b M:a->c DD. A:a->b P:a->b P:a->null DE.A:a->b DF.A:a->b M:a->b A:a->c M:a->c M:a->b A:a->c P:a->null

Pe5aJ,i,f"a! tJ lt1-!-~J"5e#altle l"e-f.iJl"J'lf4. " vs.l~1" IJrlJr'Z/;tJ da 1J.-!-l"i1l1-!-" se es-h tal' slIbhl-tlida.

9 Ao declararmos um listener no DD, quais subelementos do elemento <listener>


(Escolha todas as que se aplicam.) DA. <description> DB. <listener-name> De. <listener-type> ~D.<listener-class>
O stl/;elelt1eJ'l-!-"<.lfs+enerclass">

so necessrios?

e " uAJ'ZCO elelt1en-l-"

DE. <servlet-mapping>

,i,di'spens:vel

d6 elelt1f!n';'" <.Ii's+enel'">.

220 capituio 5

atributos

e !steners

10

Quais tipos de objetos podem armazenar atributos? (Escolha todas as que se aplicam.) [J1\.servletConfig

OB. ServletResponse
De. RequestDispatcher
Iit? D. HttpServletRequest

[JE. HttpSessionContext

fJ(j"t-a: Os V+-l'S Jis '/-'j>(;S

I'elel"e~s

lJ.

sel"vle+- 3ve PI}Je'hII

al"IfIa-;eJ7lJ.1' tJ.+-I"rbv+-s s., tJ ##pSess/()J7 e 6 Sel"vle..j.Ctil1fflf--l.

11 O que
DA DE.
Iit?

verdade? (Escolha todas as que se aplicam.) Quando uma aplicao est prestes a ser encerrada,;; pedido de notificao do listener no garantido. Quando um evento que aceita um listener ocorre, o pedido de chamada do listener no previsvel. registra os listeners baseado nas

(Sel"vle-l-

i2..~p~s.
8

87 tJ.

IJrs aF{;es A- e es+';e ,;,cI"I"e+as;pI"3ve 6 ctm+tJ.I;,er VS4 lJb pal"a Jeh;,tt' li. I}t'Jelfl Je J76+,"Ii'ca{itJpal"a tJS li'sffJ7et's t'f!!5iS+t'IJ.d()s.

c. O container

declaraes do deployment descriptor. DD.1\penas o container pode invalidar uma sesso.

lJr cp{i lJ es+: t#1CfJt't'ef-t4; ptir'lpe Vht set'vlef- pade ii1Vt4IMlJ.r ti /iVl-I-(jdlJ vlfla ses s';tJ VStJ.#1J H.f..i.p.5eSSi'611.,;'VQ.lidtJ.+eo.

12

Quais declaraes sobre o RequestDispatcher so verdadeiras (quando verdadeiras, considere que o RequestDispatcher no foi obtido via uma chamada ao getNamedDispatcher ())? (Escolha

todas as que se aplicam.)


Iit? 1\. O RequestDispatcher

(.5erll Ie-r J 112..[J / J P"5. r


pode ser usado para encaminhar uma solicitao a outro servlet. o forward (). no so

DE. De.

O nico mtodo na interface do RequestDispatcher

OS parmetros especificados na query string usada para criar o RequestDispatcher encaminhados pelo mtodo forward () .

DD. O servlet para o qual uma solicitao encaminhada pode acessar a query string original, chamando o getQueryString () no HttpServletRequest.
Iit? E. O servlet para o qual uma solicitao encaminhada pode acessar a query string

original, chamando o getAttribute ServletRequest. lJr 6p{i6

("javax.servlet.

forward.query_string")

no

8 es+:

I;'COl"I"ef-s.,; p(jr~ve tJ.,;,fft'lo.ce

+tJ.lflb~IfI P/JSSi/i' Vif\ if\~+/JJo ,;'c/vJe.

lJr 6PS';C es+: i'l'1c(jt't'e+-4;pri/e eSffs

PQ.t';""ef-t'tJs sel"'/Jel'1caif\,;,t.ad6S I'l'f!s+e C4StJ.

- lJr lJPj'/J b ~ ti1ctJrl"e+o.P/JI"f/,'f!!es se IfI~+tJdtJt'e+Ct'I1Q.Q. s+t'l;'5 de cO'lsvl-/-a '10 pQ.Jt'o uJeL


o. parl-tt'

dtJ Jee'/;vf!s-l-btspa-l-ct.et'.

voc est aqui ~

221

teste prepaBtrio

13

Qual a maneira recomendada para lidarmos com segurana de servlets e threads?


!speciflcll.gi

d6

Se"'lIle.f;

p:.,.

2.7)

DA. Fazer com que o cdigo do servlet estenda ThreadSafeServlet. DE. Fazer com que o servlet implemente o SingleThreadMode1. Dc.
1\2' D.

Logar todas as chamadas dos mtodos. Usar exclusivamente variveis locais, e se voc tiver que usar as variveis de instncia, sincronizar o acesso a elas.

- IJrs lJ/,f6es lJr e exts-h

8 silJ tm::6f'N!.ffl.S
e
IJ

plJt''!re

IJ

rt.,..ell.dSo.feSe,..vle.f

",i/J

",a Se,..ille.f. IJrPI

Sl"'5IeFt."'efJ.JMlJdel

tiesap,../JiladlJ

",4 vet'si/J

2..'-1 e ",i.,

,..ec6J/11eJ'1dll.d.,.

14

Dados os seguintes mtodos:

- ggetCookies - getContexPath - getAttribute Coincida os mtodos acima com as seguintes classes ou interfaces. Note que cada mtodo pode ser usado mais de uma vez.

HttpSession ServletContext HttpServletRequest

'" 5tt/lf:f.r:!:~~h. ...


...j.t:I:ft.H:r.fhl.f.e..o.
o

.5~~.'J.-k~fP.~f1.: ..

1-t:ft..~~!:,,!:~

. ..J.~ft.Hr.(~.I!.-k ....

AJes-h ~6J'1.f6J "'ealJ/lleJ'1.f.eJ'1iIJ deve havet' J/IIf!.J/lla"")ll.ji6 fl.SS,M. C6J/11<::1 1Jtl4is m.e.ft:iJlJs fa,..tam. Sf!.",.f.,flJem. cadll. esccfc.

15

O que verdadeiro sobre a interface RequestDispatcher?

(Escolha tudo que se aplica.)

1\2' A.

De seus dois mtodos, forward( ) usado com mais freqncia. Seus mtodos tm os seguintes argumentos: recurso, solicitao e resposta.
- Df}i.,

DE.
1:""7

8: 6 t'ectlt's

I
e

espec'-ficlt.JlJ

'16 m.cl'iflePl.f-da

. d o cna . um C"','"4ji., d., .,Qie.f6. lllJ C . D epen d en d o dI' a c asse cUJometo v RequestDispatcher, o caminho para o recurso a ser enviado mudar.
- Dffi., ~: se set/ set'lIle.f

DD. RequestDispatcher, Independentemente NO mudar. DE.

da classe cujo mtodo cria aum o caminho para o recurso ser enviado

t/sa,..
f'6tie,..a

t/1iO'l

j!!./); I7t1P1ca

el7l1''"4,.. StliJ,

Se seu servlet chamar RequestDispatcher.forward, poder ,..eSf'6s.fa. enviar sua prpria resposta para o cliente antes, mas no depois da chamada de envio.

222 captufo 5

6 betencltment9 da sess9

Estado de conversao

Os servidores web no tm memria curta. Assim que eles lhe enviam uma resposta, eles esquecem quem voc . Na prxima vez que voc fizer uma solicitao, eles no o reconhecero. Em outras palavras, eles no se recordam do que voc solicitou no passado e nem do que eles enviaram como resposta. Nada. Algumas vezes isso bom. Porm, algumas vezes voc precisa manter o estado de conversao com o cliente durante vrias solicitaes. Um carrinho de compras no funcionaria se o usurio tivesse que escolher seus produtos e finalizar a compra de uma nica vez. Voc vai encontrar uma soluo extremamente simples na API Servlet.

voc est aqu ;.

223

objetivos do exame oficial da Sun

&12

54;

06jctiV~f

G-eret1cial\tettto de Sesso

Notas sobre a Abrangncia:


Todos os quatro objetivos do exame sobre gerenciamento da sesso so completamente cobertos neste captulo (embora alguns destes tpicos tenham sido falados no captulo anterior). Este captulo a sua nica chance para aprender e memorizar estes assuntos; portanto, v com calma:

4.1 Escrever o cdigo do servlet para armazenar os objetos dentro de um objeto sesso e restaurar os objetos a partir de um objeto sesso.

4.2 Dada uma situao, usadas para acessar explicar quando ele mecanismos usados ele foi destruido.

descrever as APls o objeto sesso, foi criado, descrever os para destru-Io e quando

4.3 Utilizando os listeners da sesso, escrever o cdigo para responder a um evento quando um objeto adicionado a uma sesso; escrever o cdigo para responder a um evento quando um objeto sesso migra de uma VM para outra.

4.4 Dada uma situao, descrever qual o mecanismo de gerenciamento da sesso o Container pode empregar, como os cookies podem ser usados para gerenciar as sesses, como a reescrita de URL pode ser til no gerenciamento das sesses e escrever o cdigo do servlet para executar a reescrita de URL.

224 capitulo 6

gerenciamento

da sessiD

Eu quero que a aplicao da cerveja tenha uma conversa bidirecional com o cliente ... no seria legal se o usurio respondesse a uma pergunta, e a aplicao respondesse com uma nova pergunta, baseada nas respostas anteriores?

o o

Kil\t quer l\tattter a cotwersao especfica COl\to cliettte durattte as vrias solicitaes
Agora, a lgica do negcio no modelo checa o parmetro que vem da solicitao e devolve uma resposta (o conselho). Ningum na aplicao se lembra de nada que tenha ficado com este cliente antes da solicitao atual.

o que ele tem AGORA:


public class BeerExpert { public ArrayList getBrands(String color) ArrayList brands = new ArrayList(); brands.add(~Jack Amber"); if brands.add(~Red (color.equals(~amber")) { Moose"); else { Stout"); Pale Ale");

~\
II

brands.add(~Gout brands.add(~Jail return brands;

\\\

/IJ:Sct.ecalJ'tCSe~1'6t/e

e~I'4il4
resf~
".

<Cor)

I,""'l~

e tl&61veIM.6S

rela'i4" ti4S
<fi

3t1f p6SstlflJ\ ~tlfla c6r). ~C4S "146 e c6#'Ise!l.t:ll>'Ul


(1.10\

s-k

, tic $1e56c1(;) / 'n:"1J't L D IJ'tctielc (a ICjtCa


".

ave tiesccbrtr svltete,,-h fara

se "'a 1~/erlJ'taS4C la;er VlJ\4

O que ele QUER:


public class BeerExpert { public NextResponse getAdvice(String answer) Processar a resposta do cliente procurando em TODAS as Ilrespostas anteriores dele, assim como na resposta da Ilsolicitao atual. Se houver informao suficiente, Ilretornar o conselho final, ou ento, retornar a prxima pergunta

reC6IJ'te#'/tiS4e(ev s!ia., tiar tilca II~IJ.{)J e case #'/4Ct.'Ea., ele +e Jve


, J / e#'/vllr a fr6X1'lM,apel'5(1'Tr"a 0.6 (lSVar,6.

li

SVp6ltka ve a classe AJex1-Jeesf6ltse (ltc4psv1e p41'4 <3 vsv:l'tt. e 4~1.l ve ,'l'Jd'jv( se es+e

<3

fl':Xi"IYII.l

<t

seI' eXi!J,i/.

()Ctmse'&.1J

IJVav.fl'Q. fel'~ voc est

aqui..

225

conversao com cliente

Ueve funcionar

COtMOutMa conversa

NORMAL ...
Drinque com guarda-chuva vermelho? Oooooh, isso RUIM. Foi bom voc ter ligado ... deixe-me perguntar uma coisa: primeiro, voc quer escura, bock ou clara?

Cara, eu estou numa festa aqui em Joe's beach e estou segurando, literalmente, um drinque com um lindo guarda-chuva vermelho ... voc precisa trazer cerveja para c AGORA!

D
o

o
Q

o
Cl

ia.
226

gerenciamento

da ~

COtMO ele pode tMotltorar as respostas

do eliettte?

o projeto

do Rim s funcionar se ele puder acompanhar tudo que o cliente j tenha dito durante a conversa, e no apenas a resposta da solicitao atual. Ele precisa do servlet para conseguir os parmetros da solicitao. que representam as opes do cliente e salv-Ios em algum lugar. Cada vez que o cliente responde uma pergunta, o mecanismo de conselhos usa todas as respostas anteriores dele para retomar ou uma outra pergunta, ou a recomendao final. Quais so as opes?

Usar um enterprise javabean stateful session


Claro, ele poderia fazer isso. Ele poderia transformar seu servlet em um cliente para um bean stateful session, e toda vez que uma solicitao chegasse, ele poderia localizar este bean. Daria um certo trabalho, mas sim, voc pode certamente usar um bean stateful session para armazenar um estado de conversao. Mas isto geraria muito trfego. Mataria a aplicao! Alm disso, o provedor de hospedagem do Rim no tem um servidor J2EE completo com um Container EJB. Ele tem um Tomcat (um Container web) e s.

o 9bJet9

BttpSess'I9n

p9de mlnter 9 estld9 de C9nv'erSly9durante vrIas s91'lc1tlyges d9 mesm9 cl1ente. Em 9uttlS plIlv'tQ,'5. ele pers'Iste p9t uml sess9 v Intelrl C9m um detetm'Inld9 clIente.

Usar um banco de dados


Isto tambm funcionaria. O provedor dele permite acesso ao MySQL; portanto, ele poderia fazer isto. Ele poderia escrever os dados do cliente em um banco de dados ... mas isto impacta a performance de runtime, da mesma forma que o enterprise bean o faria, talvez at mais. E muito mais do que ele precisa.

Usar um HttpSession
Mas voc j para sabiamanter disso. Ns podemos usar um objeto HttpSession o estado de conversao durante vrias solicitaes. Ou seja, para uma sesso inteira com este cliente.

f9dem9s

us-19

gUqtdm tUd9 que recel~m9s .v d9 clIente em t9dQ,':llS

(De fato, o Rim ainda teria que usar um HttpSession, S91lCltaygeS ~.,ueele mesmo que ele escolhesse outra opo, como um banco de dados ou uma sesso bean, pois se o cliente um browser, dutlnte ele ainda teria que fazer coincidir um cliente especfico com um banco de dados especfico, ou a ID do session bean. Como voc ver neste captulo, o HttpSession cuida desta identificao.) voc est

taz

sesses em ao

Co",o as sesses funciona",

Diane seleciona "Escura" e c1icano boto submit.

o Container envia a solicitao


para uma nova thread do servlet BeerApp.

A thread BeerApp encontra a sesso associada a Diane e guarda a sua escolha ("Escura") como um atributo na sesso.
SetAtributeO

o servlet executa a sua lgica (inclusive chama o modelo) e retorna uma resposta ... neste caso, uma outra pergunta: "Qual a variao do preo?"

Diane l a nova pergunta na pgina, seleciona "Cara" e pressiona o boto submit. O Containerenvia a solicitao para uma nova thread do servlet BeerApp.

A thread BeerApp encontra a sesso associada Diane e armazena a Suanova escolha ("Cara") como um atributo na sesso.

Mesmo cliente Mesmo servlet Solicitao diferente Thread diferente Mesma sesso

/ Set AtributeO

228 captulo 6

gerenciamento

da

Oservlet roda sua lgica (inclusive chama o modelo) e retorno uma resposta ... neste caso, uma outra pergunta.

Nesse meio tempo, imagine que OUTRO cliente vai para o site de cerveja.,
A sesso de Diane ainda est ativa, mas enquanto isso, Terri seleciona "Clara" e pressiona o boto submit.

o Container envia a solicitao de Terri para uma nova thread no servlet BeerApp.

A thread BeerApp inicia uma nova Sesso para Terr e chama o setAttributeO para armazena a sua escolha ("Clara").

Cliente diferente Mesmo servlet Solicitao diferente Thread diferente Sesso diferente

IJ,tS

svel'tll\s

ve as l'eSp6s+as

da. 11'I'l e da. blal7e se ",rs+vN:",

p61'+a.17+6;cada vII\a precisa. d sev tje+ S(f!ss;'SeparfJ.d.

voc est aqui ~

22

identificando

o clente

UtIt probletlta ... COtltOO Contaitter vai saber quetlt

Como o Container reconhecer que a Diane e no a Terri? O HTTP stateless, portanto, cada solicitao uma nova conexo ...

cliettte1

o protocolo HTTP usa conexes stateless. O browser do cliente faz uma conexo para o servidor, envia a solicitao, obtm a resposta e fecha a conexo. Ou seja, a conexo existe apenas para uma nica solicitao/resposta. Devido conexo no persistir, o Container no reconhece que o cliente que fez a segunda solicitao o mesmo de uma solicitao anterior. Para o Container, cada solicitao de um novo cliente.
Eu sinto muito, mas no me lembro de voc. Tenho certeza que ns dividimos bons momentos juntos, mas teremos que recomear.

o a

o
tJ

() o

N9 ex1st~m

feth'untas ldl9tas

r:

Por que o Container no pode simplesmente usar o endereo IP do cliente? parte da solicitao, certo?

r:

Que tal as informaes de segurana? Se o usurio est logado e a conexo segura (HTTPS), o Container sabe EXATAMENTE quem o cliente, certo?

1\: Ah, o Container pode obter o endereo

IP da solicitao, mas isso identifica exclusivamente o cliente? Se voc est em uma rede IP local, voc tem um nico endereo IP, mas h chances de que ele no seja reconhecido externamente. Para o servidor, seu endereo IP o endereo do roteador; logo, voc tem o mesmo endereo IP que todo mundo tem na sua rede! Ento o IP no ajudaria! Voc teria o mesmo problema: os itens do carrinho do Jim poderiam ir parar no carrinho do Pradeep e vice-versa. Ento no, o endereo IP no uma soluo que identifique exclusivamente um determinado cliente na internet.

1\: Sim, se o usurio

est logado e a conexo segura, o Container pode identificar o cliente e associlo a uma sesso. Mas isto um diz: "No force o usurio a fazer login at que seja realmente necessrio, e no troque a segurana (HTTPS) enquanto no for realmente preciso." Se os seus usurios esto s navegando, mesmo que estejam s colocando artigos no carrinho de compras, voc talvez no queira a sobrecarga (para voc ou eles) de tlos autenticados no sistema at que decidam finalizar a compra! Por isso, precisamos de um mecanismo que crie um Iink entre um cliente e uma sesso que no requeira autenticao segura. (Entraremos em detalhes sobre segurana no ... espere por ele ... captulo de Segurana.)

grande "se". A maioria dos bons webdesigners

230 captulo 6

gerencamento

da sessc

o cliettte

precisa deut\ta nica session lU

A idia simples: na primeira solicitao do cliente, o Container gera uma nica session ID e a devolve para o cliente juntamente com a resposta. O cliente envia de volta a session ID com cada solicitao subseqente. O Container verifica o ID, encontra a sesso correspondente e a associa solicitao.

Sim, mas eu no guardo o estado das solicitaes e no me lembrarei de voc. Por isso, estou te dando uma nica session ID. Voc DEVE me devolv-Ia toda vez que fizer uma solicitao e eu saberei quem voc

o
Cl

solicitao , "ale", ID n-42 o

container

voc est

alegria dos cookies

Como o Cliente e o Container trocam as informaes da Session lO?


De alguma fonua, o Container tem que entregar a session ID para o cliente como parte da resposta. Por sua vez, o cliente tem que devolver a session ID como parte da solicitao. A maneira mais simples e comum para essa troca de infonuaes atravs de cookies.

Cooldes

n,e apel1l1.S f) H Se-l-c.lJIJl:te


t.eatiel' e"vl'4tic
114

I. FoI/rrl'''

I'f!SPOS';"4.

Aqui est o seu cookie com uma

session ID dentro ...

SetCookle. JS 0EKSSIONIO=OAAB6C80E415 HTTP/1.1 ?~O


Content-Type: Content-Length: text/html 3t 2003 03:25:40 GMT

SelVer: Apache-Coyote/1.1 Connection: close

<html>

"C/;J:,"e"

VI/f! IJV';"I'IJ t.eatier


J>;tJ

petittllJ Tudo bem, aqui est o cookie com a minha solicitao

POST

/select/selectBeerTaste

2 .d o HTTP/1.1

Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 _

Cookie: JSESSIONID-O r tion/xml


Accept: text/xml,ap~ Accept-Language: Accept-Encoding:

AAB6C8DE415 ..
apphcatlonl / 9 if'q=O.2,*I*;q=O.1 ,

I:~

9 text/~lain;q=o.8,video/x-

xhtml+xml,textlhtml,qmng,image/png,image/Jpeg,lmage .. '.

en-us, enq-O ,-. 5 gzip,defiate

232 captulo 6

gerencamento

da sesso

A tMelhor parte: o Container faz quase todo o trabalho do cooldel


Voc tem que informar ao Container que voc quer criar ou usar uma sesso, mas o Container que gera a session ID, criando um novo objeto Cookie, inserindo a session ID dentro do cookie e configurando o cookie como parte da resposta. E nas solicitaes subseqentes, o Container recebe a session ID de um cookie da solicitao, compara-a com uma sesso existente e associa essa sesso com a solicitao atual.

HttpSession

session

request.getSession(}

isso a. Em algum lugar do seu mtodo voc solicita uma sesso e as demais tarefas acontecem automaticamente.
Voc Voc Voc Voc no no no no cria o novo objeto HttpSession. gera a session ID exclusiva. cria o novo objeto Cookie. associa a session ID com o cookie.

Voc no configura o Cookie na resposta (sob o header Set-Cookie). Todo o trabalho do cookie acontece nos bastidores.

Obtendo a sesso ID da SOLICITAO:


HttpSession session

= request.getSession()

; ~

() Wle.f"JIJ sessllJI'I.....
IJ.

f(;.I1i.

()

fJ

~.,.f.Jt.11'"

CD,,/:."e

Parece familiar? Sim, exatamente o mesmo mtodo usado para gerar a session ID e o cooke para a respostat

. !J) (e CDl'l'e/4c"()"II.-11J h"./-e> "

IF (a solicitaco inclui um cookie da session lD)


encontrar a sessao que se corre aCIona com a ELSE IF (no existe nenhum cookie session ID or no existe no momento nenhuma sesso correlacionada session ID) criar nova sesso

11W1fJ.

I.

ID

Wles",D flJ.l'J)1J. Sf!SSliJI'I'

.! ~~~ . ... . vi.

.
"C4

sf!S S4"

;;~~A-Jt.
11'"

C04/:.1e .

( ",1101'4 VDCe fDS S4 4 seSSIDYi e ,) '\H l1e IJ I;,.IM'",e


SDI,.c,..f41' I.l seSS41J Z

Todo o trabalho do cookie acontece nos bastidores.

voc est

hecando par1 uma nova sesso

: se eu quiser saber se a sesso j existia ou ;oi eriada agora?


~oa pergunta. O mtodo de solicitao-padro, ~etSessionO, retoma uma sesso independentemente de ~xistir uma sesso anterior. J que voc sempre obtm uma nstncia HtlpSession daquele mtodo, o nico jeito de ;aber se a sesso nova seria perguntando a ela.

public void doGet(HttpServletRequest

request, HttpServletResponse response) throws IOException, ServletException () 5e.-I-.:5essi:mO N


() ; seilPlf>l"e re-/-lJl"n4
N

respons~. setContentType ("text/ht~l") ; PrlntWrlter out = response.getWrlter(); out.println ("test session attributes<br>"); HttpSession session
= request. getSession

V::--.

V;1I14 sessa6 ;1I1asV4ce nil ftJJe f N 0.1'1";11141" se e vll>la sessa6 "(JVil) a ;1I1en4S!ve v6c per5vnff

a ela.

if

(SeSsion.isNeW(~

() tsAJewO se

re.flJl"nQ, ClJII>I vel"JaJei'ra Q,17Jfi. "lJ l"eSp4nJef.l

out.println ("This is a new session. "); else { out.println("Welcome back!");

6 c/te,,+e

ca;1l1 es.f-e Sesst4"

Z.

Y:

Voc obtm uma sesso chamando o request.getSessionO, mas esse o nico jeito de consegui-Ia? No podemos usar o ServletContext?

Os mtodos que tratam o evento, definidos pelas nterfaces do Iistener relacionados s sesses, recebem um argumento do tipo HUpSessionEvent, ou sua subclasse, HUpSessionBindingEvent. E o HUpSessionEvent trn um mtodo getSessionOl Ento, se voc implementa alguma das quatro interfaces lstener relacionadas s sesses (falaremos sobre esse assunto mais adiante neste captulo), voc pode acessar a sesso atravs dos mtodos de callback que tratam o evento. Por exemplo, este cdigo de uma classe que implementa a interface HUpSessionListener: public void sessionCreated(HttpSessionEvent event) { HttpSession session =

1\:

Voc obtm uma sesso atravs do objeto response porque - adivinha - a sesso identificada pela solicitao. Quando voc chama o getSessionO no Container voc est dizendo: "Eu quero uma sesso para ESTE cliente ... ou a sesso que coincide com a session ID enviada pelo cliente, ou uma nova. Mas, em ambos os casos, a sesso para o cliente associado com esta solicitao." Mas existe um outro jeito de voc conseguir a sesso ... atravs de um objeto evento da sesso. Lembre-se, uma classe listener no um servlet ou um JSP - apenas uma classe que quer conhecer os eventos. Por exemplo, o listener pode ser um atributo tentando descobrir quando ele (o objeto atributo) foi adicionado ou removido de uma sesso.

evento

getSession () ;

Ii

evento que segura o cdigo

234

gerencamento

da sesso

se eu quiser APENAS uifta sesso pr-existettte?

Voc pode se deparar com uma situao na qual o servlet quer usar apenas uma sesso j criada. Pode no fazer sentido para o servlet responsvel pelo checkout, por exemplo, iniciar uma nova sesso. Ento, existe um mtodo sobrecarregado getSession (booleano) apenas para esse propsito. Se voc no quer criar uma sesso nova, chame o getSession (false) e voc obter ou um HttpSession nulo, ou um j existente. O cdigo abaixo chama o getSession (false) e verifica se o valor retomado foi nulo. Se/ai nulo, o cdigo exibe uma mensagem e ento cria uma nova sesso.
public throws void doGet(HttpServletRequest IOException, ServletException request, { HttpServletResponse response)

{) N N nJ,sS(V' /4Is(J sl;,,/'I1"(;4


response.setContentType(~text/htrnl");_J PrintWri ter out = response. getWri ter (); out. println (~test sessions<br>");

I II';.+IJJa
J_

rer6r,,4

ViJI';tJ.

N._pre-exls-n:~ J_ seSS46

6V ~/tl.J C4S6 "';,6 t,~4 ~11;"lIiltla St!SS'i6 ~ aSS6Cl'aJtJ. a

HttpSession

session

em c1t"ePrh.
I

request.getSession(false);

if

(session=null).

,,:S paJell';6S +es-f-ar exts-/-ta VII';tJ. sess';,(J


fJr3vt

out.println(~no seSSlon was avallable"); out.println (~rnaking one ... "); else { out.println(~there was a session!"); session ~ request.getSession(); ~

N. paJra6
resv

I 11. tvfhv'Crr
J
<:)

.,.a"l6 I1V

I'

!.,)
alie

A-3vt '",:s SA-$M,tJS N


vII';a l7(Jva ses S/t,6.

r: o
I\:

cdigo acima no simplesmente uma forma ineficiente e tola de fazer a mesma coisa da pgina anterior? No fim das contas, voc acabou criando uma nova sesso.

r:

Ento, parece que o getSession(true) eX;atamente o mesmo que o getSessionO ...

I\:

Voc est certo. O cdigo acima apenas para testar como funcionam as duas verses do getSessionO . No mundo real, a nica vez que voc pode querer usar o getSession (false) quando voc NO quer criar uma sesso nova. Se o seu objetivo for criar uma sesso nova e ainda assim, responder de forma diferente se voc sabe que ela uma sesso nova (e no uma que j exista), use o mtodo getSessionO padro e pergunte sesso se ela est usando agora o mtodo isNewO do HttpSession.

Acertou novamente. A verso-padro uma convenincia para aquelas ocasies em que voc sabe que quer uma sesso nova ou existente. A verso que leva um booleano til quando voc sabe que no quer uma nova sesso, ou quando a deciso de se criar uma nova verso acontece no runtime (e voc est passando uma varivel no mtodo getSession(algum 800Ieano.

voc est

quando os cookies falham

Voc ~

criar as sesses lfteslftO

quatldo o clietlte tlo aceitar os cookies, Iftas dar Ulftpouco Iftais de trabalho ...
No concordamos que algum com metade do crebro desative os cookies. Na verdade, a maioria dos browsers j tem cookies habilitados e tudo maravilhoso. Mas no h garantias. Se sua aplicao depende das sesses, voc precisa de um modo diferente para o cliente e o Container trocarem informaes sobre a session ID. Sorte para voc, pois o Container sabe como tratar um cliente que reCUSaum cookie, mas isto requer um pouco mais de esforo da SUaparte. Se Voc usar o cdigo da sesso da pgina anterior ~ chamando o getSessionO na solicitao ~ o Container tenta Usar os cOokies. Se os cookies no estiverem habilitados, significa que o cliente nUnca se juntar sesso. Ou seja, o mtodo isNewo da sesso se111preretrna verdadeiro.

O COI1"l Osders "Set-Cookie" da ircliente ignorar os hea

cookie$ desabilitados

, N receber nenhuma . . kies voce nao . . Se um cliente no acertar :o~a ou' sirene soar para mformao Nenhuma campam .. . ma sesso para este qu~ a sua ''':.'ta'',ad;ou~;~~er que o clien,eignora

resposta

'f::~

cliente falh~u. ~a~:::k:~a~ um cookie comRL .. a s~s:;~:~~e . . a sua tentatlva e .. ..' rO. eescreve a U ,s ~ 'd"go se voce N/1. r , 7\TOVA sessao (rsto e, ., h ar No seu co l. , t . nara uma lV' o get&",ionO sem~r~:: quaudv "7,ce,':u,;;;; que uma ..'P. r. e re Z' t. ~~erdadeiro" nunca dev.olve o tenha isNewv . que. um risem header ne l,i a/o O do c coa rene kie daseSSlOn . ID .uma so ler

236

gerenciamento

da sesso

Reescrita de URl.: utlta alterttativa


Se o cliente no aceitar cookies, voc pode usar a reescrita de URL como uma segunda opo. Supondo que voc faa a sua parte corretamente, a reescrita de URL sempre funcionar - o cliente no se importa com o que est acontecendo e no faz nada para impedir. Lembre-se de que o objetivo que o cliente e o Container troquem informaes sobre a session ID. Trocar cookies a maneira mais simples de compartilhar session IDs. Mas se voc no puder colocar uma ID num cookie, onde voc o colocar? A reescrita de URL carrega a session ID que est no cookie e a encaixa bem no final de cada URL que a aplicao recebe. Imagine uma pgina em que todos os links tenham um pouco de informao extra (a session ID) direcionada para o final da URL. Quando o usurio clicar naquele link "melhorado", a solicitao vai para o Container com aquele bit extra no final, e o Container simplesmente retira a parte extra da URL e a usa para encontrar a sesso correspondente.

;isess,on'

"

"d=1234567

HTTP/1.1 200 OK
Content-Length: 3 03'25-40 GMT Date: Wed, 19 Nov 200 .' server:Apache-COyotel1.1 Connection: close <html>

397

AJ,'ciAI'141r10S 4l sf!.Ssu,n I'f'" ~

z"h
!I

1M
'li A f

J", I'A -IA "" as U/t.{...s ntl fVl.'-l)IIf. "' "1"v"'..... I titlltllllf!.IrIOS ;:01rl0 /t.espOS-r4.

rrr
I L

~,

<body> . k dlysmart.comlBeerTest.dO;jSeSSIOmd-O <a href.=''http://WWW.w1c e c1ick me <Ia> </body>

</html>

Resposta HTTP

A- sessl,U"I

,.. /I

Ib 1/01-1-4 ;:0""'0 /I
ex-l-ro.

11""'4

v/riu/ti. e I , espec/!lc6 / GET 1BeerTest c1'. HTTPi1.1 . o,JSeSSlOnid=OAAB6C8DE415


Host: Accept: WWW.wickedrysmart.com

1;'!6rW\4fj4

,;,serltia n ";'0./ fie !drlc41'1-n:.J i._

"ti. vJ(.{... "4 S6IlCl-l-tJ.j. (() p6n-1-ire-

User-Agent:

MOZiJla/5.0

textlxmJ,apPlication

html;q~O.9,teXtlpl .. _ /xml,apPlication/xhtm/+xml -. . .. am,q~O.8,vldeo/x_' ,t extl JPeg,lmage/glf:q~O.2, '/*;q~O.1 mng,lrnage/png,imagel Accept-Langu . A age. en-Us,en;q~O.5 ceePt-EncOding: 9Zip,deflate

Resposta HTIP

voc est

reescrevendo

a URL

A reescrita de URI. S etttra em cetla se os cookies

falharem e S se voc matldar a resposta codificar a URI.


Se os cookies no funcionarem, o Container recorre reescrita de URL, porm s se voc tiver feito o trabalho extra de codificar todas as URLs que voc enviar na resposta. Se voc quiser que o Container fique configurado por padro para usar os cookies primeiro, com a reescrita de URL apenas em ltimo caso, voc pode relaxar. exatamente assim que ele funciona (exceto na primeira vez, mas chegaremos l num minuto). Mas se voc no codificar as suas URLs explicitamente - e o cliente no aceitar cookies -, voc no precisa usar as sesses. Se voc codificar mesmo as suas URLs, o Container primeiro tentar usar os cookies para o gerenciamento da sesso e recorrer reescrita de URL apenas se a tcnica do cookie falhar.
public void doGet(HttpServletRequest request, ; (); ~
J._ N tJb-n::t' Vit\4 seSSfJ,t)

HttpServletResponse throws

response) IOException

response.setContentType("text/html") PrintWriter HttpSession

out ~ response.getWriter(); session = request. getSession

out.println("<html><body>"); out.println ("<a href=\"" + response.encodeURL("/BeerTest.do")


a>/f);

out.println("</body></html>");

+ "\">click

me</

4 1i1ltJt'it\fJ.s'io eX+r4

Ja ses siim

IlJ

ptU'fi. eS+4 UJe.L.

r:

Espere um momento ... como o Container SABE que os cookies no esto funcionando? E em que ponto o Container decide usar a reescrita de URL?

1\: Lembre-se, se o Container no conse~uir uma session 10 do cliente, ele nem SABERA
que esta a prxima solicitao daquele cliente.

O Container no tem como saber que ele


tentou os cookies da ltima vez e que eles no funcionaram. Lembre-se, a NICA forma de o Container reconhecer que ele j viu tal cliente antes se o cliente enviar uma session 10! Ento, quando o Container percebe que voc chamou o request.getSessionO, ele entende que precisa iniciar uma nova sesso com este cliente. Ele envia a resposta com um header "Set-Cookie" para a session 10, e esta, anexada URL (supondo que voc usou o response.encodeURL()). Agora imagine a prxima solicitao deste cliente. Ela ter a session 10 anexada URL da solicitao, mas se o cliente aceitar cookies, a solicitao TAMBM ter um cookie session 10. Quando o servlet chama o request.getSessionO, o Container l a session 10 para a solicitao, encontra a sesso e pensa consigo, "Este cliente aceita cookies, ento posso ignorar as chamadas response.encodeURLO. Na resposta, vou enviar um cookie, pois eu sei que ele funciona. E no h nenhuma necessidade de uma reescrita de URL, por isso, eu nem me preocupo ..."

1\: Um Container

burro de verdade no se preocupa se os cookies esto funcionando ou no - ele vai sempre tentar enviar o cookie E fazer uma reescrita de URL toda vez, mesmo que os cookies estejam funcionando. Mas eis como um Container decente trata isso: Quando o Container v uma chamada para o getSessionO sem que tenha recebido a session 10 com a solicitao do cliente, ele sabe que deve tentar iniciar uma nova sesso com o cliente. At aqui, o Container no sabe se os cookies funcionaro, mas com esta primeira resposta enviada ao cliente, ele tenta os cookies e a reescrita de URL.

r:
238

Por que ele no pode tentar os cookies primeiro ... e fazer a reescrita de URL na prxima resposta, caso no consiga receber um cookie?

captulo 6

gerencamento

da sesso

A reescrita de URL funciona

COIft

o sendRedirectU

Voc pode encontrar uma situao em que voc queira redirecionar a solicitao para uma URL diferente, e ainda assim usar uma sesso. Existe um mtodo para escrever uma URL especial para isso:
response.encodeRedirectURL(~/BeerTest.do")

f:

E quanto a todas as minhas pginas HTML estticas ... elas esto cheias de Iinks <a href>. Como eu fao reescrita de URL nessas pginas estticas?

J\.

teescdta de UI\L
? "

1\: Voc no faz! A nica maneira

de usar a reescrita de URL se TODAS as pginas que so parte de uma sesso forem dinmicas! Voc no pode fazer um hard-code das session 10s, obviamente, visto que o 10 no existe at o momento da execuo. Ento, se voc depende das sesses, voc precisa da reescrita de URL como uma estratgia alternativa. E j que voc precisa da reescrita de URL, voc tem que gerar dinamicamente as URLs na resposta HTML! O que significa que voc teria que processar o HTML no runtime. Sim, esta uma que~to de performance. Portanto, voc_ deve pensar com carinho sobre os lugares onde as sessoes s~~ importa~tes para a sua aplicao - e se elas so cntlcas ou simplesmente boas.

aut9mlfica... Y9ce c9d'itlc9u suas UI\Ls. VOC tem ~ue t9dat t9das as suas UI\Ls lttavs d9 mt9d9 de 9bjet9 tesp9:'!ta - enc9deUItL() 9U enc9deIted'itectUItL() - e 9 C9nta1nett\:Z

f:

Voc disse que para usarmos a reescrita de URL, as pginas devem ser dinmicas. Portanto, quer dizer que eu posso fazer isso com os JSPs?

1\: Sim! Voc pode criar uma reescrita

de URL em um JSP. Existe at uma tag JSTL bem simples que faz isso facilmente, <c:URL>, que voc ver quando chegar no captulo que trata das tags customizadas.

-o da URL A codificaa Resposta! tratada peta


e o mtodo

f:

1\:

No se esque~ dei qUque voc chame: nO seu encode URLO e a go onse! roce nao o . HttpServletResp objeto . - nem no seu contexto chama na sOliclta?aoLembre_se de que o Sim, a reescrita de URL especfica por fabricante. O objeto sessao. _ d URL todo Tomcat usa o ponto-e-vrgula ";" para anexar a informao oU no d e codijicaao a rocesSo extra URL. Outro fabricante talvez use uma vrgula ou p . d resposta. relacwna o algo diferente. E enquanto o Tomcat adiciona "jsessionid=" na URL reescrita, outro fabricante pode anexar apenas a session 10 em si. A questo , aquilo que o Container usa como separador reconhecido por ele quando uma solicitao chega. Ento, quando o Container encontra um separador que ele usa (ou seja, o separador que ele adicionou durante a reescrita de URL), ele sabe que tudo o que vem depois "informao extra" que ele mesmo colocou l. Em outras palavras, o Container sabe como reconhecer e analisar o material extra que ele (o Container) anexou URL.
TT. A

A reescrita de URL especfica por fabricante?

voc est

239

gerencando sesso

No seja enganado com o parmetro da solicitao "jsessionid" ou o header "JSESSIONID".


VOC no deve jamais usar o "jsessionid". Se voc encontrar um parmetro de solicitao "jsessionid", algum est fazendo algo errado. Voc nunca deveria ver algo assim:
String sessionID = request.getParameter(~js

E voc no deveria ver um header customizado


POST Iselect/selectBeerTaste.do

"jsessionid"

em uma solicitao ou resposta:

HTTP/l.l

UserJSE Alis, o

ent:

Mozilla/5.0

NIco

ID: OAAB6C8DE415 lugar em que um "jsessionid"

f--

:5YI';e-se 3ve s~a V~ "faJet'! deve ficar dentro de um header cookie:

POST /select/selectBeerTaste.do

HTTP/l.l

User-Agent: Mozilla/5.0 Cookie: JSESSIONID=OAAB6C8DE415~

IS+6

'_ es+aeet'+6; extra'"

""as 174611'1.]1'1.1'61' si 8I'leslfl.t'J.


() I'f!Su!.f.aJ6 J4 l"eesct'/-+lI. e

Ou anexado no final de uma URL como "informao

,
POST /select/selectBeerTaste.

,
do; sessionid=OAAB6C8DE415 ~

lJ/t.L. (voc h~!Jlfl. la5el" /'S+O).

17a'<1

deve

Pootos de bala A reescrita de URL adici ' as URLs no HTML que v o?a a seSSlOnID no final de todas oce eSCreve na resposta. A session ID retoma "extra" no final da URLcomla so ICla ..sOdlcltaOcomo a, informao A reescrita de URL Ocorrer auto ' no funcionarem com o di . t . matIca~ente se os cookies explicitamente todas as U~ e, mas V?Ce tem que codificar s que voce escrever, Para codificar uma URL h encodeURL( uma s' tnng). ., c ame tesponse.
oUt.print1n(~<a href='. + response,enco4eURL(~/ + ~'> I' BeerTest,4o"}
c lck me</a>");

r'

No existe forma de con .' , automtica nas SuasPg::~=a reescnta de URL das sesses voc deve usar . ,~as. Logo, se voc depende , as pagmas geradas dinamicamente,

240

gerenciamento

da sesso

Livrat'ldo-se das sesses


A cliente entra, inicia uma sesso, muda de idia e sai do site. Ou a cliente entra, inicia uma sesso e seu browser trava. Ou a cliente entra, inicia uma sesso e a finaliza fazendo uma compra (check-out do carrinho de compras). Ou o computador dela trava. Seja o que/oro A questo que os objetos da sesso usam recursos. Voc no quer que as sesses fiquem l alm do tempo necessrio. Lembre-se, o protocolo HTTP no tem nenhum mecanismo que informe ao servidor que a cliente j foi. (Em termos de aplicao distribuda, para aqueles que esto familiarizados, no h nenhum leasing.)* Mas como o Container (ou voc) sabe que a cliente foi embora? Como o Container sabe que o browser da cliente travou? Como o Container sabe que seguro destruir uma sesso?

(le 3ver
"1a "

II./lAl'dal'

eSfp'ylJ

-n.e S,.s ca"'" PIU:".f.e " li";,, ba.f.e" ,.)

si/a ."a~i/I"'a p4ra vjatl41' fJ" "

Quais seriam as estratgias que voc (e o Container) usariam para gerenciar o nmero de sesses e eliminar as desnecessrias? Quais so algumas das maneiras possveis que o Container poderia saber que uma sesso no mais necessria? Pense um pouco e d uma olhada na API HttpSession algumas pginas adiante para conseguir algumas dicas.

"Algumas aplicaes distribudas usam o leasing como forma do servidor saber que a cliente se foi. A cliente recebe um lease do servidor e deve renov-Io em intervalos especficos, informando ao servidor que ela ainda est l. Se o lease da cliente expirar, o servidor sabe que pode destruir qualquer recurso que mantinha para a cliente .

voc est

."

241

sesses abandonadas

CotttO queretttos que ele futtciotte ...


Gostaramos que o Container reconhecesse quando uma sesso ficasse inativa por muito tempo e a destrusse. claro que teramos que brigar com o Container para que ele soubesse o que "muito tempo" realmente quer dizer. Vinte minutos muito tempo? Uma hora? Um dia? (Talvez exista uma maneira de informarmos ao Container o que "muito tempo".)

Diane seleciona "Escura" e c1ica no boto submit.

o Container

envia a

solicitao para uma nova thread do servlet BeerApp.

Container cria uma nova sesso, ID n 343. O cookie "JSESSIONID" enviado de volta para Diane na resposta (no exibido).

Web Container

Diane desaparece misteriosamente.

O Container faz o que qualquer Container faria em seu tempo vago (embora provavelmente haja um monte de clientes a serem atendidos).

A sesso iniciada por Diane ainda est l... esperando ... abandonada.

Web Container

Diane no retorna. Os minutos passam ...

O Container

checa o estado da sesso

O Container

diz "20 minutos

n 343 e descobre que nenhuma solicitao chegou com aquela session ID durante 20 minutos.

tempo. Ela no voltou.", e destri a pobre e abandonada sesso.

muito

Web Container

242

captulo6

gerenciamento

da sesso

A itrterface flttpSessiot1
Tudo com o que voc se preocupa quando chama o getSessionO que voc receba uma instncia de uma classe que implemente a interface HtlpSession. tarefa do Container criar a implementao. Uma vez que voc consegue uma sesso, o que voc podejazer com ela? Na maioria das vezes, voc usar as sesses para receber e configurar os atributos do escopo sesso. Mas tem mais, claro. Veja se voc consegue descobrir sozinho alguns dos mtodos mais importantes. (As respostas esto na prxima pgina, ento no vire!)

. <<interface>> Javux.servlethttp Ri Ob. . ttpSession lo;:ect getAttribute(String) g getCreationTi String getIdO llneO long getLastAcc . int getMaxIna .essedTllneO ServletC ctzveIntervalO . ontext getSer vozd invalidateO v etContexto bO~leanisNewo Vozdr. enzoveAttrib " void setAttr"b ute(Strzng) " z ute(Strin O" void setMaxIn " g, bJect) /; alguns Outro actz~eInterval(int) os Inetodos
1<

pnte seU lpIS

o que

ele faz

Para que voc o usaria

getCreation TimeO

getLastAccessedTimeO

setMaxlnactivelntervalO

getMaxlnactivelntervalO

invalidateO

voc est

. 243

mtodos HttpSesson

Os prit'lcipais ttttodos HttpSessiot'l


Voc j conhece os mtodos para atributos (getAttributeO, setAttributeO, removeAttribute()), mas aqui esto alguns dos mais importantes de que voc pode precisar na sua aplicao (e que podem cair na prova).

a do os, te

recebeu uma que voc quer permitir permitido entre as criada pela primeira tempo. Por exemplo, voc pode dizer: "Uma existe mais e os atributos foram removidos armazenados nesta que sua matar sesso uma seja sesso, invalidada. caso o cliente h muito tempo, voc enviar um e-mail Descobrir a durao da sesso. Voc nenhuma invalidateO solicitao na sesso. nesta sesso. Esta uma Para determinar por quanto tempo uma pode decidir restringir que certas sesses do objeto sesso. pelo o O cliente invalidate Container, finaliza significa mas uma isso compra que no a session nos ou importa. se ID Ioga). no esteja inativo ou se voc SOUBER que a para perguntando tenha pela depois ltima fazer decidir descobrir passado, que com um vez que, se sem certo quando que ele esta caso vai uma que perodo sesso. o um retomar. o sesso cliente cliente cliente Voc de seja tempo tenha Ou tenha pode acessou encerrada, usar sado feito us-Io o Aa tempo das formas um pode cliente de permanecer reduzir inativo a quantidade inativa ainda possui, sem de perder sesses antes ultrapassem um determinado perodo de sesso instncia terminou da sesso (por em exemplo, si pode ser depois reciclada que validade. Voc pode us-Io para julgar quanto Retoma o momento vez para logado, completar voc este tem formulrio exatamente ..." IO minutos paradas no seu servidor.

o que

ele faz

Para que voc o usaria

SUA
Agora que voc j conhece estes mtodos, voc consegue definir uma estratgia que elimine as sesses abandonadas?

244 captulo 6

gerencamento

da sesso

Cot1figurat1do
Voc no pode estar falando srio ... ento quer dizer que eu tenho que acompanhar a atividade da sesso e que eu tenho que matar as sesses inativas? O Container no pode fazer isso?

titMeout da sesso

Boas notcias: no voc que vai acompanhar isto. Est vendo aqueles mtodos acima? Voc no tem que us-Ios para se livrar das sesses mortas (inativas). O Container pode fazer isto para voc. Trs formas de matar uma sesso: ~ Por timeout

D o

~ Voc chama o invalidateO no objeto sesso ~ A aplicao cai (trava ou no distribuda)

Configurando

o timeout da sesso no DO

Configurar o timeout no DD tem quase o mesmo efeito que chamar o setMaxInactiveIntervalO em cada sesso que criada.

() 7'> es+:
<web-app <servlet> </servlet>

elJ\ 1J\/~(,rfIJs.1.le ;:/lj 3l1E'se

...> (J cllE'l1+e l1'liIJ

fljer

l1el1t.lIlJ\4 s(Jlict+4S'li1J

I S(!!S SiM N eJt\ I';> "Tr. Jt\ll1l1"T'IJ$j1J\4rt'-4. 1 I_;t l1es'T'/J.

-l, <session-config> <session-timeout>lS</session-timeout> </session-config> </web-app>

Configurando

o timeout para uma sesso especfica

Se voc quiser alterar o valor do session-timeout para uma instncia de sesso especfica (sem afetar a durao do timeout em nenhuma sesso da aplicao):

session.setMaxlnactivelnterval(20*60);

:5:
Os timeouts no DD esto em MINUTOS! Eis aqui uma enorme incon!istnci~ que devemos prestar atenao ... voce especifica timeouts no DD usando MINUTOS, mas se voc configura: um timeout programtico, voc especifica em SEGUNDOS!

"
#.

st'ss(J 114

"
tJ

() ar/t/ll>lel1+tJ

lia!

11 iJc ct.aJt\Q

u-fa

(:'11>I

Jt\'e'T(J;:/ (J e !.

I.

e-fa;:/a.

~lIe se l1el1l.t/lI>I#. II>IIi1l1+6S;

"tjer

voc est aqui ~

245

exerccio do intervalo da sesso

~
;; ~;; q

Especifiqu~ no DD e programatlcamente, que uma . sesso deve ser destru da, se ela no receber nenhuma solicitao por 20 minutos. Ns colocamos o primeiro m no servlet para voc e possvel que voc nem use todos.

Im de GeladeIra

o O

;nactive-interva1> <max-~ </session-con

-Servlet----------------------------public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException

I HttpSession

ao
getServletContext() .getSession(); setMaxlnact' . lvelnterval(
_ [setTimeout(

12000

D~

L-:.=J
(
!

I request

.\

[]

I-se-S-S-i-o-n-II ,etSmionTimeout

246

e8pJ'fulo

gerencamento

da sesso

SEJA 9 C91lta1ne,t Cada um d9S c9dlg9s abaI)(9 t91 te,tltad9 de, um BttpSe,ty'le,t c9mpI1ad9. Se,u ttaba.1h9 ~ pe,nsat C9m9 9 C9ntaIne,t e, de,te,tmlnat 9 'lpe, y'aI aC9nte,Ce,t'Luand9 cada um de,ste,s se,ty'le,ts t9t chamad9 duas y'e,ze-spe,19 me,sm9 clle,nte,. De,scte,y'a 9 'Lue,aC9nte,Ce,na pdme,lta e, na se,gunda y'e,z 'Lue,9 me,sm9 clIe,nte, ace,ssa 9 se,ty'le,t.
~PUbliC void doGet(HttpServletRequest request, HttpServletResponse throws response) IOException

response.setContentType(~text/htrnl"); PrintWriter out = response.getWriter(); HttpSession session ~ request.getSession(); session.setAttribute(~foo", ~42"); session.setAttribute(~bar", ~420"); session.invalidate() ; String foo = (String) session.getAttribute(~foo"); out~println(~Foo: ~ + foo);

~PUbliC

void

doGet(HttpServletRequest

request,

HttpServletResponse throws

response) IOException

response.setContentType(~text/htrnl"); PrintWriter out ~ response.getWriter(); HttpSession session ~ request.getSession(); session.setAttribute(~foo", ~42"); session.setMaxlnactivelnterval(O); String foo = (String) session.getAttribute(~foo"); if (session.isNew()) { out.println(~This is a new session."); else { out.println(~Welcorne back!");

out.println(~Foo:

~ + foo);

voc est

247

respostas dos exerccos

Im de G-eltdeltt
l\esp9staB

Especifique no DD e programaticamente, que uma sesso deve ser destruda, se ela no receber nenhuma solicitao por 20 minutos.

I <web-app

...> I

Leliflbre-sf?.J ., +i"lifle"v-f-~.,
I <session-con g> I

blJ ~

~especi'flcI4I"

f!1ifl

Il.{ItJfJro's.

<session-timeout>

I~

</session-timeout>

I <I session-con
I </web-app> I

g>

~Servlet------ ------------------------public void doGet(HttpServletRequest request, HttpServletResponse throws response) IOException

[ HttpSession

11

session

[J

request. getSession

();

lsession.

setMaxlnactivelnterval(

[1200

I~

LeJM.f,re-se;

.,

e.sped/lctJ.llIJ elifl

248 CBtJ,'tulo 6

gerenciamento

da sesso

SBJ A

9 C9l1tl1net

I\esp9st:ls

public

void

doGet(HttpServletRequest

request,

HttpServletResponse throws

response) IOException

response.setContentType(~text/html"); PrintWriter out = response.getWriter(); HttpSession session ~ request.getSession();

session. setAttribute

("foa", "42") i
~420");

session.setAttribute(~bar", session.invalidate() ; String foo =

(String)sesslon.ge~~~ribute(~foo"); ~ + foo);

<'

out.println(~Foo:

~
><r! M.Vt.f.4 -I-I!./'de pa/'I!. ct.l!.tfP,a/'

Resultado: ocorrer uma exceo de runtime (lllegaIStateException), porque voc no pode ter um atributo DEPOIS que uma sesso j tenha sido invalidada.

5e+A'ff/'lbvh

114Sf!S S6P/'1JVf!

f!14j: FoI

public

void

doGet(HttpServletRequest

request,

HttpServletResponse throws

response) IOException

response.setContentType(~text/html"); PrintWriter out = response.getWriter(); HttpSession session ~ request.getSession(); session.setAttribute(~foo", ~42"); session.setMaxlnactivelnterval(O);

A-3Vl es-h.*t6S -A""ev-I-

IJ-d.pIl}ro

161"5411d6 v*t dI/.

.seSS6Jf>61$ eS+4*t.:)s dl;f!l1da:

-A""e(w-l- depill'$ de ()
if (session.isNew() out.println(~This else { { i~ back!"); Ai. (~foo") ) ; ts

de 1;'tJ.-A.lldl/.de.

out. println (~Welcome

p"de ew();tfP,

Ct.QtfP,fU'
""

} out. println (~Foo: ~ + session. getAttribute

3Vfjt~f"l i'IVo.lldt!.dl!..
esh:"
I"

VtfP,a Sf:SSQ tfP,estfP,,, fJ.C/~fJ.

Resultado: ocorrer uma exceo de runtime (lllegaIStateException), porque voc no pode chamar o isNewO na sesso DEPOIS que ela tenha sido invalidada. Configurar o intervalo mximo de inatividade em O significa que a sesso vai expirar e ser invalidada imediatamente!

/1;r+"11.f.4;

pr"b1e.tfP,fJ. da cadljtl

114IJ '" pde ct.atfP,fJ.rf!s-n:; 1_V.:)cf

tfP,:+t>d f,l)j V,l)j4 sfss.,


1i?lIalldadfJ..

voc est aqui..

249

custon cookies

Posso usar cookies para outras coisas, ou eles so apeKas para sesses?
Ainda que os cookies tenham sido originalmente desenvolvidos para ajudar no suporte do estado da sesso, voc pode usar cookies customizados para outras tarefas. Lembre-se, um cookie nada mais do que um pequeno pedao de dados (um par String nome/valor) trocado entre o cliente e o servidor. O servidor envia o cookie para o cliente e este retoma o cookie quando fizer uma nova solicitao. Uma coisa legal dos cookies que o usurio no se envolve - esta troca automtica (supondo que o cliente tenha habilitado cookies, naturalmente). Por padro, um cookie vive somente enquanto dura uma sesso; uma vez que o cliente fecha o browser, o cookie desaparece. assim que o cookie "JSESSIONID" funciona. Mas voc pode mandar um cookie permanecer mesmo DEPOIS que o browser fechado. Dessa forma, a sua aplicao ainda pode obter a informao do cookie, mesmo que a sesso com o cliente j tenha sido finalizada h muito tempo. Imagine que o Kim queira mostrar o nome do usurio cada vez que ele retome ao site da cerveja. Ento, ele configura o cookie na primeira vez que recebe o nome do cliente, e se obtiver o cookie de volta com uma solicitao, ele sabe que no tem que pedir o nome de novo. E no importa se o cliente simplesmente reiniciou o browser ou esteve fora por uma semana!

yT9c p9de ustt 95 c99kles pttt tt9Ctt 9S pq.tes de Stt'lnb n9me! Yt19tentte 9 setYld9t e 9 cl1ente. O sety'id9t enYIa 9 c99kIe t9 clIente, Cjye 9 enVIa de Y9lttem ctda S911c1ta9 subse<tiiente. Os c99kles da sess.9 S9mem <tuand9 9 6t9Wset d9 clIente encettad9, mas V9ce rODE dIzet

n9
clIente tecLat seu dep915 ~.:ueele

~~~.~lect~selectBeerTaste2.do . w.W1Ckedlysmart.com User-Agent: Mozi11a/5.0

HTTPll 1 .

HTTP/l.l 200 OK _ToroasHirsch Set-Cookie: usernaroeContent-Type: text!htm1 Content- en . 200303:25:40 Date: Wed, 19 Nov . Anache-Coyote/l.1 Server.t' Connection: close <htrol> <lhtrol>

Accept textl 1 . Irsc ht 1 ~ Xli ,apphcation/xml a . m ,q-O.9,textlplaiuq==o 8,VI'd eo/x ,pp mn IcatlOn/xhtml+xml ]P' . ,. . ,textl

Cookie: username==TomasH' h
eg,Image/glf;q==O.2, *1*;q==O.1

r .

L gth. 397

g,lmage/png,imagel

GMT

age: en-us,en;q==O.5 Accept-Eucoding: gzip,deflate

Accept-Langu

() c/tf!,,-h e"ll/tl

15.f-.,

de

V.,/.f-o..

() Si!I'ViflM' i!"Vltl i5.f-., ,l'lmeil'''. 250 captulo 6

gerencamento

da sesso

Usando cooldes

COtH

a API Servlet

Voc pode obter headers relacionados ao cook:ie atravs da solicitao e da resposta HTTP, mas voc no deve. Tudo o que voc precisa fazer com os cook:ies foi encapsulado naAPI Servlet em trs classes: HttpServletRequest, HttpServletResponse e Cook:ie.

javax.servlet. http. Cookie <<inteJjaee> > http HttpServletRequest javax.servlet. . getcontextPathO getCookiesO etHeader(String) g get QueryString() Cookie(String, String) ~tring getDomainO znt getMaxAgeO String getNameO String getPathO boolean getSecureO String getValueO vo~dsetDomain(String) vozd 'se!" A . olV1GX ge(znt) vO~d setPath(String) vOldsetValue(String) Ii alguns outros mtodos

< <interfaee> > javax.servlet. http.HttpServletResponse

addCookieO addHeaderO getSession(), J d' VIraS mais metodos ... eneoueRe zreetURLO Ii M sendErrorO setStatusO Ii MUITOS mais mtodos ...

Criando um novo cookie


Cookie cookie

o CIJPls+rf.l"1-6r
name);~

ClJoUe leva lIlrl

= new Cookie(~usernameH,

.sI . I , .,..r1Pl5P1itJlrle{VafitJr.
no cliente
O se+A4.axA'fif!: <J ~f.btJlJJ)O.s. perlrlaPleg4
'l1:

Configurando

o tempo que um cookie permanecer


,

cookie. setMaxAge (30*60);

Jetl'P1it/itJ elrl I

{) caJi5tJ Ji;: Vt"lItJ PltJcliePlh


11

Enviando o cookie ao cliente


response.addCookie(cookie);

f'i'U'

30'1f\'O

s'!!5l1P1Jas

IrlI'P1l1+as). CaPlt~lIral"

IrlQX

Recebendo

o{s) cookie{s) da solicitao

do cliente f'4Nl.

-1ta;

CIJIrl 6 3l1e ll4P1JIJitJ

6 Co66kte

Cookie [] cookies

= request. getCookies ();


i++) {

Jesapl1.reja

for Cookie (int i = O; i = < cookies.length; cookie cookies[i]; if

tec~ar.~r+I1.PI+o6JSe ;;'fJ.1rl4r tJ 5e-1-1A.axIf9e() Ll.5f..5.s~olJ~J) r,!!Cder4 PlIJc6IfJkte

(cookie. getName ().equals (~usernameH) ) String userName = cookie.getValue(); out.println(~Hello ~ + userName); break;

tJ

Je

!J';IJ ~: " 1Itt:+"JIJ 5e-H:.IJt:J/:.te(S+rtPl5)'" c"o/:.tes elltt lIlItt arr, PIe.arr, p4ra CIJIJ/:.tee vc hr:

ve.c s:' pe.Je tJ~hr 1l1e ta;er lIlItt IlJtJp

ePlC6P1+r4r alpe1e 3l1e voee SlIer.

voc est aqui..

251

exemplo cookie

Exet\tplo sit\tples de ut\t eoolde eustot\tizado


Imagine que o Kim deseje criar um formulrio que pea ao usurio para enviar o seu nome. O formulrio chama um servlet que recebe o parmetro usemame da solicitao e usa este valor para criar um cookie na resposta. Na prxima vez que o usurio fizer uma solicitao em QUALQUER servlet nesta aplicao, o cookie retoma com a solicitao (supondo que o cookie ainda esteja vivo, baseando-se no valor maxAge dele). Quando um servlet na aplicao v este cookie, ele pode colocar o nome do usurio em uma resposta gerada dinamicamente, e a lgica do negcio sabe que no tem que pedir ao usurio que digite o seu nome novamente. Este cbe\~go~ uma verso fie \es\e acabamos de descrever.

slmp\ln~~~~ ~~ i\\\\'?~"d\') \\\\~

o servlet
import import import public

que cria e CONFIGURA o cookie

javax.servlet.*; javax.servlet.http.*; java.io.*; class CookieTest extends HttpServlet {

public

void

doPost(HttpServletRequest

request, HttpServletResponse response) throws IOException, ServletException

response. setContentType String Cookie name

("text/html") ;

= request. getParameter

("username") ;

itecebe

(} /7t}/MetJlJ vsv:l'l{j

f!J1Vlo.tJ"J16161'W1vl:l'ia. VNoJ16V6 c<tJfjl:le~lIe


F

cookie

= new Cookie ("username",

name); <--Cl'tfll.

o.I'WIlJ.jf!/7IJ. <> /7iJWletJ" lISVfl.l'i'eJ.


cookie.setMaxAge(30*60);

I
'" Malfrff.No" (;41JMe 11lVfJJ1(j W11;'V+4S.

30

A-tJlci'6/7fl. .o C()lJl:te Ct'JWlIJ


response. addCookie RequestDispatcher (cookie) ; view

t.eatJel' tJe

<f:--_____

l'esft'Js-ra,

/I .se.,...-l.-M/tae. J J'I
~

= request.getRequestDispatcher("cookieresult.jSP"); response);

view. forward (request,

Pel'W1,--h: 3l1e lIWI J.sP crie IJ. I

tJe l'eSft:lS.f-lJ.

.-I

o JSP que cria a view


<htm >< o y> <a href=" checkcookie </body></html>

a partir deste servlet

1 b d

.do">click

1tJt:IbeWl. c!al'lJ, t.a J1atJlJ. Ct)No J._'" I '" I here</ a> Cli.l'aCTf:l'ls-ri'ctJ.S tJe 1-P /71's S).W1tJ.S I'MS t:ltJi'Q.If'lt:lS 5U'4f' VIf'IIJ. SlJ.ltJae'lf'IlJrML. tJe lIlf'I Sff'V1dj IJ.t;,tJa~ve S~lJ. J).s-r .f-ailJ'lf3.J1i.". () h-ft:l tJe es-fQI'W1tJS eJ1Calf'll;,t.4J1tJ<ii paf'a lIlf'I J.sP J1';' If'IlIJ, IJ.ctJ;,/~tJf'tJJifJ ;/.0 c(J(J/::ie.() elf'l ClJlJ/::'-ejfl es-fo. ;,Q. f'(SPlJs.f1J. 116iIJ'It)/I!;el1-fIJ 3tJe
4

SlJli'cl-flJ.j';C : eI1ClJ.iIJ'It;,t.a;/a 41J J.sP.

252 captulo 6

gerenciamento

da sesso

ExetMplo de UtM coolde custotMizado,

cottlit1uao ...

o servlet
import ~mport lmport public

que RECEBE o cookie


javax.servlet *. javax.servlet:h~tP.*; ]ava.io.*; class CheckCookie extends HttpServlet (

public

void

doGet(HttpServletRequest

request, HttpServletResponse response) throws IOException, ServletException

response.setContentType(~text/html") . PrlntWrlter out = response.getWriter();' Cookie [] cookies if ~ request. getCookies (); ~ecebe

6S uM/t:.tes

da Sf:Jlit-l-at/ti6.

( cookies !~ null) { . for (int i ~ O' . < . _ ,l cookles.length; i++) Cookle cookie = cookies[i]; lf (cookie getNa () . . me .equals{~username")) Strlng userN _ . . ame - cookle. getVal ue () . out.prlntln(~Hello ~ + userName)' '~ break; ,da

i .___

J ' t.!-rl'illltS dli

ca4/l:le I'l'ilJCill'tlPlJtJ illJ'i ClJtJkl'e cl..fJ,IJ'ifJ.JiIJ

If'

IISI!I'Pl41J'ie

Se

ele

I!PlClPl-l-I'RdtJ)IJb-l-ePlt.a a

val61' e extb4-t}.

No confunda Cookies com headers! Quando voc adiciona um header em uma resposta, voc passa as Strings nome e valor como argumentos:
response.addHeader(~foo", o ~bar");

: ara a prova ,nao voce' - te . : memorizar cad ra que : : cIasse cooki a um dos me'to d os na e, masdev ' : : os mtodos de sol" lClta era - conhecer : para obter e adi . ao e resposta: : 10c tamb' d czonar Cookies. : : em eve conh : ecer o construtor C. ookie e' : : getMaxAgeO ., IOS metodos :.......... e set1V1axAgeO. : ........
............

p
:

I "

.=~lQ'o

..

;t

......

saber i;DC no . I os precisa me't .. do cookie. Ouos :

'"

"0

00 00 00 000.

Mas quando voc adiciona um Cookie em uma resposta, voc passa um objeto Cookie. Voc configura o nome do Cookie e o valor no construtor Cookie.

os

Cookie cookie = new Cookie(~name", response.addCookie(cookie);

name);

E lembre-se tambm de que existem o mtodo setHeader() e o addHeader() (o addHeader adiciona um novo valor a um header existente, caso exista, e o setHeader troca o valor existente). Porm, NO existe um mtodo setCookie(). Existe apenas o addCookie()!

. :

voc est

momentos do ciclo da vida da sesso

Os prittcipais 'ltO'ltetrtos de U'lt HttpSessiott


Os momentos mais importantes na vida de um objeto HttpSession:

A sesso

criada
new

ou destruda.

invalidate

Os atributos da sesso so adicionados, removidos ou substitudos por outras partes da aplicao.

removeAttributeO

A sesso torna-se passiva em uma VM e aplicao distribuda.

ativada

em outra dentro de uma

VMl prepare-se para mudar

AContainer A-l
IOIj

sess"
/'tI.
1/1010.

Agora eu tenho voc. Container A-2

de V,(,{ptU'4 "tr!-f'o..

254

captuo 6

gerenciamento

da sesso

Eventos do ciclo de vida da sesso

Momento
Ciclo de vida
A sesso foi criada

Tipo de Evento e Listener

HtipSessionEvent

Quando o Container cria uma sesso pela primeira vez. Neste momento, a sesso ainda considerada nova (em outras palavras, o cliente ainda no enviou uma solicitao com uma session ID).
A sesso foi destruda
~, ~ ..... Y

Quando o Container invalida uma sesso (porque houve um timeout da sesso, ou alguma parte da aplicao chamou o seu mtodo invalidate()).

, ,

Atributos
Um atributo foi adicionado

Quando alguma parte da aplicao chama o setAttributeO na sesso.


Um atributo foi removido

HttpSessionBindingEvent

Quando alguma parte da aplicao chama o removeAttributeO na sesso.


Um atributo foi substitudo

~.'.: ~ ... V

HttpSessionAttributeListener

Quando alguma parte da aplicao chama o setAttributeO na sesso e o nome do atributo j esteja associado a ela.

Migrao
A sesso est a ponto de se tornar passiva

Quando o Container est prestes a migrar (mudar) a sesso para uma VM diferente. E chamado antes de a sesso ser movida, de forma que os atributos tenham a chance de se preparar para a migrao.
A sesso foi ativada

HtipSessionEvent

Quando o Container acaba de migrar (mudar) a sesso para uma VM diferente. chamado antes que qualquer outra parte da aplicao possa chamar o getAttributeO na sesso, para que os atributos recm-movidos possam se preparar para o acesso.

HttpSessionAttributeListener

voc est

255

HttpSessionBndingListener

No se esque~ado HttpSessiot'Jit'dit'gListet'er
Os eventos da pgina anterior so para os momentos principais na vida da sesso. Mas o para os momentos mais HttpSessionBindingListener importantes na vida de um atributo sesso. Lembre-se do captulo 5, onde ns vimos como voc pode us-Io ~ se, por exemplo, o seu atributo quer saber quando ele adicionado a uma sesso, para que ele possa sincronizar-se com o banco de dados em questo (e atualizar o banco de dados quando for removido de uma sesso). Veja abaixo uma pequena reviso do captulo anterior:
package import com.example; javax.servlet.httP.*;~ HttpSessionBindingListener

o
O

II.K p. serv1e-r,

1_ l?s-rl.nf>P liS-n;i'ler

I'

I1CIJ+e

'"

illVI!X,

public class Dog implements private String breed; public Dog(String breed) this.breed=breed;

public String getBreed() return breed;

U'fl

public void cdigo

Ii

valueBound (HttpSessionBindingEvent event) a ser executado agora que eu sei que estou

/} fo,lavt'4 !7,#Ji'lt Si5l'1l';:tCfl alie 4'Jll,.. kbICItJA]()1I {es+e 4-1-"l/;u-I-c. e,.. U"'<'l sesslJ.
numa sesso

public void valueUnbound(HttpSessionBindingEvent event) { cdigo a ser executado agora que eu sei que no fao mais

Ii

parte

da sesso

V-NO configura todos os oce . d" g no DO' listeners session bm m .


o a classe Dog aqui) implementa Se uma classe a!rz~uto (com . o Container chama os callbacks o HttpSessionBmdmgLrste;el, dO e valueUnboundO) quando que tratam eventos (value o,undo nada ou removida de uma uma instncia dessa classe e a IClO sesso. isso. E funciona. . d . - vale ara os outros lzsteners e O HttpSessionListenere o Mas Isto NAO p sesso da pgin~ ante~lOr. devem ser registrados no DD, HttpSessionAttrlbuteLrstener, - es em si diferentemente I - relacionados as sesso ' visto que ~ es s~od' "d de um atributo m IVI u aI localizado na sesso.
o o o

256 captuio 6

gerenCamento da sesso

A tltigrao da sesso
Lembra no captulo anterior que ns falamos brevemente sobre aplicaes distribudas, onde os pedaos da aplicao poderiam ser replicados por vrios de ns na rede? Em um ambiente de clusters, o Container pode fazer um balanceamento de carga, recebendo as solicitaes dos clientes e enviando-as para as NMs (que podem estar, ou no, em mquinas diferentes, mas isso no relevante para ns). O fato que a aplicao est em diversos lugares. Isso significa que cada vez que o mesmo cliente faz uma solicitao, esta pode acabar indo para uma instncia diferente do mesmo servlet. Ou seja, a solicitao A para o Servlet A pode acontecer numa VM, e a solicitao B para o Servlet A pode ir parar numa outra VM. Ento a questo , o que acontece com os componentes como o ServletContext, ServletConfig e objetos HtlpSession? Resposta simples, implicaes importantes: Apenas os objetos HttpSession (e seus atributos) so movidos de uma VM para outra. Existe apenas um ServletContext por VM. Existe um nico ServletConfig por servlet, por VM. Mas existe apenas um objeto HttpServlet para uma determinada session ID por aplicao, independentemente de em quantas VMs a aplicao esteja distribuda.

A aplicao Cerveja distribuda etlt duas VMs

VM 1 Aplicao Cerveja

~"
PI';""'iJ .5e1",11~~
eo.m!JsS opliCQ{ic~1f,,(/.1tt!
yltt!

,y;;.psesS\O~ .5eI'VI~;d-,
1iid")/((cef-"" ~SSi<>i'l; esh. dyplic(I.Jt; i'IfJ, tJ(r/-1'{I.

V~

VM2
Aplicao Cerveja

Alt:rh;
IJ'

es-IJ -fvJi'J diA Ilcf1.dt; I'lt;


Z:l

Sejtl'1d
'Cs

y sess:ks

e((I~1tt! ebl

Dpei'IfJ.S 1/M.1Y5QI' ebl a!;tlbl d(I.Ji'J ~n+D. I} ~SJtt!fJ.sesslJ'l I!J parQ GlJtt!fJ. dml'l>V~a opliC"ffi" AlI/AlCI} ~ce ebl dGlf1.S ~ tJ.~sJtt!fJ.h""f>6.

voc est aqui...

257

migrao da sesso

A t\1igrao da sesso et\1 ao


A forma como os fabricantes de servidores lidam com c1ustering e distribuio de aplicaes web varia. No h nada na especificao J2EE que obrigue um fornecedor a dar suporte a aplicaes distribudas. Mas a figura abaixo nos d uma idia interessante de como isso funciona. O fundamental que, enquanto que as outras partes da aplicao so replicadas em cada nNM, os objetos sesso so movidos. E isto garantido. Logo, se o fornecedor realmente suporta aplicaes distribudas, o Container requerido para migrar as sesses atravs das VMs. E isso inclui migrar os atributos da sesso tambm.

Diane seleciona "Clara" e c1icano boto submit. de balanceamento de carga decide enviar a solicitao para o Container A-i na VM Um.

o Container

o servidor

cria uma nova sesso, ID n2.343. O cookie "JSESSIONID devolvido para Diane na resposta (no mostrado).

Servidor/Container de balanceamento de carga

Diane seleciona "Amarga" e c1icano boto submit. Sua solicitao tambm inclui o "JSESSIONID" n2.343.

Desta vez, o servidor de balanceamento de carga decide enviar a solicitao para o Container A-2 na VM Dois.

O Container recebe a solicitao, verifica a session ID e percebe que a sesso est em uma outra VM, a VM Um!

o
o

Servidor/Container de balanceamento de carga

Container A-2

258 captulo 6

gerenciamento

da sesso

A sesso n9.343 migra da VM Um para a VM Dois. Ou seja, ela no existe mais na VM Um, j que ela se mudou para a VM Dois. Esta migrao significa que a sesso se tornou passiva na VM Um e foi ativada na VM Dois.
VM 1

Container

A-1

Servidor/Container balanceamento

de
VM 2

de carga

Container A-1

O Container cria uma nova thread para o Servlet A e associa a nova solicitao sesso recmmovida n9.343. A nova solicitao de Diane enviada para a thread e todos saem felizes. Diane no tem idia do que aconteceu (exceto pelo breve atrasol latncia na espera da migrao da sesso).

Servidor/Container balanceamento

de

de carga

voc est

lt-

259

HttpSessionActivationListener

deixa os atributos protrtos para a graKde tMUdaKa ...


J que possvel migrar um HttpSession de uma VM para outra, os desenvolvedores da especificao pensaram que seria legal se algum se preocupasse em dizer aos atributos dentro das sesses que eles tambm esto prestes a mudar. Dessa forma, os atributos podem garantir que sobrevivero mudana. Se todos os seus atributos so objetos Serializveis de verdade, que no se importam onde eles sero colocados, voc talvez nunca use este listener. Alis, imaginamos que 95,324% de todas as aplicaes nunca usem este listener. Mas ele est l caso voc precise. Seu uso mais provvel dar aos atributos uma chance de preparar as variveis da sua instncia para a Serializao. A migrao da sesso e a Serializao

o HttpSessiottAetivatioKListmer

Este Iistener to parecido com um atributo, que eu consigo descobrir quando eu estou para Ser movido para uma nova VM como parte de uma sesso, e posso ter certeza de que as variveis da minha instncia esto prontas ...

o
a

Agora fica meio confuso ... Um Container exigido para a migrao dos atributos Serializveis (o qual assume que todas as variveis da instncia dentro do atributo ou so <<interface> > Serializveis, ou so nulas). HttpSessionActivationListener Mas um Container no exigido para usar a Serializao para migrar o objeto HttpSession! O que isto significa para voc? Simples: sess~onDi~ctivate(HttpSesSionEventj garanta que os tipos das suas classes de seSSlOn WiJIPassivate(HttpSessionEventj atributos sejam Serializveis e voc nunca ter que se preocupar com isso. Mas se eles no forem Serializveis (em virtude de uma das variveis da instncia do objeto atributo no ser Serializvel), faa com que a classe do seu objeto atributo implemente o HttpSessionActivationListener e use os callbacks ativao! passividade para contornar o problema.

o Container no REQUERIDO para usarmos a Serializao, por isso no h nenhuma garantia de que o readObject() e o writeObject() sero chamados no atributo Serializvel ou em uma das variveis da sua instncia!
Se voc est familiarizado com a Serializao, voc sabe que uma classe que implementa esse recurso tambm pode escolher implementar um mtodo writeObjectO, chamado pela VM sempre que um objeto for serializado, e um mtodo readObjectO, chamado quando ocorrer o inverso. Um objeto Serializvel pode usar estes mtodos para, por exemplo, configurar nulos os campos noSerializveis durante a Serializao (writeObjectO), e ento restaurar os campos quando ocorrer o processo inverso (readObjectO). (Se voc NO estfamiliarizado com os detalhes da Serializao, no se preocupe.) Mas os mtodos no sero, necessariamente, chamados durante a migrao da sesso! Portanto, se voc precisa salvar e restaurar o estado da varivel da instncia no seu atributo, use o HttpSessionActivationListener e use os dois eventos de callbacks (sessionDidActivateO e sessionWillPassivateO), assim como voc usaria o readObjectO e o writeObjectO.

260 captulo 6

gerencamento

da sesso

Exeiflplos de listcmer
Nas duas pginas a seguir, preste ateno nos tipos do objeto evento e se o listener tambm uma classe atributo.

o contador

da sesso

Este listener permite que voc acompanhe a quantidade de sesses ativas na aplicao. Muito simples.
package com.example; import javax.servlet.http.*; public class BeerSessionCounter implements HttpSessionListener { e",

static

private

int activeSessions;

~s';"a classe se;,,: ;/i's';"rtbll{Ja w6-IIJFlclasses 611';";"IJ.S classes


C<l""<l

';"<lJ4s as

da

apftclJ.{i<l)'IJ.;"1J.

public static int getActiveSessions() return activeSessions;

{ ~

ve ';";/s 6,s ,se;"lIfe';"s e 4S 611+;"4S cllJ.sses /l.ssts-/-e,,-/-es P6SSIJ.'" acessa;" es-/-e "'~';"6J6.

public activeSessons++; vod sessionCreated(HttpSessionEvent

event)

{~

fshs
publc void sessionDestroyed(HttpSessionEvent actveSessions--; event) {~

,I
Cfl.l"l"e541r< Vir<

""'fff)JI)S

H++,Ses

slt:'l'Jve"./-.

Configurando o Iistener no DD
<web-app ...>

<listener> <listener-class> com.example.BeerSessionCounter </listener-class> </listener> </web-app>

voc est aqui ~

261

atributo de sesso listener

Exet\tplos de Iistet1er

o Listener Attribute
Este listener permite rastrear cada vez que algum atributo acrescentado, removido ou substitudo em uma sesso.
package com.example; import javax.servlet.http.*; public class BeerAttributeListener implements

s+e 'ts+el'/el" usa V"" I'IlJ""f! I';;Ci:>I'!Sts+el'l+e - l<j>esal" '/e ser 'ts+eller IJrHt'lbil+e) wewf-i:>8'-1'1'/'';;3_
u""

HttpSessiOnAttributeListener event} (

recebe iI""

public

void

attributeAdded(HttpSessionBindingEvent

String name == event. Obj ect value event. getName getValue (); () "7.. O HHpSessianlle,,-I"11i:>""e e" va!,,/' per""r+e ,/<la-!-I'lbu+" a lI<lc ue ,JieSf!"ca,Jie"iIes+e Wf!"-!-". System.out.println{"Attribute added: " + name + ": " + value);

public void attributeRemoved(HttpSessionBindingEvent String name = event.getName(); Object value ~ event.getValue{); System.out.println("Attribute removed: " + name

event}

+ ". " + value);

public void attributeReplaced(HttpSessionBindingEvent String name = event.getName(); Object value ~ event.getValue(); System.out.println("Attribute replaced: " + name

event}

+ ". " + value);

Configurando o listener no DD
<web-app ...> <listener> <listener-class> com.example.BeerAttributeListener </listener-class> </listener> </web-app>

r:

Ei, onde voc est exibindo? Onde

entra o System.out na aplicao?

quer que o Container decida envi-Io (que voc pode ou no configurar). Em outras palavras, um lugar determinado pelo fabricante, geralmente um arquivo de log. O Tomcat coloca a sada em tomcaUlogs/catalina. log. Voc ter que ler a documentao do seu servidor para descobrir o que o seu Container faz com a sada-padro.

Jt: Para onde

262 captulo 6

ExetMplos de listmer

A classe atributo (escutando eventos que afetam o IT)


Este listener permite que um atributo acompanhe os eventos que possam ser importantes para o prprio atributo - quando ele acrescentado ou removido de uma sesso e quando a sesso migra de uma VM para outra.
package com.example; import javax.servlet.http.*; import java.io.*; public class Dog implements HttpSessionBindingListener, HttpSessionActivatiOnListener,Serializable incluindo

private String breed; imagine outras variveis da instncia, algumas que no sejam Serializveis

Ii Ii Ii

imagine

o construtor

e outros

mtodos

get e set

public void valueBound(HttpSessionBindingEvent event) cdigo a ser executado agora que sei que estou em uma

Ii Ii

public void valueUnbound(HttpSessionBindingEvent event) { cdigo a ser executado agora que sei que no fao mais sesso

parte

da

public

Ii

Ii

void sessionWillPassivate(HttpSessionEvent event) cdigo para obter meus campos no-Serializveis em um que possa sobreviver mudana para uma nova VM

public void sessionDidActivate(HttpSessionEvent event) { cdigo para restaurar meus campos ... para refazer tudo tenha feito

Ii Ii no

sessionWillPassivate()

o qco oc OO:--'~ tLve"l.f.tJsde fl.f.lV4{i4


do. sess';tJ (~t!s

abstt've

as

~:.f.(,jd{)s CfJ.t't'e54"

u.

H#p.:5es slt:mtLve",.f).

voc est

sesso listeners

Os Listetters relaciottados Sesso


classe ? classe sessionDidActivate AJ~+b.: Vds+e attributeAdded valueBound AJ/Jfa: PJ4C n'6 f!.xtsh i1ei1t.v~ nft"hVJJ1 A interface Geralmente Iistener/mtodos atributo valueUnbound attributeRemoved HttpSessionActivationListener HttpSessionEvent HttpSessionBindingListener HttpSessionAttributeListener HttpSessionEvent HttpSessionListener (javax.servleLhttp ) HttpSessionBindingEvent Tipo do evento classe HHf'5es HHf'Sess1i>"IrHri/fl,1-/-eve,,-Is1t,,,A-Hrt/;l/-/-eve.,.f outra (javax.servleLhttp) DUma classe sessionCreated attributeReplaced atributo Alguma outra ~ Alguma Uma classe sessionDestroyed

Cenrio sesso. ou removidos de uma eles forem associados deste notificados tipo sejam quando implementado por Voc quer saber Voc quer saber

Alguma outra

Alguns dos eventos relacionados sesso n~o seguem de nomenclatura para os eventos. os pa d roes
Os mtodos HttpSessionListener adotam os HttpSessionEven~s. . . Os mtodos HttpSessionBindingListener adotam os HttpSesslOnBmdmgEvents. Porm, os mtodos HttpSessionAttributeListener empregam o HttpSessionBindingEvents. . E os mtodos HttpSessionActivationListener empregam o HttpSessl~nEvents. Jrfiqu~t as clatssbeesmHtn~Soe~~~;:~:~;s~::~~:~:~c~:~:~;:;;:~~1:;;~~~;:;; pe el amen e , eventos na API. de

264 captulo 6

geref~lcilmienl'oda sess

Os Ustmers para Evemos relaciotlados Sesso e utlta viso geral da API Objetos Evemo
< <interfaee> >

HttpSessionActivationListener
sessionDidActivate(HttpSessionEvent) session WiIlPassivate(HttpSessionEvent)

HtipSessionEven
< <interfaee> >

HttpSessionListener
sessionCreated(HttpSessionEvent) sessionDestroyed(HttpSessionEvent)

< <interfaee>

>

HtpSe~wnBmmngL~wn"
HttpSessionBindingEven
valueBound(HttpSessionBindingEvent) valueUnbond(HttpSessionBindingEvent)

getSessionO getNameO getValueO

< <interfaee>

>

HtpSessionAttributeListener
attributeAdded(HttpSessionBindingEvent) attributeRemoved(HttpSessionBindingEvent) attributeReplaced(HttpSessionBindingEvent)

tJ ~tJ(/6

~tJ.~

~tV'1?4.

6~

Ja

.:s.f.f"15til) trl-rt~V+41JtIf ti.ese~aJelW 6 tJ 1Pi+4J~/IJeO ~tlf'~a


t!J;

1I1J,/(Jf' JtI

J6
eve~.,.
iltJ./f'J

l)fJ~tI;

Jese~t:aJelW ., f'~6f'~tJ.

6 tJ.~5(j

., ~"VtJ. Is-I-<Js;~lltc4 1Ft ele


Jfi. IPI.{JJtJ.#1ftJ.1;IJe jtf'lW (j eve~d

re:+61"1?4. tJ 118.161" 1JIJe () trl-1"t1JIJ-/-,(J ,6S suJa

A-AJr:5

voc est

sesso Iisteners

Os Listetters relaeiottados sesso


Sim, esta uma cpia quase fiel da tabela que vimos duas pginas atrs, ento no vale olhar. Tente imaginar estes listeners e anote seus melhores palpites. Voc pode esperar por no mnimo duas, ou at quatro perguntas sobre os listeners da sesso na prova. Use a memria e o bom senso para preencher a tabela.

Cenrio Voc quer saber sesso. classe

A interface Iistener/mtodos

Tipo do evento

Geralmente implementado por classe D outra atributo D Alguma Uma DUma classe D Alguma outra

'OJuaA:>! op!qo

ap sod!J S!OP svuadv

maJs!xa :g;)!<I

266 capl'tulo 6

'Pausa pata

9 cat

1 Dado:
10. pub1ic 11. class void MyServlet extends HttpServlet { public doGet(HttpServletRequest response) IOException, ServletException ~value"); ~value"); ~value"); ~value"); request, HttpServletResponse 12. 14. 15. 16. 17. 13. 18.

Ii

throws

request.getSession()

.setAttribute(~key",

request.getHttpSession()

.setAttribute(~key",

HttpSession)request.getSession( HttpSession)request.getHttpSession(

.setAttribute(~key",

.setAttribute(~key",

Qual(is) linha(s) poderia(m) ser desanotada(s) sem causar erros de compilao ou runtime? (Escolha todas as que se aplicam.) DA. Somente a linha 13. DB. Somente a linha 14. Dc. Somente a linha 15.

DD. Somente a linha 16. DE. Linhas 13 ou 15. DF. Linhas 14 ou 16.

Se um cliente NO aceita cookies, qual mecanismo de gerenciamento da sesso o web container pode utilizar? (Escolha uma.)

DA. Cookies, mas NO reescrita de URL. OB. Reescrita de URL, mas NO cookies. Dc. Tanto os cookies, como a reescrita de URL podem ser usados.

DD. Nem os cookies, nem a reescrita de URL podem ser usados. DE. OS cookies e a reescrita de URL devem ser usados juntos.

voc est aquj . 267

teste preparatrio

3 Quais declaraes
aplicam.)

sobre os objetos HttpSession

so verdadeiras? (Escolha todas as que se

DA. Uma sesso cujo tempo de timeout foi estipulado em -1 nunca expirar. DB. Uma sesso tomar-se- invlida assim que o usurio fechar todas as janelas do seu browser. De. Uma sesso tomar-se- invlida depois do tempo de timeout definido pelo servlet container.

DD. Uma sesso pode ser explicitamente invalidada chamando o HttpSession. invalidateSession().

Quais das segintes opes NO representam tipos de eventos listener na API J2EE 1.4? (Escolha todas as que se aplicam.) [JA.HttpsessiOnEvent DB. ServletRequestEvent De. HttpSessionBindingEvent

DD.HttpsessiOnAttributeEvent C}E.servletContextAttributeEvent

5 Quais das seguintes


as que se aplicam.)

declaraes sobre o monitoramento da sesso so verdadeiras? (Escolha todas

C}A. A reescrita de URL pode ser usada por um servidor como base para o monitoramento de sesses. C}E. O SSL tem um mecanismo nativo, que um container servlet pode usar para obter dados usados para definir uma sesso. De. Ao usar cookies para acompanhar as sesses, no h restries para o nome do cookie que realiza o acompanhamento da sesso. C}D. Ao usar cookies para acompanhar as sesses, o cookie usado para acompanhar a sesso deve receber o nome de JSESSIONID. [JE. Se o browser de um usurio est desabilitado para receber cookies, o container pode decidir usar um objeto javax. servlet. http.CookielessHttpSession para monitorar a sesso do usurio.

268 captulo 6

gerenciamento

da sesso

6 Dado:
1. import javax.servlet.http.*; 2. public class MySessionListener implements HttpSessionListener 3. 4. public void sessionCreated() { System.out.println(~Session Created"); public void sessionDestroyed() { System.out.println(~Session Destroyed");

5.
6. 7.

8.
9.

o que h de errado

com esta classe? (Escolha todas as que se aplicam.)

DA. A assinatura do mtodo na linha 3 est INCORRETA. DB. A assinatura do mtodo na linha 6 est INCORRETA. De. A declarao import no importar a interface HttpSessionListener.

DD. O sessionCreated e o sessionDestroyed NO so os nicos mtodos definidos pela interface HttpSessionListener.

Quais declaraes sobre os atributos da sesso so verdadeiras? (Escolha todas as que se aplicam.)

DA. O tipo de retomo do HttpSession.getAttribute DB. O tipo de retomo do HttpSession.getAttribute

(String) Object. (String) String.

De. OS atributos associados a uma sesso ficam disponveis para qualquer servlet que faa parte do mesmo Serv1.etContext, e que trate uma solicitao identificada como sendo parte da mesma sesso. DD. Chamar o setAttribute (~keyA", ~va1.ueB")em um HttpSession que j possua um valor para a chave keyAcausar uma exceo. DE. Chamar o setAttribute (~keyA", ~valueB") em um HttpSession que j possua um valor para a chave keyAfar com que o valor anterior para este atributo seja substitudo pela String

valueB.

voc est

269

teste preparatrio

8 Quais interfaces definem um mtodo getSession


C]i\.ServletRequest C]B. ServletResponse C]C. HttpServletRequest C]D. HttpServletResponse

() ? (Escolha todas as que se aplicam.)

9 Seja um objeto sesso s e o cdigo:


s.setAttribute{~key", value); Quais dos listeners podem ser notificados? (Escolha um.) Di\. i\penas o HttpSessionListener. C]B. i\penas o HttpSessionBindingListener. C]C. i\penas o HttpSessionAttributeListener. C]D. O HttpSessionListener C]E. O HttpSessionListener e o HttpSessionBindingListener. e o HttpSessionAttributeListener. e o HttpSessiOnAttributeListener.

C]E O HttpSessionBindingListener

00. Todos os trs.

10

Considerando que req um HttpServletRequest, quais das opes criam uma sesso, caso no exista nenhuma? (Escolha todas as que se aplicam.) ;

Di\.req.getsession{)

C]B. req.getSession{true); C]C. req. getSession (false) ; C]D. req. createSession () ; DE. req.getNewSession{); C]F.req.createSession{true);

00. req. createSession


270 captulo 6

(false) ;

gerencamento

da sesso

11 Dado

o objeto sesso s com dois atributos chamados myAttrl e myAttr2, quais alternativas removero ambos os atributos desta sesso? (Escolha todas as que se aplicam.)

CJi\. s.removeAllValues(); [JB. s.removeAttribute(~myAttrl");s.removeAttribute(~myAttr2");

[Je. s. removeAllAttributes

() ; (~myAttr2", UNBIND);

[JD. s. getAttribute (~myAttrl", UNBIND); s. getAttribute [JE. s. getAttributeNames (UNBIND) ;

12

Quais das seguintes declaraes sobre os objetos HttpSession em um ambiente distribudo so verdadeiras? (Escolha todas as que se aplicam.)

CJA Quando uma sesso movida de uma sesso sero perdidos. DE. De.

NM

para outra, quaisquer atributos armazenados na

HttpSessionBindingListener

Quando uma sesso movida de uma NM para outra, os objetos devidamente registrados sero notificados. Quando uma sesso movida de uma NM para outra, os objetos devidamente registrados sero notificados.

HttpSessionActivationListener

DD. Quando uma sesso movida de uma NM para outra, os valores dos atributos que implementam j ava. io. Serializable sero transferidos para a nova NM.

13

Quaisdeclaraes aplicam.)

sobre o timeout das sesses so verdadeiras? (Escolha todas as que se

DA DE.

i\s declaraes de timeout da sesso que foram criadas no DD aceitam o tempo em segundos. i\s declaraes de timeout da sesso que foram criadas no DD aceitam o tempo em minutos.
aceitam o tempo aceitam o tempo aceitam o tempo

De. i\s declaraes de timeout da sesso que foram criadas programaticamente em segundos. DD. i\s declaraes de timeout da sesso que foram criadas programaticamente em minutos. CJE. i\s declaraes de timeout da sesso que foram criadas programaticamente em minutos ou segundos.

voc est

teste preparatrio

14- Escolha o trecho do cdigo servlet que ativaria a partir de uma solicitao o valor de um cookie
denominado "ORA_UID"? (Escolha todas as que se aplicam.) DA. String value DB. String value Dc.

= request.getCookie("ORA_ UID"); = request.getHeader("ORA_ UID");


cookies

javax.servlet.http.Cookie[]
request.getCookies(); String String if cName value = null; = null;

(cookies for

!~ null) {
i++) {

(int i = O; i < cookies.length; = cookies[i] != null .getName(); &&

cName if

(cName

cName.equalsIgnoreCase(~ORA_UID")){ value

= cookies[i] .getValue();

DD. javax.servlet.http.Cookie[] request.getCookiesO;


if (cookies.length String value

cookies

> O) {
.getValue();

= cookies[O]

15

Qual(is) mtodo(s) pode(m) ser usado(s) para pedir ao continer para notificar seu aplicativo sempre que uma sesso estiver com o tempo esgotado? (Escolha tudo que se aplica.)

DA. HttpSessionlistener.sessionDestroyed; DB. HttpSessionBindingListener.valueBound; Dc. HttpSessionBindingListener.valueUnbound;

DD. HttpSessionBindingEvent.sessionDestroyed; DE. HttpSessionAttributeListener.attributeRemoved; DF. HttpSessionActivationListener.sessionWillPassivate;

272

gerenciamento

da sesso

16

Como voc usaria o objeto HttpServ1.etResponse em um servlet para adicionar um cookie no cliente? (Escolha todas as que se aplicam.)

DA. <context-param>
<param-name>myCookie</param-name> <param-va1ue>cookieVa1ue</param-va1ue> </context-param>

DB. response.addCookie("myCookie"," cookie Value"); Dc. javax.servlet.http.Cookie newCook =


new javax.serv1et.http.Cookie(~myCookieH,HcookieValueH); // ...set other Cookie properties

response.addCookie(newCook);

DD. javax.servlet.http.Cookie[] cookies = request.getCookiesO;


String if cname ~ nu11; != nu11) { i++) { (cookies for

(int i = O; i < cookies.1ength; cName if ~ cookies[i] .getName();

(cName

!~ nu11 &&
cName + ~: ~ + cookies[i] .getVa1ue();

cName.equa1sIgnoreCase(~myCookieH){ out.print1n(

11 Dado:
13. 14. 15. 16. 17. 18. 19. 20. pub1ic pub1ic throws c1ass Serv1etX extends HttpServ1et { resp) void doGet (HttpServ1etRequest IOException, Serv1etException req, HttpServletResponse { (req); HttpSession sess = new HttpSession sess.setAttribute(~attr1H, sess.invalidate(); String s = sess.getAttribute(~attr1H);

21. }
Qual o resultado? (Escolha tudo que se aplica.) DA. A compilao falha DB. O valor de s null De. O valor de s "value"

DD. Uma IOException enviada DE. Uma ServletException enviada DF. Uma IllegalStateException enviada voc est ~ 273

respostas do teste

1Dado:
10. public 11. class MyServlet void extends HttpServlet { public doGet(HttpServletRequest response) IOException, ServletException ~value"); ~value"); ~value"); ~value"); request, HttpServletResponse 12. 16. 14. 15. 17. 13. 18.

Ii

throws

request.getSession()

.setAttribute(~key",

request.getHttpSession()

.setAttribute(~key",

HttpSession)request.getSession( HttpSession)request.getHttpSession(

.setAttribute(~key",

.setAttribute(~key",

Qual(is) linha(s) poderia(m) ser desanotada(s) sem causar erros de compilao ou runtime? (Escolha todas as que se aplicam.) DA. Somente a linha 13. DB. Dc. Somente a linha 14. Somente a linha 15.

DD. Somente a linha 16. ~ E. Linhas 13 ou 15. DF. Linhas 14 ou 16.

Z Se um cliente NO aceita cookies, qual mecanismo de gerenciamento da sesso o web container


pode utilizar? (Escolha uma.) DA. Cookies, mas NO reescrita de URL. ~ B. Reescrita de URL, mas NO cookies. Dc. Tanto os cookies, como a reescrita de URL podem ser usados.
A-

(.5ervle.f-v2.'~f~'

S7

OD. Nem os cookies, nem a reescrita de URL podem ser usados. DE. OS cookies e a reescrita de URL devem ser usados juntos.

/jfJ';~

es.f-:

Cl'l"fl.f-fJ.;

f/j~l~e Ctl_ff;S)
AJA-o

I-JA-o POJ)f.M.~? 4\{'I.$4 l"eeSCI'IT"IJ. (/;fJ.;:: ",e "" . es.f-tja4\

f"dtlt.f-a.tis.

tiepenJe tie 3(/f! eles

274 captulo 6

gerenciamento

da sesso

3 Quais declaraes

sobre os objetos HttpSession

so verdadeiras? (Escolha todas as que se

(Servle-l-v2.~p~. aplicam.) Iilr A. Uma sesso cujo tempo de timeout foi estipulado em -1 nunca expirar.

S"9)

OB. Uma sesso tomar-se- invlida assim que o usurio fechar todas as janelas do seu browser. ~ C. Uma sesso tomar-se- invlida depois do tempo de timeout definido pelo servlet container. OD. Uma sesso pode ser explicitamente invalidada chamando o HttpSession. invalidateSession().
- A- DfS!J es-l-: t'/cN'e-l-~ plu'ave <l ",Ht:uill ave devert). ser I/stld ct.a",a-se t'/valtda-hO. - A- fS es-l-: eXis-h: v", stPial

de 3ve ti sess

acabv.

Quais das seguintes opes NO representam tipos de eventos listener na API J2EE IA? (Escolha todas as que se aplicam.) OA. HttpSessionEvent

OB.

ServletRequestEvent

OCo HttpSessionBindingEvent IilrD.HttpSeSSiOnAttributeEvent OE.servletContextAttributeEvent

5 Quais das seguintes


as que se aplicam.)

declaraes sobre o monitoramento da sesso so verdadeiras? (Escolha todas


<'Servle+-

Iilr A. A reescrita de URL pode ser usada por um servidor como base para o monitoramento sesses.

de

Iilr B. O SSL tem um mecanismo nativo, que um container servlet pode usar para obter dados usados para definir uma sesso. Oe. Ao usar cook:ies para acompanhar as sesses, no h restries para o nome do cookie que realiza o acompanhamento da sesso. Iilr D. Ao usar cook:ies para acompanhar as sesses, o cookie usado para acompanhar a sesso deve receber o nome de JSESSIONID. DE. Se o browser de um usurio est desabilitado para receber cook:ies, o container pode decidir usar um objeto javax. servlet. http.CookielessHttpSession para monitorar a sesso do usurio.

es-l-: t'/c6N'e-l-tl)fr3ve exls-!-e es-l-a c/4S5e.


- A- ~PS

'1

voc est

IP

275

respostas do teste

6 Dado:
1. import javax.servlet.http.*; 2. public class MySessionListener implements HttpSessionListener 3. 4. public void sessionCreated() { System.out.println(~Session Created"); public void sessionDestroyed() { System.out.println(~Session Destroyed"); - fJrs "p.';es fJr e es-l-';" c""'t'e-l-4sJ f"t'3ve eshs . -l-'Jfl"s tievel'l"Q. . hl' ti.p4t'M..e+l''' HHpSes sl(JIfLve.rl-.

5.
6. 7.

8. 9.

O que h de errado com esta classe? (Escolha todas as que se aplicam.) ~ A. A assinatura do mtodo na linha 3 est INCORRETA. ~ B. A assinatura do mtodo na linha 6 est INCORRETA. Dc. - fJr "P'j';t) C es-l-: ~Ptc4N'e-l-4J pt:II"3ve" lishlfel' e ofel,PtIi;f"IfD p4c6h i"'f>"1'-I-4ti6.

A declarao import no importar a interface HttpSessionListener.

DD. O sessionCreated e o sessionDestroyed NO so os nicos mtodos definidos pela interface HttpSessionListener.


- fJr lJp,';6!J es-l-: IPtc(Jl'l'e-l-~ptJI'11'e eshs s'; tJS tids tJ..,ic/JS ""=l-tJtitJs Ifes-l-a ,Pt-h,..{ace.

Quais declaraes sobre os atributos da sesso so verdadeiras? (Escolha todas as que se aplicam.)
(Sel'vle-l11

2..~ p~.

S-9)

~ A. O tipo de retomo do HttpSession.getAttribute DB. O tipo de retomo do HttpSession.getAttribute

(String) Object. (String) String.

~ C. Os atributos associados a uma sesso ficam disponveis para qualquer servlet que faa parte do mesmo ServletContext, e que trate uma solicitao identificada como sendo parte da mesma sesso. OD. Chamar o setAttribute (~keyA", ~valueB") em um HttpSession que j possua um valor para a chave keyAcausar uma exceo. ~ E. Chamar o setAttribute (~keyA", ~valueB") em um HttpSession que j possua um valor para a chave keyAfar com que o valor anterior para este atributo seja substitudo pela String

valueB.

- fJr tJP'j';tJ es-l-~ IPtc61'1"e-l-t!..J p61'{pe -I-ip" tie 1"e+"1"If6e 0!(jec+.

tJ

- fJr 6f,';" es-l-: IPtC61"1"e+~fI"3{jei!f-l-a ja d,a_tio. apel1f),Ssvbs-l-,.-I-v""'f), () Vf),I",.. exishl1h.

276

captulo 6

gerencamento

da sesso

8 Quais interfaces definem um mtodo getSession{)?


eli\. ServletRequest elB. ServletResponse ~C.HttpServletRequest elD. HttpServletResponse

(Escolha todas as que se aplicam.)

9 Seja um objeto sesso 5 e o cdigo:


s.setAttribute(~key", value); Quais dos listeners podem ser notificados? (Escolha um.) eli\. i\penas o HttpSessionListener. elB. i\penas o HttpSessionBindingListener. elC. i\penas o HttpSessionAttributeListener. elD. O HttpSessionListener elE. O HttpSessionListener DG. Todos os trs.
- Pr 4pl4 F li C41'1'rl-fl.)p4t''lll'!. H#p5es Si61'1t;r#I'''!w/~L''s+el'1l!.I' VIYI, I!.114+'-llCfl.d<lse""I'e

e o HttpSessionBindingListener. e o HttpSessionAttributeListener. e o HttpSessionAttributeListener.

~ F. O HttpSessionBindingListener

3";

VIYIa.f-l't!IlI-l-<I I!.aCl"escel'l-l-ad<l) e <I <lfje-l-tl valtll" .f-alYlIJelYt sel"a I1tl+'-llcfl.d<l se ele iJty>lelYlelr-fl.l' VlYtff#p5essl41'18t"ldtI'15L,"sI-e",el".

10

Considerando que req um HttpServletRequest, quais das opes criam uma sesso, caso no exista nenhuma? (Escolha todas as que se aplicam.) req. getSession (true) ;
- Prs tlpjces Pr e

~ i\. req.getSession{);
~B. elC. req.getSession(false); elD. req. crea teSession () ; elE. req.getNewSession(); elE req. createSession (true) ; elG. req. createSession (false) ;

8 cri"tJ.I'';<I"IYtfl."'''lia

Cfl.Stl I'e.f-"I'I'IfJ. tllYI

l'l6.tl ex'"s+-fI. "IYta. O 5rl-5essftll'l(IfJ.lstl) l'es"l-I-ad6 "Ivl" se fi. S(,SS';<l '"146

voc est

li>

277

res.lJostas do teste

11 Dado

o objeto sesso s com dois atributos chamados myAttrl e myAttr2, quais alternativas removero ambos os atributos desta sesso? (Escolha todas as que se aplicam.)

DA. s. removeAllValues () ;
~B. s.removeAttribute(~myAttrl");s.removeAttribute(~myAttr2");

De. s. removeAllAttributes

() ; UNBIND);

DD. s.getAttribute(~myAttrl", UNBIND) ;s.getAttribute(~myAttr2", DE. s. getAttributeNames (UNBIND) ;

- /} cp{,c 8 es+: cCI'I'e+a. e> reIMclleA-#rl/JlI+eO a tfJ'JlcafUIMtI. de de VIMctje+ de cada lIe;.

reIMCllerIMCS VIMa+l'lltll+C e ele reIMclle VIMa+l'lltv+c

sess46;

12

Quais das seguintes declaraes sobre os objetos HttpSession em um ambiente distribudo so

verdadeiras? (Escolha todas as que se aplicam.) (5ervle+v2..~pt.s. (,0) DA. Quando uma sesso movida de uma NM para outra, quaisquer atributos armazenados na sesso sero perdidos. DE. Quando uma sesso movida de uma NM para outra, os objetos HttpSessionBindingListener devidamente registrados sero notificados.

~ C. Quando uma sesso movida de uma NM para outra, os objetos HttpSessionActivationListener devidamente registrados sero notificados. ~ D. Quando uma sesso movida de uma NM para outra, os valores dos atributos que implementam java. io. Serializable sero transferidos para a nova NM.

13

Quais declaraes sobre o timeout das sesses so verdadeiras? (Escolha todas as que se

aplicam.) (A-fI) DA. As declaraes de timeout da sesso que foram criadas no DD aceitam o tempo em segundos. ~ E. As declaraes de timeout da sesso que foram criadas no DD aceitam o tempo em minutos.

~c.

As declaraes de timeout da sesso que foram criadas programaticamente em segundos.

aceitam o tempo aceitam o tempo aceitamo tempo

DD. As declaraes de timeout da sesso que foram criadas programaticamente em minutos. DE. As declaraes de timeout da sesso que foram criadas programaticamente em minutos ou segundos.

-lJlJlJ; secs IISfJ,t'IMCS c eleIMe'l+c <ses s~ f-cJew"t;s espect/lcal' IMi'J'1V+cs. Se flSal'IMS {;SlDJ'J-+,'w,ecl.I+:> se+MlJ.xI'Iac~veI'I+ervtl.IO ft#pSesS'i'c"l; ape"lfJs6S se51.1"1rJs p6r1eIM seI' especr-li'caJ6S'.

rJ

278 capitulo 6

gerenciamento

da sesso

14 Escolha

o trecho do cdigo servlet que ativaria a partir de uma solicitao o valor de um cookie denominado "ORA_ UID"? (Escolha todas as que se aplicam.)

DA. String value DB. String value


li2'

= request.getCookie("ORA _illD"); = request.getHeader("ORA _UID");


cookies

c. javax.servlet.http.Cookie[]
request.getCookies(); String String if eName value ~ null;

-If (Jp{(J If f"efef'ellt: ".(J t:xtsh.

S't: 4 tllfI lfI.f(JtJ(J

- If

= null;
!= null) { i++){

(eookies for

(JPS.(J C f"ect:be 1I1f1 41'1'" C(J"kte lIsa"tJ(J (J relles.f'5~k"e$()J e tJepi'$ verlflca a exts+eJfci'fJ; tJe IIIf1 c/:te

(int i = O; i < eookies.length;

de "(Jlfle espec,ftc(J.

eName

= eookies[i].getName(); if (cName != null &&


eName.equalsIgnoreCase(~ORA_UID"){ value ~ cookies[i].getValue();

-If

pS."
Jf

b 1J11.44pf!114$
tAl'f"4j.

tl p"tlflt:if"tl

C"l:te

DD. javax.servlet.http.Cookie[] request. getCookiesO;


if (eookies.length String value

cookies

> O) {
.getValue();

~ eookies[O]

15

Qual(is) mtodo(s) pode(m) ser usado(s) para pedir ao continer para notificar seu aplicativo sempre que uma sesso estiver com o tempo esgotado? (Escolha tudo que se aplica.)

li2' A. HttpSessionlistener.sessionDestroyed;

DB. HttpSessionBindingListener.valueBound;
li2' C. HttpSessionBindingListener.valueUnbound;

DD. HttpSessionBindingEvent.sessionDestroyed; DE. HttpSessionAttributeListener.attributeRemoved; DF. HttpSessionActivationListener.sessionWillPassivate;

voc est

11>

279

reSiPos:tas do teste

16

Como voc usaria o objeto HttpServletResponse cliente? (Escolha todas as que se aplicam.)

em um servlet para adicionar um cookie no

DA. <context-param>
<param-name>myCookie</param-name> <param-value>cookieValue</param-value> </context-param>

Dff es+~ il'/c{>l"l"e+a,;ffJf'3l1e (> ""fj-lNJIJ ~JdC<)fJJ:i'eO ehlpl'ej" li"" IJtje-l-

- jf

C6fJtte) e I'/ :5+1"I"1'I5s,

- /} "ff6 b es+:
eltJ.

'''''CIJI''I'e+a,; p"l"?Jve (J;/-lV{J;I7J6) e

OB. response.addCookie("myCookie"," ~ C. javax.servlet.http.Cookie


// ...set other Cookie

cookie Value");

""6S+I'~ V"" servle+ Cf'i'o.I1JIJ11""c6/i:ie.

newCook
properties

new javax.servlet.http.Cookie(~myCookie","cookieValue");

response.addCookie(newCook);

OD. javax.servlet.http.Cookie[]
String if cname

cookies

= request.getCookiesO;

= null;
!~ null) { i++) (

(cookies for

(int i = O; i < cookies.length; cName if

= cookies[i] .getName();
!= null && ( .getValue();

(cName

cName.equalsIgnoreCase(~myCookie")) out.println( eName

+ ~: ~ + cookies[i]

11 Dado:
13. 14. 15. 16. public publie elass ServletX extends HttpServlet ( void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException ( (req); HttpSession sess = new HttpSession sess.setAttribute(~attrl", sess.invalidate(); String ) s ~ sess.getAttribute(~attrl");

17 .
18. 19. 20. 21.

Qual o resultado? (Escolha tudo que se aplica.) ~ A. A compilao falha

O. .B.
De.

O valor de s e null O valor de s "value"

_ {) D 1Jr:a ;,.",t.o.I' : "~ ~lIe ihlp . Ie""e'7ra L "tie.,-/) "


lXe+5esstIJJ'I( ).

,,,,,c/)f'reh..

Vc <IJSlltl"e 11""
re'!.. fi

#-/-+p5eSSi{IIlSfA'7JIJ ,

OU. Uma IOException enviada DE. Uma ServletException enviada

DF. Uma IllegalStateException

enviada

280 capitulo 6

USand9 9 JSP

Sendo umJSP

Um JSP torna-se um servlet. Um servlet que voc no cria. O Container olha o seu JSP, o traduz em cdigo-fonte Java e o compila em uma classe servlet de Java completa. Porm, voc tem que saber o que acontece quando o cdigo que voc escreveu em JSP se transforma em cdigo Java. Voc pode escrever cdigos Java em JSP, mas ser que voc deveria? E se voc no escrever o cdigo Java, o que voc escrever? Como ele faz a traduo para o cdigo Java? Neste captulo, veremos seis diferentes tipos de elementos JSP - cada um com seu prprio propsito e, sim, sintaxe nica. Voc aprender como, por que e o que escrever no seu JSP. Talvez o mais importante, voc aprender o que no escrever no seu JSP.

este

um

novo ca{.ltu,rO'"

281

objetivos do exame oficial da Sun

os
o Modelo
de Tecnologia do JSP Notas sobre

a Abrangncia:

6.1 Identificar, descrever ou escrever o cdigo JSP para os seguintes elementos: (a) template text, (b) elementos de scripting (comentrios, diretivas, declaraes, scriptlets e expresses), (c) aes-padro e customizadas, e (d) elementos da expression language. 6.2 Escrever o cdigo JSP que usa as diretivas: (a) page (com os atributos import, session, contentType e isELIgnored), (b) include, e (c) taglib. 6.3 Escrever um Documento JSP (documento baseado em XML) que usa a sintaxe correta. 6.4 Descrever o propsito e a seqncia de eventos do ciclo de vida de uma pgina JSP: (1) traduo da pgina JSP, (2) compilao da pgina JSP, (3) carregar a classe, (4) criar a instncia, (5) chamar o mtodo jspInit, (6) chamar o mtodo jspService, e (7) chamar o mtodo jspDestroy. 6.5 Dado um objetivo de design, escrever o cdigo JSP, usando os objetos implcitos apropriados: (a) request, (b) response, (c) out, (d) session, (e) config, (f) application, (g) page, (h) pageContext, e (i) exception. 6.6 Configurar o deployment descriptor para declarar uma ou mais bibliotecas de tags, desativar a linguagem de avaliao e desativar a linguagem de scripting. 6.7 Dado um objetivo de projeto especifico para incluir um segmento JSP em outra pgina, escrever o cdigo JSP que usa o mecanismo de incluso mais apropriado (a diretiva include ou a ao-padro jsp:include).

A maioria tratada neste captulo, mas os detalhes que envolvem as (c) aes-padro e customizadas e (d) os elementos da expression language sero abordados nos prximos captulos.

A diretiva de pgina ser abordada neste captulo, mas o include e a taglib sero abordados nos prximos captulos. No ser abordado aqui; verifique o captulo sobre Distribuio. Tudo abordado neste captulo. (Dica: estas sero algumas das perguntas mais tranqilas do exame, uma vez que voc aprendeu o bsico neste captulo.) Tudo abordado neste captulo, embora se espera que voc j saiba o que a maioria deles significa, baseado nos dois captulos anteriores. Ns falamos sobre tudo aqui, exceto declarar as bibliotecas de tags, que ser visto no captulo Usando a JSTL.

No abrangido aqui; verifique no prximo captulo (JSP sem scripts).

282 captulo 7

usando

o JSP

No fitM das comas, o JSP s

UtM servlet

seu JSP toma-se um servlet completo rodando em sua aplicao. E muito parecido com qualquer outro servlet, exceto pelo fato de que a classe do servlet escrita para voc - pelo Container. O Container utiliza o que voc escreveu no seu JSP, o traduz para um arquivo-fonte da classe servlet (.java) e o compila em uma classe servlet Java. Depois disso, ele ser s um servlet e rodar exatamente do mesmo jeito, como se voc mesmo tivesse escrito e compilado o cdigo. Ou seja, o Container carrega a classe servlet, instancia-a e inicializa-a, cria uma tbread para cada solicitao e chama o mtodo serviceO do servlet.

, carregado

traduzido
-paro.

~
MyJSP.jsp

com-pila em

: ini ciali zado como

~
MyJSP jsp Servlet

MyJSPjsp.class

Algumas das perguntas que responderemos neste captulo so: ~ Para onde vai cada parte do seu arquivo JSP no cdigo-fonte do servlet? ~ Voc tem acesso s caractersticas "sem servlet" da sua pgina JSP? Por exemplo, o JSP tem noo do ServletConfig ou do ServletContext? ~ Quais so os tipos de elementos que voc pode inserir em um JSP? ~ Qual a sintaxe para os diferentes elementos de um JSP? ~ Qual o ciclo de vida de um JSP? Voc pode interferir nele? ~ Como os diferentes elementos de um JSP interagem no servlet final?

voc est

283

fazendo um JSP

Criando

UtM

JSP que exiba quatttas vezes ele foi acessado

Pauline quer usar JSPs em suas aplicaes - ela est realmente cansada de escrever HTML no seu mtodo printlnO do PrintWriter do seu servlet. Ela decide aprender JSPs, criando uma pgina dinmica simples que exibe o nmero de vezes que ela foi solicitada. Ela sabe que voc pode colocar um cdigo Java normal em um JSP usando um scriptlet - que significa simplesmente o cdigo Java dentro de uma tag <% ... %>.

J que eu posso colocar cdigo Java no JSP, vou criar um mtodo esttico em uma classe Counter, para manter a varivel esttica de contagem de acessos e chamar este mtodo a partir do JSP ...

BasicCounter.jsp
<html> <body> The page <% count is:

out.println(Counter.getCount(;

</html> ~~bOdY>

1/ D cltje+6
(jiJ.f

1Vi/ce~l'e
3iJe a,eJ1s's

es+a ,~/u:r+t'J <% e %> iJl;i SCl'l,+le+J


JIJ.IIs'

s,~/es.

Counter.java
package foo;

public class Counter ( private static int count; public static synchronized count++i return count;

int getCount()

Clas se (;.s sis-k?t-k


JlJ.1I4

siMples.

284 captulo 7

usando o JSP

Ela distribui e testa o JSP


Distribuir e testar trivial. A nica parte confusa garantir que a classe Counter esteja disponvel para o JSP. E isso fcil: basta coloc-Ia no diretrio WEB-INF/classes da aplicao. Ela acessa o JSP direto pelo browser: http://localhost:8080/testJSPl/BasicCounter.j sp

The page count is: 1


!tdjhqn Jfhq.i F.ijqof

BasicCouj'-fr.jsp
Kcljhgn

3fhg.i

Fijgof

weh.'<rnl

Po.l'fJ.

flc
"-'OlOI

I
Ctl/lJ3ve b ,/il'e-l-/-l'ltJ pfJ.clJh e" al'3VlV6 JI1lJ .,fll'e-l-/-I't

~.,m

Couni~~lcla"
HTTP Status 500 an internal error The server encountered

J (J

o that

prevent

it from

fulfilling c1ass

this request.

.class

II!!J!IIorg.apache.jasper.JasperException:
An errar occurred at line 1 in the jsp file :/Basic Generated servlei errar:

Unable to compile Counter.jsp

for JSP

w$-IIJFI

Uavac} Compiling 1 source file IUsers/kathy/App[ications2/jakarta-tomcat-5.019!workfCatalinaJIocalhostltestJSP1/org/apache/jspl ~::~~I~U;~~~f~ba~~~:;cannot resolve symbol location: class org.apache.jsp.basicCounterjsp

clo.sses)

,/es"F1.I.apltcl.l.fl.l.o sel'lt

e 1Jtltl,!fl/el'pfJ.l'h '" I

\4,c

C611Se
':5

Vf

"

out.pri~t( Counter.getCountO); 1 error

capa; Je ve-!c.

eJ1ffJ1Jel' IJ 3(1E' Jev E'I'I'D.,/?


127)

org.apache.jasper.compiler. DefaultErrorHandler.javacError(DefaultErrorHandler.java: org.apache.jasper.compiler. ErrorDispatcher.javacError(ErrorDispatcher.java:351 ) org.apache.jasper.compiler.generateclass(Compiler.java:415) org.apache.jasper.compiler.Compiler.compile(Compiler.java:458) org.apache.jasper.compiler.Compiler.compile(Compiler.java:439) org.apache.jasper.JspCompilalionContext.compile(JspCompilationContext.java:553) org .apache.jasper.servleUspServletWrapper.service(JspServletWrapper.java:291 ) org .apache.jasper.servleUspServlet.serviceJspFile(JspServlet.java:301 ) org.apache.jasper.servleUspServlet.service(JspServlet.java :248) javax.servlet-http.HttpServlet.service(HttpServle1.java:856)

.,

voc est aqui .

o atributo imporl da diretiva da pgina

o JSP Ko recoKhece

a classe Couttter

A classe Counter est no pacote foo, mas no h nada no JSP capaz de reconhec-Ia. idntico ao que acontece com voc em qualquer outro cdigo J ava. E voc conhece a regra: importe o pacote ou use o nome da classe totalmente qualificado no seu cdigo.

Eu acho que voc tem que usar o nome da classe totalmente qualificado dentro dos JSPs. Faz sentido, pois todos os JSPs foram transformados em cdigo servlet Java simples pelo Container. Mas claro que eu gostaria que voc pudesse colocar im orts no seu cdigo JSP ... package foo;

Counter.java

C>

public class Counter ( private static int count; public static int getCount() count++; return count;

o cdigo o cdigo

JSP era:
%>

<% out.println(Counter.getCount());

JSP deveria ser:


%>

<% out.println(foo.Counter.getCount());

1"f3eJl'IJ. V ai

Il.~

. fVl'fcitJl'ltU".

286

ca(,~twro

usando

o JSP

Mas voc PODE incluir declaraes import num JSP... basta ter uma diretiva.

C>

Use a diretiva de pgitla para itMportar pacotes


A diretiva um recurso que voc tem para dar instrues especiais ao Container no momento da traduo da pgina. As diretivas vm em trs sabores: page, include e taglib. Ns veremos as diretivas include e taglib nos prximos captulos. Por enquanto, nossa preocupao ser com a diretiva page, porque ela a nica que nos permite importar.

Para importar um
<%@ page

nico

pacote:
f.s-t-a
%> '-(----

vh'la
#f",

ptl.Je

'import="foo. *"

C"'h'I Vh'I

J. J tlrlpl:il"r. ------y fJ.-rl"tbvr

<html> <body>
The page <% count is: ;
\

(Obsel"ve 3ve

1.:
11/J

out.println(Counter.getCount()
%>

#fel1t.VIt'Ip.m-t-.re-v{,.jVifJ. tli711.1 '/4 di're.f.tV4).

</body> </html>

Os scrlh-t-Ie.f.s r

s", Jtlva

l1",rh'lal:S-~l"'j4.) -t-6'/fJ.S as decl41"l~f;e:s e:1t'I VIt'I scriphe-tdevel!l1 -I-erh'lli7ar C<ll1!l1 Vh'I

Para importar

mltiplos

pacotes:

p61'1-t-c-e-v:l"jVIQ.! %>

<%@ page import="foo.*,java.util.*"

1',
ti se
VI!l1Q.

VlrjvllA parti

separlAl" .os pIAC6-1-eS.

II:S--t-a 1i1-1-etra '/e pll.CfJ-I-es vel!l1fl'1-t-re

Reparou a diferena entre o cdigo Java que exibe o contador e a diretiva de pgina? O cdigo Java vem entre os smbolos <% e %>. Mas a diretiva acrescenta um caractere a mais no comeo do elemento - o smbolo @ (arroba)! Se voc vir um cdigo JSP que comea com <%@, voc j sabe que se trata de uma diretiva. (Ns entraremos em maiores detalhes sobre a diretiva de pgina mais adiante.)

voc est

287

usando expresses

Mas etlt seguida Kitlt tltetlciotla as "expresses~~


Justo quando voc pensou que fosse seguro, o Kim percebe o scriptlet com uma declarao out.printlnO. Isto JSP, pessoal. Grande parte da razo do JSP evitar o printlnO! por isso que existe um elemento expresso no JSP - ele exibe automaticamente aquilo que voc colocou entre as tags.

Voc no precisa dizer out. printlnO em um JSP! Basta usar uma expresso ...

o cdigo
<%@

script/et:
%>

page import="foo.*"

<html> <body> The page count is: <% out.println(Counter.getCount()); </body> </html>

%>

o cdigo
<%@ page <html>

expresso:
import="foo.*" %>

<body> The page count is now: <%= Counter.getCount() </body> </html>


I"f

%>

It expJ"esst'uJ'" e'"fJi'\tds cClJ"-ra J


IJ

I - I1IJS

pJ"edsfJ.fJi'\lJs escJ"eveJ"

Notou a diferena entre a tag para o cdigo scriptlet e a tag da expresso? O cdigo scriptlet vem entre os sinais de porcentagem <% e >%. J as expresses recebem um caractere adicional no incio do elemento: um sinal de igual (=). At agora ns j vimos trs tipos diferentes de elementos do JSP: Scriptlet: Diretiva: Expresso:

<% <%@ <%=

%> %> %>

288 capftuio 7

usando oJSP

O;;Je es+: po;;+-e-v!rjVla?

<%= Counter.getCount()

%>

As expresses se tOl11atM o argUtMettto out.prittt()

para UtM

Em outras palavras, o Container carrega tudo o que voc digita entre <%= e >% e acrescenta como argumento para uma declarao que exibe para a resposta implcita out do PrintWriter.

Quando o Container encontra isso:


<%~ Counter.getCount() %>

Ele o transforma nisso:


out.print(Counter.getCount();

Se voc colocou mesmo um ponto-e-vrgula na sua expresso:


<%= Counter.getCount(); %>

Isso mau. Significaria isso:


out.print(Counter.getCount();) ;

'x.l!! Is+

i1Vl1ca

NUNCA termine uma expresso com um ponto-e-vrgula! <%= nuncaColoqueUmPontoEVrgulaAqui <%= porquelstoUmArgumentoParaPrintO %> %>

voc est

289

expresses

e diretiva

de pgina

N&9 exIstem

feth'untas dl9tas
Y:
Bem, se voc tem que usar as expresses EM VEZ DE colocar o out.printlnO em um scriptlet, ento por que existe um "out" implcito? Diga quais das seguintes expresses so vlidas, ou no, e por qu. Ns no abordamos todos os exemplos aqui; portanto, use a sua imaginao, baseado no que voc j sabe sobre o funcionamento das expresses. (As respostas esto mais adiante neste captulo; ento, faa o exerccio AGORA). Vlido? (Verifique se vlido ou no, justificando quando no for.) 0<%= 27%>

I\: Voc provavelmente no usar a varivel out implcita de dentro da sua pgina JSP, mas
voc pode pass-Ia adiante ... alguns outros objetos que so parte da sua aplicao no tm acesso direto ao stream de sada de dados da resposta.

f:

Em uma expresso, o que acontece se o mtodo no retomar coisa alguma?

0<%=

((Math.randomO

+ 5)*2); %>

I\: Voc receber

um erro!! Voc no pode, e NO DEVE, usar um mtodo com um tipo de retorno void como uma expresso. O Container esperto o suficiente para descobrir que no haver nada a exibir se o mtodo tem um tipo de retorno void! Por que a diretiva import comea com a palavra "page"? Por que <%@ page import %> em vez de simplesmente <%@ import %>?

0<%=

"27"%>

0<%=

Math.randomO %>

Y:

0<%=

String s = "foo" %>

0<%=

new String(3]) %>

I\: Boa pergunta! Em vez de possuir uma


enorme pilha de diretivas, a especificao JSP tem apenas trs diretivas, que podem ter atributos. O que voc chamava de "a diretiva import" na verdade "o atributo import da diretiva da pgina".

0<%

= 42*20; %>

0<%=

5>3 %>

Y:

Quais so os outros atributos para a diretiva da pgina? a diretiva da pgina para dar ao Container a informao de que ele precisa quando traduz seu JSP para servle1. Os atributos que nos importam (alm do import) so: session, content-Type e isELlgnored (falaremos deles mais adiante neste captulo).

0<%=

false %>

I\: Lembre-se,

0<%=

new CounterO %>

290 captulo 7

usando

o JSP

KiiM solta a bOiMba fi"al...

C>

Humm... eu sei que o JSP se transforma em um servlet. Ento, talvez eu possa declarar uma varivel contadora em um scriptlet que transformar-se-ia numa varivel no servlet. Ser que funcionaria?

o que ela tentou:


<htrnl> <body> <% int count=O; %> The page count is now: <%= ++count %> </body> </htrnl>

Isto vai compilar? Vai funcionar?

voc est

291

variveis scr~[)tet

l1eclarat1do ui\ta varivel ei\t Ui\t scriptlet


A declarao da varivel vlida, mas no funcionar conforme Pauline esperava.

o que ela tentou:


NtlS I1Q4pt't;ClSQIi\4S i'I'y>tlf'T"fi.t' P/4JQ; f.P/T"Q4P/IJ$
<body> .~ N ~ ~

<htrnl> ~.f>tlI41i\(J$ count=O; %> %>~

fi.

Jlt'e-ftv4 lJedl3.t'Q

tia P~i"'fl,.
fi.

sct'ifJ,~ .----*
flfpt'es SIM

<% int

The page count is now:


<%= ++count </htrnl> </body>

v4F'ttJ.lIef cdP/.fQdt'4

-r J 4 VfJ.t'ltJ.lle!ctmT"adlJt'13. I J..p/ct'eli\e"T"a
fi:

exl!le ti IIlJ,lf'.

o que ela viu na primeira vez que abriu a pgina:

The page count is: 1

o que ela viu na segunda, na terceira


a pgina:

e em todas as outras vezes em que ela abriu

usando

o JSP

o que REALMENfE acomece

COtlt

o seu cdigo JSP?

Voc escreve um JSP, mas ele vira um servlet. A nica maneira de saber realmente o que est acontecendo ver o que o Container faz com o seu cdigo JSP. Ou seja, como o Container traduz o seu JSP em servlet? Uma vez que voc saiba onde os diferentes elementos do JSP se encontram no arquivo de classe do servlet, voc achar muito mais fcil de saber como criar a estrutura do seu JSP. O cdigo do servlet nesta pgina no o cdigo verdadeiro gerado pelo Container - ns o simplificamos e aproveitamos o essencial. O arquivo do servlet gerado pelo Container , digamos, mais feio. O verdadeiro cdigo-fonte do servlet gerado um pouco mais dificil de ser lido, mas ns o veremos nas prximas pginas. Contudo, por enquanto, o que nos interessa onde o nosso cdigo JSP realmente termina na classe servlet.

Este JSP:

Torna-se este servlet:


public class basicCounter_jsp SomeSpecialHttpServlet { extends

public void jspServlce(HttpServletRequest request, HttpServletResponse response)throws java. io.IOException, ServletException { PrintWriter out = response.getWriter(); response.setContentType("text/html"); ~ out.write("<html><body>"); %>----------~.int count=O; is now:");

<html><body> <% int count=O;

The page count is now :-----~ out. wri te ("The page count <%= ++count %>---------------pout.print( ++count ); </body></html>-------------~.out.write("</body></html>");

I
O CM-/-oJnel' c"IIJCil. -/-l:Jtl.a lJ ctl.ij" e"'" v"'" "",:J..tl."sel'lIi'ce PePlse PIe/e C<:l""''' v"'" tl.tJbe-/-1 tl.lJ~s-/- ~ve

TODOS os cdigos do scriptlet e das expresses ficam em um mtodo service. Isto significa que as variveis declaradas em um scriptlet so sempre variveis LOCAIS!

tJ.1'((I'.f.ir AI".f.tJ.:Se checal' cttl.fjlJ J sel'vle.f. jel'aJ 1;"",ca.j.jvoc V~4 sVi"sel' e"",H'JI',:elJ'i"PlJSev1;irlca..f.!WIJl'k! Ca.f.ali'PlfJ.! JlJ AliJirlePI!JSevSel'vMtJl' (AJ.'irlebtJ.SvaApli'co.{i! svbl,i,t.IJ.JJS irlvJI<I''i,,; JepenJenJIJ IJ1'5! 4p4ct.e;Jsp.
ti!

(Os nlJirles

JIJ sev sts.feirlt.(

Jfi. SVfJ.IJ.f1i'clJ.g'i,,)

voc est aqui..

293

declaraes JSP

D
PrecisatMos de outro e1etMettto JSP ...
Declarar a varivel contadora no scriptlet nos mostrou que a varivel foi reinicializada cada vez que o mtodo de servio rodou. Quer dizer que ela foi reiniciada para Oa cada solicitao. De alguma forma, precisamos tomar count uma varivel de instncia. At agora, ns vimos as diretivas, os scriptlets e as expresses. As diretivas so para instrues especiais para o Container, os scriptlets so Java simples localizados dentro de um mtodo service do servlet gerado, e o resultado de uma expresso sempre se toma o argumento para um mtodo printO Mas existe um outro elemento JSP chamado declarao.

<%!

int

As declaraes JSP servem para declarar membros da classe do servlet gerado. Isto significa as variveis e os mtodos! Portanto, tudo que estiver entre a tag <%! e %> adicionado classe fora do mtodo service. Logo, voc pode declarar os mtodos e as variveis estticas e de instncia.

294 captulo 7

As declaraes JSP
Vma declarao JSP sempre definida dentro da classe, mas fora do mtodo service (ou qualquer outro). E simples assim: as declaraes servem para as variveis estticas e de instncia e para os mtodos. (Na teoria, sim, voc poderia definir outros membros, incluindo as classes internas, mas em 99,9999% das vezes voc utilizar as declaraes para os mtodos e as variveis.) O cdigo abaixo resolve o problema de Pauline; agora, o contador incrementado cada vez que um cliente solicitar a pgina.

A Declarao da Varivel Este JSP:

Torna-se este servtet:


public class basicCounter jsp extends HttpServlet {

Gint
<html><body> <%! int count=O; %> The page count is now: <%= ++count %> </body></html>

public void request, count=O;

jspService(HttpServletRequest HttpServletResponse

response)throws java.io.IOException { PrintWriter out = response.getWriter(); response.setContentType(~text/html"); out.write(~<html><body>"); out.write(~The page count is now:");

out.print( out.write("</body></html>"); ++count ); ~

.~

'\

1Jfs-+-a VfjJ fs-+-all'liJS-

tl'Jcl"fll'le"';-tl.I'JJ" lIlI'l~ Je
li1s-+-';"ci'a E

ell'l vej Je lIlI'lfll

vai"lfJ.Velltlcal,

A Declarao do Mtodo Este JSP:

Torna-se este servtet:


public class basicCounter jsp extends HttpServlet {

<html> <body> <%! int doubleCount() { count = count*2; return count;

-nt doubleCount() { count = count*2; return count;


alie

}
int count~l;~

%>
<%! int count=l;

Is-l-e ~ Java.; eP'l.fi) selll fl'b1ellltJ.S N 3vu'I'J-Ireferel1cfu,s de f /'ward (ofedlu'fJ.JlJ.tJ .lu,

%>

!JPOI:5 Sue

l/ec

U,

u-/-NtYJiE

e'1II

VIII hl-l-fJdc),

The page count is now: <%= doubleCount() %> </body> </html>

public void ]spService(HttpServletRequest request, HttpServletResponse response)throws java. io.IOException { PrintWriter out ~ response.getWriter(); response.setContentType(~text/html"); out.write("<html><body>"); out.write("The page count is now:"); out.print( doubleCount() ); out.write("</body></html>");

voc est

o servlet gerado

Hora de ver o VERUAUEIRO servlet

gerado

Estvamos vendo uma verso bem simplificada do servlet que o Container realmente cria a partir do seu JSP. No h necessidade de se ver o cdigo gerado pelo Container durante o desenvolvimento, mas voc pode us-Io para ajud-Io a aprender. Uma vez que voc veja o que o Container faz com os diferentes elementos de um JSP, voc no precisar mais ver os arquivos-fonte .java gerados pelo Container. Alguns fabricantes no deixaro que voc veja a fonte Java gerada, mantendo apenas os arquivos .class compilados. No se intimide quando voc notar partes da API que voc no conhea. Os tipos de classe e interface so, na maioria, implementaes especficas do fabricante que voc no deve se preocupar.

o que o Container

faz com o seu JSP

~ Olha as diretivas, em busca de informaes de que ele possa necessitar durante a traduo. ~ Cria uma subclasse HttpServlet. Para o Tomcat 5, o servlet gerado estende:
org.apache.jasper.runtime.HttpJspBase

~ Se houver uma diretiva de pgina com um atributo import, ele escreve as instrues do import no topo do arquivo classe, logo abaixo da declarao do pacote. Para o Tomcat 5, a declarao do pacote (com a qual voc no deve se preocupar) :

Ns estam os mostrando o cdigo gerado de forma que voc possa entender como o JSP traduzido

para o cdigo servlet. Mas voc no precisa saber em detalhes como um determinado fabricante faz isso e nem a aparncia verdadeira do package org.apache.jsp; cdigo gerado. Tudo o que voc ~ Se houver declaraes, ele escreve-as no arquivo classe, precisa saber como se comporta geralmente logo abaixo da declarao da classe e antes cada tipo de elemento (scriptlet, do mtodo service. O Tomcat 5 por si s declara uma diretiva, declarao, etc.) e como varivel esttica e um mtodo de instncia. aquele elemento funciona dentro do servlet gerado. Voc precisa saber, ~ Cria o mtodo service. O nome real do mtodo : por exemplo, que seu scriptlet pode _j spService (). Ele chamado pelo mtodo usar objetos implcitos, e voc precisa ativado serviceO da superclasse do servlet e recebe o conhecer os tipos de objetos implcitos HttpServletRequest e o HttpServletResponse. Como daAPI Servlet. Mas voc NO parte da construo desse mtodo, o Container declara precisa conhecer o cdigo usado para e inicializa todos os objetos implcitos. (Voc ver mais disponibilizar tais objetos. objetos implcitos quando mudar de pgina.) A nica coisa que voc precisa saber ~ Mistura o HTML simples (chamado template text) com os: sobre o cdigo gerado so os trs scriptlets e as expresses no mtodo service, formatando: mtodos do ciclo de vida do JSP: jsplnitO, tudo e escrevendo no PrintWriter da resposta. : jspDestroy e -.JspServiceO. (Falaremos ~ sobre eles ainda neste captulo.)

. .

...........................................

296

captulo 7

usando

o JSP

A classe gerada pelo Tomcat 5


package import import import public

. org.apache.]sp;
javax. servlet. *; javax. servleLhttp. *; javax. servlet. jsp. *; final class

Se voc -hvel' /T ,. "'~I'h tio.


tiil'e-hv!l:!e
"JI!11t.VIYo, pD.Ji"""J,eles".

<html><body>

<%! int count=O;

%>

~~l!1.l'eCer46 4'1pt(,,6S "46, +e_s


Iw.p~r+ J'II!S+ei.JSP>.

The page count is now: <%== ++count %> </body></html>

BasicCounter_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent

int count=O; private static java.util.Vector jspx~dependants;

O Ca"+IlIPier
public util. List getDependants returnjava. jspx_dependants; () {tie;,+r6 I"

ca!t:,c4

4S

suAs

tias +4itS <%/ % N PI'<JPf't4S d4tXtJ tia tieclaf'IJJaa


request, HttpServletResponse

public response)

void _jspService(HttpServletRequest

throws ServletException JspFactory jspxFactory = null; PageContext pageContext ~ null; HttpSession session = null; ServletContext application ~ null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter jspx_out = null; PageContext jspx_page context null; try

java.io.IOException,

true.

{ jspxFactory = JspFactory.getDefaultFactory(); response.setContentl'ype("text/html"); pageContext = jspxFactory.getPageContext(this, 8192, true); jspx pagecontext = pageContext; ;;-ppli~atio:;;: = pageContext. getServletContext config = pageContext. getServletConfig (); session = pageContext.getSession(); out = pageContext.getOut(); jspx_out ~ out; out.write("\r<html>\r<body>\r"); out.write("\rThe page count is now: \r"); out.print( ++count ); out.write("\r</body>\r</html>\r"); catch (Throwable t) { if (! (t instanceof SkipPageException){ out = jspx_out; if (out != null && ouLgetBufferSize() out.clearBuffer(); context 1= null)

request,

response,

null,

(); A11t ele +e~4 inicia!i;").;' as a~e+"s 11ty>11!:t+as.

!= O) !clar"zveatsp"tietio.rerf'fllti jspx_page contexto

if ( ]spx_page handlePageException(t);
}

} finally { if ( jspxFactory context);


}

!= null)

jspxFactory.releasePageContext(

]spx_page~

voc est

objetos implcitos do JSP

A varivel out no

o nico objeto itMplcito ...

Quando o Contaner transforma o JSP em um servlet, o comeo do mtodo service uma pilha de declaraes de objetos implcitos e atribuies. Com os objetos implcitos, voc pode escrever um JSP, sabendo que o seu cdigo far parte de um servlet. Em outras palavras, voc pode aproveitar as suas caractersticas de servlet, mesmo que voc no esteja escrevendo diretamente uma classe servlet. Lembre-se dos captulos 4,5 e 6. Quais foram alguns dos objetos importantes que voc usou? Como o seu servlet conseguiu seus parmetros init? Como o seu servlet obteve a sesso? Como ele conseguiu os parmetros enviados pelo cliente em um formulrio? Estas so algumas das razes que seu JSP pode precisar para usar alguns dos recursos disponveis para o servlet. Todos os objetos implcitos apontam para algum item daAPI Servlet/JSP. O objeto implcito request, por exemplo, uma referncia ao objeto HttpServletRequest, passado para o mtodo service pelo Contaner.

AP.
JspWriter HttpServletRequest HttpServletResponse HttpSession ServletContext ServletConfig JspException PageContext Object pageContext page ~ " application config exception ~ session

'l.s+e bid- '" 'hy>I:Cl+ disp~JI1:vel ~f.ep!~s ... / p41'a pI.!Jll'l4Sde f!1'1'6detll'litl4s. ~ce Vel'4 lSSIJ 1Pl41$ +al'de)

IJIPl ~l.!JeC~x+ eJOlc4pslI!o. CII+1'6$ atJe+cs 1hy>I,cttas. A-ssi~ se vce pll,SSQI' IIIPlIl, o. 'f,5l/1Pl 4tJe+4 t.elpel'j l'elel'e'1C1~ Pl.!JeCc~x+ ele ptAdf.NI l/S41' es so. I'e-lel'el'lct~ p~l'o. tJb+e,. I'elel'-,cl~s pUo. ()trrJetJS ctJe+cs t""Pl:Cl+tJSe a+dIJII+$ de +ad4s tASescapas.

r:
R:

Qual a diferena entre um JspWriter e um PrintWriter que eu recebo de um HttpServletResponse?

No muita. O JspWriter UM PrintWriter com algumas funes de buffer. O nico momento em que voc deve realmente dar maior ateno a ele quando voc estiver criando tags customizadas. Portanto, falaremos um pouco a respeito das habilidades especiais do JspWriter no captulo que aborda o desenvolvimento das tags customizadas.

298

captulo 7

Exetcc'l9S

Cada um d9Sttecb9s vem de umJSY. Seu ttabalb9 set desc9btlt 9 '1ue aC9nteoot '1uand9 9 C9Iltalnet tentar ttanst9tmat 9 S Y num setVlet. O C9ntalnet set

cap~ dettaduz,'lt 9 seulSY


em um c9d'lg9 setvlet legtlm9 Se n9, p9t '1ue? Em CClS9 at'ltmatlv9, 9 '1ue aC9nteoo '1uand9 um cl'lente aoossat 9 JSY?

e c9mp'llvel?

<htrnl><body> Test scriptlets ... <% int y=5+x; %> <% int x=2; %> </body></htrnl>

<%@ page irnport="java.util.*" %> <htrnl><body> Test scriptlets ... <% ArrayList list = new ArrayList( list.add(new String(ftfoo"));

%>
<%= list.get(O) </body></htrnl> %>

<htrnl><body> Test scriptlets ... <%! int x ~ 42; %> <% int x = 22; %> <%= x %> </body></htrnl>

voc est

exerccos JSP

Im de Gehtde'h'q ([este Ytepttflt9tl9)


Estude o cenrio (e o restante nesta pgina) e coloque os ms no JSP para criar um arquivo legtimo que produziria o resultado correto. Voc no deve usar um m mais de uma vez e nem usar todos eles. Este exerccio supe que existe um servlet (que voc no precisa ver) que recebe a solicitao inicial, associa um atributo no escopo da solicitao e encaminha para o JSP que voc est criando. (Nota: ns chamamos este exerccio de "m de Geladeira (Teste Preparatrio)" em vez de "m de Geladeira", pois a prova est repleta de perguntas "arrastar e soltar" como esta).

Objetivo do Projeto
Criar um JSP que produzir isto:

!The friends who share your hobby of extreme knitting are: IFred lPhilippe

Ui

I O texto

"extreme knitting" vem de um

. l.pradeep ~ Os trs nomes vm de uma ArrayList de atributos da solicitao, chamados "names". Voc ter que receber o atributo do objeto solicitao. Considere que o servlet recebeu esta solicitao e configurou um atributo no escopo da mesma.

parmetro do formulrio de solicitao. ! seu JSP. O servlet obtera a sohcltaao ! primeiro (e ento a encaminhar ao JSP), mas no muda como voc ..V ; ocisto precisa recebera forma es~e par~~etr~ do receber o parmetro no seu JSP.

Zsra
J

a
$<;ll"el-+8.J';6

"e . vle.f- 311e eCll'ltij(,ll'4

O formulrio HTML
<form method~"POST" <html><body>

a.f-I'l!II./7<;

Conselhos e dicas importantes


~ O atributo da solicitao do tipo java. util.ArrayList. ~ A varivel implcita para o objeto HttpServletRequest chamada de request e voc pode us-Ia em scriptlets ou expresses, mas no em diretivas ou declaraes. Independentemente do que voc fizer com um objeto solicitao em um servlet, voc o far dentro do seu JSP. ~ O mtodo servlet do JSP pode processar os parmetros request, pois lembre-se, seu cdigo vai estar dentro do mtodo service do servlet. Voc no precisa se preocupar com o mtodo HTTP(GET ou POST) que foi usado na solicitao.

e teplJls ePlcelI'Ililho.

..

JSP 311e Vee

es.f-: $<;lCl.f-a{.a farei 6 eSCl'evel'/t6.

action~"HobbyPage.do"> Choose a hobby:<p>


name=NhobbyJ'.f size="1"> <option>horse skiing <option>extreme knitting <option>alpine scuba <option>speed dating </select> <br><br> <center> <select

<input type="SUBMIT"> </center> </form> </body></html>

300

usando o JSP

Ns colocamos algumas linhas para voc. O cdigo que voc colocar neste JSP DEVE funcionar com o cdigo que j est aqui. Quando voc tiver terminado, ele deve ser compilvel e produzir o resultado na pgina anterior (voc deve CONSIDERAR que j exista um servlet funcionando, que primeiro recebe a solicitao, configura o atributo "names" da solicitao e encaminha a solicitao para esse JSP).

PARE\
~O

. e u'"

exerc\C\O

Este ~pC\ona\. o ~ sobre a

rao

parte da \
S\ntaxe do

JSP\

The frends

who

share

your hobby

of

are:

<br>

<% Iterator

alo terator ();

voc est

301

respostas dos exerccios

SEJA 9 C9ntUnet I\esp9sta5 O nQ 2 fcil de entender e funciona. O nQ 1 uma questo bsica da linguagem Java (usar uma varivel local antes que ela seja declarada) e o nQ 3 tambm demonstra uma questo bsica da linguagem Java - aquilo que acontece quando voc tem uma varivel local e de instncia com o mesmo nome. Ento veja ... se voc traduzir o cdigo JSP no cdigo Java do servlet, voc no ter problemas em descobrir o resultado. Uma vez que o contedo do seu JSP estiver dentro do servlet, isso Java.
/
s+e J'j CJJy>lftU"/ exahl>le~ V/tl /tl+dl.l ca/tl; <htrnl><body> Test scriptlets ... <% int y=5+x; %> <% int X=2i %> </body></htrnl>

ir:

C<ll>l,{l

escrever

,~
xJ

lf9c~es+:

+e,,+aPld<l vsar a vt<r,-tvel A-Alrf.,5 Zll'i! ela s!:ia Jef;#jiGla. A-

lii15vt<5el>lJt<Vll "l", perl>l,"-k iSslJ e IJ c.cl1+IJ.,#jer "Ic se ,i1C,{l/tlcdfJ. e/tl N!liif'rlll>lfl.r a <lr",!!1>I

"ti sev

C:diJ6 scrij>+le+.

%> <%@ page import="java.util.*" <htrnl><body> Test scriptlets ... <% ArrayList list = new ArrayList(); list.add(new String(~foo")); %>
<%= list.get(O) </body></htrnl> %>

scriptlets ... foo


-;el>l pr<l!;le/tlt<s; exl!;e ., pf'l"'elf' 1I1'J1C) ~e+- (e

da /}N,L.lS.f.

302

captuio 7

usando o JSP

Im de &lade'ita
Resp9staB

Se a sua resposta parecer um pouco diferente e voc ainda acreditar que ela deve funcionar - tente! Voc ter que fazer o servlet que carrega o formulrio de solicitao configurar um atributo e encaminhar (despachar) a solicitao para o JSP.

B8 \
j <html><body>
r

mport="java.util.*"~1i:J

AJ:s fl"eci'sahics

da dll"e.f.lV4 e

de f:.slP;a i'IIV>I"Ij I./-el"a..f<IfJI".

p41" C4t1SadalJrl"l",Lts..f

d4

The friends

who

share

your

hobby

of

1<%= I 1 request.' getParameter ("hobby"l ~


are: <br>

EJIArraYLst~~

[:]

I(ArraYLstlUrequest1
-r ..

IgetAttrbute("names"ll

O~

<%

Iterator it = aI. ~terator (); ~ ______

.L,.p;ICre C SCI"IP"'-'

. I"e-r I 4~tll

IWhilell(t.hasNext(lE3~
,<%= 11

t. next () l

a~

e {j fiYtalt;e o.tlt
Use tlhi4 eXfl"ess';e.

<br> <% } %>

l.p;cel"l"e c blccc de Icep

w"'l!e!

(Se vcc

eS3t1ecel" i's.f.c) ele P;';c c<:JlIV>t/al":)

mport
("names")

voc est

expresses vlidas

a invlidas

u~co~etttrio...
Sim, voc pode colocar comentrios no seu JSP. Se voc um programador Java com alguma experincia em HTML, voc pegar-se- digitando: // isso um comentrio sem pensar duas vezes. Mas se voc o fizer, a no ser que esteja dentro de um scriptlet ou em uma tag de declarao, voc acabar EXIBINDO isso para o cliente como parte da resposta. Portanto, para o Container aquelas duas barras so simplesmente mais texto, como "Ol" ou E-mail :". Voc pode colocar dois tipos diferentes de comentrios em um JSP:

A.P9nte seu lpIS


Respostas

As Expresses Vlidas e Invlidas


Vlidas? l\Z <%=; 27 %>
1;das as Ir.ferats f'I',,,,rftvas valeli<l,

o <%=; ((Math.randomO
AJfi() / () p~;;f<l-e-V(l'j(/lt<

+ 5)*2); %>
1'/';<1

ptlde es+al'

11$11",

l\Z <%=; "27" %>


/1r S+I't''l5 1".feNJ.I

1I~!tfia,

l\Z <%=; Math.randomO %>

~ <!-- comentrio HTML -->


O Container passa isso diretamente para o cliente e o browser o interpreta como um comentrio.

Si"';

D li<l-l-6dD

1'e+61'11t1. Uli<lo. c:1' o..

o <~=;

String s =;"foo" %>

AJf.}O/ ~c 1'/41) pade .fel' """li declaras';" de vadfJ.llel "3"''''

~ <%-- comentrio JSP --%>


Estes so para os desenvolvedores de pginas e, tal qual com os comentrios Java em um arquivo-fonte Java, eles so tirados da pgina traduzi da. Se voc estiver digitando um JSP e quiser adicionar comentrios da maneira como voc os usaria em um arquivofonte Java, use um comentrio JSP. Se voc quiser que os comentrios faam parte da resposta HTML que vai para o cliente (embora o browser no os mostrar ao cliente), use um comentrio HTML.

l\Z <%=; new String[3] ) %>


S'''''J.pDI' t:lIJ I'f:
Je.
<I

,.

0,1'1"" p~de I'/ew seI' S+r'''l5 e VIi<l atJe+ e ~tJe+" e"llll"tldD p{(l'a y""a

decftu'o.S';" prtn+ll1.

0<%

=; 42*20 %>
f.} al',~""-hcfJ. es+: bt>fJ.J Ii<las J.: tlli<l fi: " "', AJ';c f<lde seI' <% "')

AJfi()/
.fe""

esptJ.fD e'1+l'e % 3t1e seI' <%=.

l\Z <%=; 5 > 3 %>


CItJ.I''') p<ll' seI'
YIi<l

btMllo'l'/D) extile +rve.

l\Z <%=; false %>


AJ:sJ: ~ ,. dtsseli<les 3"'e o,s Il.fel'fl.f"$ pr,,,,t+rllt<s St<Dvalfila$'.

l\Z <%=; new CounterO %>


Seli<lpr<l/!Ie a. Is+e IU(tJ.+ael'l.fe S+I'I''I Ir~ ext/! I' e N!sv!+o.d6 +6S
d<l otJe+""

de

304

C8j'Jt1Jlo

usando o JSP

A API para o servlet gerado


gera uma classe a partir do seu JSP, que implementa a interface HttpJspPage. Esta a nica parte daAPI do servlet gerado que voc precisa saber. No se incomode se no Tomcat, por exemplo, a sua classe gerada estenda:
org.apache.jasper.runtime.HttpJspBase

o Container

Tudo o que voc precisa saber so os trs mtodos pnnCIpaIS:

<<interface> > javax.servlet.jsp.JspPage jsplntQ jspDestroyQ

~ jspInitO Este mtodo chamado pelo mtodo irritO. Voc pode anular este mtodo. (Voc consegue imaginar como?)

<<interface> > javax.servlet.jsp.HttpJspPage ~ jspDestroyO Este mtodo chamado pelo mtodo destroyO do servlet. Voc tambm pode anular este mtodo. -.JspService(HttpServletRequest,
""

HttpServlet

\4c MfJrO POJ)

Q#'}lIl,u" es+ef

~ -ispServiceO Este mtodo chamado pelo mtodo serviceO do servlet, o que significa que ele roda em uma thread separada para cada solicitao. O Container passa para este mtodo os objetos Solicitao e Resposta. Voc pode anular este mtodo! Voc no pode fazer NADA por sua prpria conta neste mtodo (exceto escrever o cdigo que vai dentro dele), e responsabilidade do fabricante do Container aceitar seu cdigo JSP e adaptar o mtodo jspServiceO que ir utiliz-Ia.

Observe o underscore no incio do mtodo jspService()


Ele NO aparece no incio dos outros dois mtodos jsplnitQ ejspDestroy(). Faa ~e d conta q~e o underscore no incio do meto o significa "no toque" Portanto, nenhum underscore no m!ClOdOas nome significa que voc pode a~~l~-lo. M; o se EXISTIR um underscore no ZnlClO voce n DEVE tentar anul-Io!

.,.

voc

!I>

305

ciclo da vida JSP

o ciclo de vida

de

UtM

JSP

Voc escreve o arquivo .jsp. O Container escreve o arquivo .java para o servlet no qual o seu JSP se transformou.

Kim escreve um arquivo .jsp e o distribui como parte de uma aplicao.

o Container "l" o web.xml (DD) para esta aplicao, mas no faz mais nada com o arquivo .jsp (at que ele seja
solicitado pela primeira vez).
e I;. I L I 1_' l.S-rtl.JlIs-rall1f!"IT"f: (CCllli;ill"C "lQ sel'vMQI' eSf>/tNJ."Itl.peta
salici1-agl:J

dre"lh.

Web Container

web.xml

o cliente

c1icaem um link que solicita o .jsp.

"

o Container tenta

TRADUZIR o .jsp em cdigo-fonte .java para uma classe servlet.

...-- traduz

"",-

gera

MyJSP.jsp Web Container

MyJSP jsp.java

o Container tenta COMPILAR o cdigofonte .java do servlet em um arquivo .c1ass.

__

compila

___

gera~

Web Container

MyJSP jsp.java

MyJSP jsp.class

306

usando o JSP

o ciclo de vida

do JSP com1ttua...
CARREGA a classe do serv/et gerada recentemente.

o Container

carrega

MyJSP .Jsp.class

Web Container

insta o servlet e faz com que o mtodo jsplnitO dele rode.

o Container

agora um servlet completo, pronto para aceitar as solicitaes do cliente .

o objeto

. ..---

jspInitO ~

..../torna-se~
MyJSP -Jsp MyJSP -Jsp

Web Container

o Container

cria uma nova thread para tratar a solicitao deste cliente, e o mtodo -JspServiceO do serv/et roda.

Tudo o que acontece depois disso simplesmente a rotina normal do servlet para tratamento de solicitaes. Por fim, o servlet envia uma resposta de volta para o cliente (ou encaminha a solicitao para outro componente da aplicao).

Web Container

voc est aqui'"

307

traduo

e compilao

A traduo e a cotMpilao acomecetM

UMA t1ica vez


Quando voc distribui uma aplicao com um JSP, toda a etapa de traduo e compilao acontece uma nica vez na vida do JSP. Uma vez que esteja traduzido e compilado, ele fica exatamente como qualquer outro servlet. E como qualquer outro servlet, uma vez que tenha sido carregado e inicializado, a nica coisa que acontece na hora da solicitao a criao ou a alocao de uma thread para o mtodo service. Portanto, a figura mostrada na pgina anterior e nesta apenas para a primeira solicitao.

r:
I\:

Tudo bem, quer dizer que somente o primeiro cliente a solicitar o JSP que leva a pancada. Mas DEVE haver uma maneira de configurar o servidor para pr-traduzir e compilar ... certo? Embora apenas o primeiro cliente tenha que esperar, a maioria dos fabricantes de Container OFERECE uma forma de fazer toda a tarefa de traduo e compilao acontecer antecipadamente, de forma que at mesmo a primeira solicitao acontea como em qualquer outra solicitao do servlet. Mas cuidado, isso depende do fabricante e no garantido. EXISTE uma meno na especificao JSP (JSP 11.4.2) que sugere um protocolo para a pr-compilao do JSP. Voc faz a solicitao para o JSP anexando uma query string "?jsp_ precompile" e o Container pode (caso queira) fazer a traduo/compilao ali mesmo, em vez de esperar pela primeira solicitao real do cliente.

308 captulo 7

usando o JSP

Se o JSP se transforma em um servlet, eu gostaria de saber se posso configurar os parmetros init do servlet ... e j que estou aqui, ser que posso anular o mtodo initO do servlet ...

Observe estas perguntas. D uma olhada nas pginas anteriores (e captulos), caso ache necessrio, mas no continue antes de terminar. Sim, voc PODE obter os parmetros init do servlet atravs de um JSP, ento, as questes so: 1) Como voc os restaurou de seu cdigo? (Grande, imensa, embaraosa dica: muito parecido com a maneira que voc o restaura em um servlet "comum". De qual objeto voc normalmente obtm os parmetros init do servlet? Ele est disponvel para o seu cdigo JSP?)

2) Como e onde voc configura os parmetros init do servlet?

3) Suponha que voc queira mesmo anular o mtodo initO ... como voc o faria? H alguma outra maneira de se fazer e que traga o mesmo resultado?

voc est

. 309

utrapassando jsplnt( )

lt1icializat1do seu JSP


Voc pode fazer tarefas relacionadas inicializao do servlet com seu JSP, mas um pouco diferente do que voc faz num servlet comum.

Configurando os parmetros init do servlet


Voc configura os parmetros init do servlet para o seu JSP, quase da mesma maneira que voc os configura para um servlet normal. A nica diferena que voc tem que acrescentar um elemento <jsp-file> na tag <servlet>. <web-app <servlet> ... > <servlet-name>MyTestlni

srll.
J

t</ servlet-name>

servle}

/ , 1./ L me V*' li !.II'/tc(;. lI.~Vli!li! Jf'rli!rli!J'I7""fI: c,,*,v*,. Pij basictl*,tl1h: tlfl'?pe


.J II"1'1

<j sp-file> /Testlni t. j sp</ j sp-file> ~ -I-vJ" -I-fAJ <:;el'vle-l-> "" servli-/<init-param> crraJJes-l-t< '(;1' es+a ,a;,"I'IQJSp' <param-name>email</param-name> <param-value>ikickedbutt@wickedlysmart.com</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>MyTestlni t</ servlet-name> <url-pattern>/Testlnit.jsp</url-pattern> </ servlet -mapping> </web-app> ~
t,(lIi:1'7Jti lI"c JIi!/I"I'Ie v*' servle-l- ,b.rt;. li*' JSP v"c Jelle '5l.1a/*,li!l1hJe{tp/i'r .l/e-!Jti " I. JeJSP v*' sel'v *,1I.f'el1,i1 i:I f'a;'p/11,

Anulando o jsplnit()
simples assim. Se voc implementar um mtodo jsplnitO, o Container o chama no comeo da vida desta pgina como um servlet. Ele chamado pelo mtodo initO do servlet, portanto, na hora em que este mtodo roda, haver um ServletConfig e um ServletContext disponveis para o servlet. Isto significa que voc pode chamar o getServletConfigO e o getServletContextO de dentro do jspInitO. Este exemplo usa o jspInitO para recuperar um parmetro init do servlet (configurado no DD) e usa este valor para configurar um atributo de escopo application.

< %! <:

public void j splnit () ServletConfig sConfig

lI*,1:I

getServletConfig();

~c es-l-: "li*' servle-l-; f',,/'hi1-1-j f'tiJe chl1,*,i:I/' sev je-!-Serv/e+e.til'/fijO I.e/'Jo.J".

String emailAddr = sConfig.getlnitParameter("email");~ ServletContext ctx ~ getServletContext(); f\

"

ctx. setAttribute

("mail",

emailAddr); ~

_, Is-l-ti ''} ."~ 'i.'x.A'rA'JtA.Alr se'VlH~_I. 3Vl! Ci1sl!jve V*,11, I'efel'el'/c,"a '111'(;' " S/i!l"v/e+e.tii1hx-l- '! C"lfijVI"RIIhI 4-1-l'ibv+e Je escp tlfplicR+lim.

r)

310

captulo 7

usando

o JSP

Os atributos

etM UtM

JSP

da pgina anterior mostra o JSP configurando um atributo application, usando uma declarao que anule o jspInitO. Porm, na maioria das vezes voc usar um dos quatro objetos implcitos para receber e configurar os atributos correspondentes aos quatro escopos disponveis no JSP. Sim, quatro. Lembre-se, alm dos escopos-padro do servlet - request, session e application (contexto), o JSP acrescenta um quarto escopo - o escopo page -, que voc obtm de um objeto pageContext. Geralmente, voc no precisar (e nem se preocupar) do escopo page, a menos que voc esteja desenvolvendo tags custornzadas. Por isso, no entraremos em maiores detalhes, at o captulo que trata das tags custornzadas.

o exemplo

Em um servlet

Em umJSP (usando objetos implcitos)


application.setAtlribute("foo", barObj); request.setAtlribute("foo", barObj); barObj); session.setAtlribute("foo", barObj); pageContext.setAtlribute("foo", barObj);

Application Request Session


Page

getServletContext().setAtlribute("foo", barObj); request.setAtlribute("foo", barObj); request.getSession().setAtlribute("foo", No se aplica!

Mas no s isso! Em um JSP, existe uma outra maneira de receber e configurar os atributos em qualquer escopo, usando apenas o objeto implcito pageContext. Continue e descubra como ...

"context" .. mesmo que .os No existe um escopo lication estejam assocIados atributos no escopo Wllal!Pl2o'==--ao ob]eto ServletContext.
0

, 10 a pensar que os _ enclatura pode leva- _ d copo context. A convenao de nom S rvletContext sao... o:~ t" atributos armazenados no e do voc encontrar Contex , No existe isso. Lern:br~:s~ q~an existe uma diferena entre os pense em "appliC~~::Sado~;e:;~ obter os atributos do escopo , diz' nomes servlet e], . . . um servlet, voce ,,") apphcatlOn. n ) tAttribute ( foo tservletcontext( .ge ge SP voc diz: mas em um], . t ("foo")

application.getAttrlbu

voc est

311

pageContext

e atributos

Usando o PageCotttext para atributos


Voc pode usar uma referncia PageContext para obter atributos a partir de qualquer escopo, inclusive o escopo page para atributos associados ao PageContext. Os mtodos que funcionam com os outros escopos usam um argumento int para indicar o escopo. Embora os mtodos de acesso derivem do JspContext, voc encontrar as constantes para os escopos na classe PageContext.

JspContext getAttribute(nome da String) getAttribute(nome da String, escopo int) getAttributeNamesInScope (escopo int) findAttribute(nome da String)
lJ'IfctiC$
11 11

ave

IV'7CicPlfJ.IJ'If'fJ.I'fJ.

~II A-L.~fJ!/t. mais mtodos inclusive, mtodos similares 11 para armazenar e remover atributos de 11 qualquer escopo

PageContext APPLICATION PAGE SCOPE SCOPE


ca""ft;S

REQUEST _SCOPE SESSION SCOPE l/mais campos getRequestO getServletConfigO

e$+~+lc"S Ilnats

,
1M,&"d6S para

getServletContextO ct."seSulr ?Jutl.lver getSessionO 6h't!!+ .i""flct+6 1/ mais mtodos ~

312

usando o JSP

ExeiMplosusat1do o pageCotttext para obter e cot1figurar atributos Configurando um atributo do escopo page
<% Float one = new Float(42.5); %> one); <% pageContext.setAttribute("foo",

o pageContext

. getAttribute(stnng) serve para o escopo ~

%>

Obtendo um atributo do escopo page


<%~ pageContext.getAttribute("foo") %>

. DOIS mtodos getAttributeO pode chamar EXistem muito usados que voce . t m de um so no pageContex . u d dois to IString) e outro e argumen \' . ) argumentos (String e mt. todos os . . fiunc I'ona como O prunelro . dos ara atributos aSSOCia outros - P C text O segundo, AO objeto page onado p'ara obter . pode ser us porem, atributos de QUALQUER um dos
A

Usando o eC:Ofl'h;~xt para configurar um atributo do escopo session


<% Float two = new Float(22.4); %> <% pageContext.setAttribute("foo",

quatro escopos.

two, PageContext.SESSION_SCOPE);

%>

Usando o pageContext para obter um atributo do escopo session


<%= pageContext.getAttribute("foo", PageContext.SESSION_SCOPE)
%

%>

(Que idntico a:

<%=

session.getAttribute("foo")

Usando o pageContext
Email is:

para obter um atributo do escopo application


PageContext.APPLlCATION_SCOPE)

<%~ pageContext.getAttribute("mail",

%>

Dentro de um JSP, o cdigo acima idntico a:


Email is:

<%~ application.getAttribute("mail")

%>

Usando o pageContext para encontrar um atributo quando voc no conhece o escopo


.. <%~ pageContext.findAttrlbute("foo") %> enC<lnrI'I'~-I<l<lI'I~e?

Onde o mtodo findAttributeO olha? Ele olha primeiro no page context, e se houver um atributo "foo" com o escopo page context, ento, chamar o findAttribute(nome da String) num PageContext funcionar exatamente como chamar o getAttribute(nome da String) num PageContext. Mas se no existir nenhum atributo "foo", o mtodo comea procurando em outros escopos, do mais restrito ao menos restrito ~ ou seja, primeiro o escopo request, depois o session e, finalmente, o application. O primeiro que ele encontrar com este nome ganha.

voc est

[!>

313

diretriz three

J que estatltOS falatldo sobre isso ... vatltos falar tltais sobre as trs diretivas
Ns j vimos as diretivas usadas para inserir as declaraes import na classe do servlet gerado pelo seu JSP. Foi a diretiva page (um dos trs tipos de diretivas) com um atributo import (um dos 13 atributos da diretiva page). Ns agora daremos uma rpida olhada nas outras, embora algumas no sejam abordadas em detalhes at os prximos captulos. Outras, inclusive, nem sero muito faladas aqui, pois so raramente usadas.

o
8

A diretiva paga
<%@ page import=lIfoo.*" session="false"

%>

Define propriedades especficas da pgina, como cdigos de caracteres, o tipo de contedo para a resposta e se esta pgina deveria possuir o objeto implcito session. Uma diretiva page pode utilizar at 13 atributos diferentes (como o atributo import), embora apenas quatro sejam cobrados no exame.

A diretiva taglib
<%@ taglib tagdir~"/WEB-INF/tags/cool" prefix~"cool"

%>

Define as bibliotecas de tags disponveis para o JSP. Ns ainda no falamos sobre o uso das tags customizadas e aes padronizadas; portanto, talvez no faa sentido neste momento. Fique com isto por enquanto ... teremos dois captulos inteiros sobre bibliotecas de tags vindo em breve.

Adiretiva
<%@ include file="wickedHeader.html" %>

Define os textos e os cdigos que so acrescentados na pgina atual no momento da traduo. Isto lhe permite construir pedaos reutilizveis (como um ttulo-padro para a pgina ou a barra de navegao), que podem ser acrescentados a cada pgina, sem precisar repetir todo aquele cdigo em cada JSP.

r:
1\:

Estou confuso ... o ttulo deste tpico diz: "J que estam os falando sobre isso ...", mas eu no vejo o que as diretivas tm a ver com pageContext e atributos. Nada a ver, realmente. Ns s dissemos aquilo para disfarar a transio inexistente e pattica entre dois tpicos no relacionados. Espervamos que ningum notasse, mas NO ... voc simplesmente no permitiria, no mesmo?

314 capitulo 7

usando

o JSP

Os atributos para a diretiva page


Dos 13 atributos da diretiva page da especificao JSP 2.0, apenas quatro so cobrados no exame. Voc NO precisa memorizar a lista inteira, mas veja o que voc pode fazer. (Veremos os atributos isELIgnored e os dois atributos relacionados a erros mais adiante.) PODE cair na prova -------------------------import Define as declaraes import do Java que sero adicionadas classe do servlet gerado. Voc tem alguns import de graa (por padro):java.lang (bvio),javax. servlet,javax.servlet.http e javax.servletjsp. Define se o servlet gerado precisa implementar o SingleThreadModel que, como voc j sabe, uma Coisa Terrivelmente Ruim. O valor-padro ... "true", o que significa: "Minha aplicao thread-safe e eu NO preciso implementar o SingleThreadModel, pois sei que ruim por natureza." A nica razo para especificar este atributo seria se voc precisasse configurar o valor do atributo para "false", o que significa que voc quer que o servlet gerado use o SingleThreadModel, mas voc nunca/ar isto. Define o tipo MIME (e o cdigo opcional do caractere) para a resposta JSP. Voc conhece o padro. Define se as expresses EL sero ignoradas quando a pgina for traduzi da. Ns s falaremos a respeito da EL no prximo captulo. Por enquanto, saiba apenas que voc talvez queira ignorar a sintaxe EL em sua pgina, e este um dos dois modos que voc pode informar ao Container. Define se a pgina atual representa uma outra pgina de erro dos JSPs. O valorpadro "false", mas se for true, as pginas tm acesso ao objeto implcito exception (que uma referncia ao inconveniente Throwable). Se for false, o objeto implcito exception fica indisponvel para o JSP. Define uma URL para o recurso para onde os uncaught Throwables devem ser enviados. Se voc definir um JSP aqui, ento este JSP ter um atributo isErrorPage="true" na sua diretiva page.

isThreadSafe

contentType isELlgnored

isErrorPage

errorPage

NO cair na prova ---------------------------language Define a linguagem scripting usada nos scriptlets, expresses e declaraes. No momento, o nico valor possvel "java", mas ele est aqui pensando no futuro quando outras linguagens provavelmente sero usadas. Define a superclasse da classe que este JSP tomar-se-. Voc no o usar, a menos que REALMENTE saiba o que est fazendo - ele anula a hierarquia da classe fomecida pelo Container. Define se a pgina ter um objeto implcito session. O valor-padro "true". Define como o buffering tratado pelo objeto implcito out (referente ao JspWriter). Define se a sada bufferizada est limpa automaticamente. O valor-padro "true". Define uma String que inserida na pgina traduzida, exatamente para que voc possa obt-la usando o mtodo getServletInfoO herdado do servlet. Define o cdigo de caracteres para o JSP. O padro "ISO-8859-1" (a menos que o atributo contentType j o tenha definido ou a pgina use a sintaxe XML Document).

extends

session buffer autoFlush info pageEncoding

voc est aqui...

315

so scriptiets maus?

316

captulo 7

usando oJSP

Scriptlets cotlsideradas prejudiciais?


Isso verdade? Poderia haver uma desvantagem em se colocar todo este Java no seu JSP? Afinal, no este todo o PROPSITO do JSP? De forma que voc escreva seu Java no que essencialmente uma pgina HTML, ao contrrio de escrever o HTML em uma classe Java? Algumas pessoas acreditam (tudo bem, tecnicamente um monte de gente, inclusive as equipes que criaram as especificaes do JSP e do servlet) ser uma prtica ruim colocarmos todo este Java no seu JSP. Por que? Imagine que voc foi contratado para construir um grande site. A sua equipe inclui uns poucos programadores Java e um enorme grupo de "webdesigners" - artistas grficos e profissionais que criam pginas utilizando o Dreamweaver e o Photoshop para construrem aquelas pginas fabulosas. Eles no so programadores (bem, existem aqueles que continuam achando que HTML " programao").

Atores

aspirantes

trabalhando

como webdesigners no showbiz.

enquanto

esperam por sua grande oportunidade

voc est

. 317

fora do scripting

Duas perguntas: POR QUE voc est nos ensinando isso e QUAL a alternativa? Que outra m**** EXISTE, alm do HTML, j que no podemos usar scriptlets, declaraes e expresses no JSP?

No EXISflA .,e.,hutMa alternativa.


Isso significa que j existem montanhas de arquivos JSP abarrotados de cdigo Java enfiados em cada pedao da pgina, acomodados entre scriptlets, expresses e tags de declaraes. J est l e no h nada que algum possa fazer para mudar o passado. Portanto, significa que voc tem que saber como ler e entender estes elementos e como manter pginas escritas com eles (a menos que voc tenha a chance de recriar todo o JSP da sua aplicao). C entre ns, at achamos que ainda h lugar para coisas desse tipo - no h nada melhor do que um pouco de Java no JSP para testar rapidamente algo no seu servidor. Mas na maioria das vezes, voc no vai querer usar isso nas suas pginas verdadeiras e em produo. A razo para tudo isto estar no exame que as alternativas ainda so novidade. Por isso, a maioria das pginas hoje ainda "da antiga". Por enquanto, voc ainda tem que ser capaz de trabalhar assim! Em algum momento, quando novas tcnicas que dispensem Java atingirem um pblico considervel, os objetivos deste captulo provavelmente no constaro mais na prova. E respiraremos aliviados pela morte do Java-em-JSPs. Mas esse dia ainda no hoje.

(Nota para pais e professores:

a palavra

de cinco letras implcita no balo acima, que comea com "m" seguida por quatro asteriscos, NO o que vocs esto pensando. simplesmente uma palavra que achamos engraada demais para ser includa aqui, sem que distrasse o leitor. Por isso ela foi truncada. Porque engraada. E no, imprpria.)

318

usando oJSP

Poxa, se pelo menos existisse uma maneira do JSP usar tags simples que permitissem que os mtodos J ava rodassem, sem ter que colocar na pgina o cdigo Java em si.

C>

EL:

a resposta para, digatltos, tudo.

Ou quase tudo. Mas certamente uma resposta para duas grandes reclamaes sobre colocar o lava no lSP:

1. Os designers no precisariam saber Java. 2. O cdigo Java existente no JSP difcil de mudar e manter.
EL significa "Expression Language" e, oficialmente, tomou-se parte da especificao a partir da especificao lSP 2.0. A EL quase sempre o jeito mais simples de se fazer algo que voc normalmente faria com scriptlets e expresses. claro que neste momento voc est pensando: "Mas se eu quiser que meu lSP use mtodos customizados, como poderei declar-Ios e escrev-Ios se no posso usar lava?" Ahhhh ... escrever a funcionalidade real (o cdigo do mtodo) no o propsito da EL. O propsito da EL oferecer um jeito simples de invocar o cdigo lava - mas o cdigo em si pertence a algum outro lugar. Ou seja, uma classe lava simples normal, que funcione como um lavaBean, uma classe com mtodos estticos, ou aquilo que chamamos de Tag Handler. Em outras palavras, voc no escreve o cdigo do mtodo no seu lSP se voc estiver seguindo as Melhores Prticas de hoje em dia. Voc escreve o mtodo lava em algum outro lugar e o chama usando a EL.

voc est

. 319

fora do scripting

UtMa apresentao rpida da

EL

seguinte fala s sobre EL, portanto no entraremos em detalhes aqui. A nica razo de estarmos falando dela devido ao fato de ela ser um outro elemento (com sua prpria sintaxe) que o JSP aceita. E os objetivos da prova que constam neste captulo incluem reconhecer tudo o que possa estar em um JSP.

o captulo

Uma expresso EL SEMPRE se parece com: ${alguma coisa} Ou seja, ela vem SEMPRE entre chaves e precedida pelo smbolo ($).

Esta expresso EL:


Please contact:

${applicationScope.mail}

o mesmo que esta expresso Java:


Please contact: <%= application.getAttribute("mail") %>

f etguntls
r:
1\:

No exIstem

idl9:lS

No querendo ser chato, mas creio no ter visto nenhuma grande diferena entre a EL e a expresso Java. Claro que ela um pouco menor, mas vale a pena mudar toda a linguagem scripting e os cdigos no JSP? Voc AINDA no viu as vantagens da EL. As diferenas tornarse-o bvias no prximo captulo, quando mergulharemos no assunto de cabea. Mas voc deve se lembrar que para um programador Java, a EL NO oferece, necessariamente, uma gigantesca vantagem no desenvolvimento. Na realidade, para um programador Java ela simplesmente significa "uma coisa a mais (com sua prpria sintaxe e tudo) para aprender, quando, psiu, eu j SEI Java ..." Mas no s com relao a voc. A EL muito mais fcil para algum que no programe em Java aprender rapidamente. E para um programador Java, ainda muito mais fcil manter uma pgina sem scripts. Sim, mais uma coisa a aprender. Ela no deixa os webdesigners completamente a salvo, mas voc ver em breve que mais intuitivo e natural para eles usar a EL. Por enquanto, aqui neste captulo, voc simplesmente precisar ser capaz de reconhecer uma EL quando se deparar com ela. E no se preocupe ainda em diferenciar se a EL vlida - tudo que queremos saber agora se voc consegue identificar uma expresso EL em uma pgina JSP.

320

captulo 7

usando oJSP

Usat1do

<Scriptit1g~it1valid>

simples, voc pode impedir que um JSP possua elementos scripting (scriptlets, expresses Java ou declaraes), colocando uma tag <scripting-invalid> no DD:

<web-app

...>

<jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid> true

IS+6

Jesdfll-h.

6S

</scripting-invalid> </jsp-property-group> </ jsp-config> </web-app>

elellP;ePl+6s scri,+tPlj pare.

rf:ibos

(lS JSPs

l'1a fJ.p/'ca{41J

(p.:.r1pe Cuidado - voc pode ter visto outros livros e artigos mostrando uma diretiva page que desabilita o scripting. Na verso rascunho da especificao 2.0, havia um atributo da diretiva page: <%@ page isScriptingEnabled="false" %>

(JSO,IIP;6S tJ *,:}Sf> C(lIIP;(I pfJ.dr'i de tJ/I!.L).

Is+

PI'i tllm:ttJP1e.! () fJ.+rtbll+tJ __

i'sScrip+/'PI;7"PlfJ.b1e.d PI'i<I'J CIJP1s+1J. IIP;lJ,i's PlIJ, especlti'clJ.f'iIJ dlJ JSP/

mas ele foi removido da especificao definitiva! A nica forma de invalidarmos o scripting agora atravs da tag <scripting-invalid> no DD.

voc est

321

ignorando

a EL

Voc pode decidir ignorar a EL


Sim, a EL uma coisa legal que salvar o mundo, como ns j sabemos. Mas algumas vezes voc pode querer desabilit-Ia. Por qu? Lembre-se de quando a palavra-chave assert foi adicionada na linguagem Java verso 1.4. De uma hora para outra, o identificador perfeitamente legal e no reservado "assert" passou a significar algo para o compilador. Ento, se voc tivesse, digamos, uma varivel chamada assert, voc estaria "ferrado". Com exceo da verso J2SE 1.4, que veio com as declaraes desabilitadas por padro. Se voc soubesse que estaria escrevendo (ou recompilando) um cdigo que no usasse assert como identificador, voc poderia escolher habilitar as tais declaraes. Ou seja, quase o mesmo que desabilitar a EL - se voc decidiu ter template text (HTML simples ou texto) em um JSP que inclusse algo parecido com a EL ($ {alguma coisa} ), voc estaria com um Grande Problema, caso no pudesse informar ao Container para ignorar tudo que se parecesse com a EL, em vez de tratar como qualquer outro texto comum. Exceto pelo fato de haver uma grande diferena entre a EL e as assertions:

A EL habilitada por padro!


Se voc quiser que os elementos do seu JSP parecidos com a EL sejam ignorados, voc tem que dizer explicitamente, ou atravs de uma diretiva page ou de um elemento no DD.

A.diretiva page tem

Inserindo <el-ignored> no DD
<web-app ...> <jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <el-ignored> true </el-ignored> </jsp-property-group> </jsp-config> </web-app>

prioridade sobre a configurao do DO!

Se houver um conflito entre a tag <el-ignored> configurada n? D.D o atributo isELIgnored da dlretlva page, a diretiva se,!!pre ga~ha! Isto permite a voce determmar o comportamento-padro no DD, mas, tambm, anul-Io em uma pgina especifica, usando uma diretiva page.

Cuidado com as inconsistncias na nomenclatura!

Usando o atributo isELlgnored da diretiva page


<%@ page isELIgnored="true" %>

l
322 captulo 7

A tag do DD <el-ignored> portanto, algum poderia ' pe~sar, com toda razo, que o atributo da diretiva page seria talvez, elIgnored. Mas no ' esse algum estaria errad; se chegasse a tal concluso. O DDe d' . _a ~r~tzva para ignorar a EL sao dIstzntos! No caia na

armadilha da <is-el-ignored>.

::

i&1;

usando o JSP

Mas espere ... existe UtM outro eletMettto JSP que ns ainda no vitMos:
At aqui, voc viu cinco diferentes tipos de elementos que podem aparecer em um JSP: scriptlets, diretivas, declaraes, expresses Java e expresses EL. Mas ns no vimos as aes. Elas vm em dois sabores: padres e... no-padres.

Ao-Padro:
<jsp:include page="wickedFooter.jsp"

Outra Ao:
<c:set var="rate" value="32"

/>

Embora possa parecer confuso, existem aes que no so consideradas aes-padro, mas que ainda fazem parte de uma biblioteca agora padronizada. Ou seja, voc aprender mais tarde que algumas aes no-padro (os objetivos referem-se a elas como customizadas) so ... padres, mas ainda no so consideradas "aes-padro". Sim, isso mesmo: elas so aes customizadas padronizadas no-padro. Agora no ficou mais claro? Num captulo mais adiante, quando chegarmos em "usando tags", usaremos um vocabulrio um pouco mais rico, em que trataremos deste assunto mais detalhadamente. Ento, relaxe. Agora, tudo o que nos interessa que voc reconhea uma ao quando se deparar com ela em um JSP!

Observe a sintaxe de uma ao e compare-a com a sintaxe de outros tipos de elementos JSP. E responda: 1) Quais so as diferenas entre o elemento de uma ao e um scriptlet?

2) Como voc reconheceria uma ao?

voc est

."

323

exerccio de avaliao

Matriz de Avaliao
O que acontece quando cada uma destas configuraes (ou a combinao delas) ocorre? Voc ver as respostas quando virar a pgina; portanto, faa AGORA.

E){etc1C19S ? o

Faa um X na coluna avaliado, se as combinaes levarem as expresses EL a serem avaliadas, OU faa um X na coluna ignorado, se a EL for tratada como outro texto template. Nenhuma linha ter as duas opes marcadas, claro.

o Avaliao da EL
Configurao no DD <el-ignored>
no-especificado

diretiva de pgina isELlgnored


verdadeira falsa no-especificado

avaliado

ignorado

Faa um X na coluna avaliado, se as configuraes levarem as expresses de scripting a serem avaliadas, OU faa um X na coluna erro, se o scripting gerar um erro de traduo.

Validade do scripting
avaliado

Configurao ignorado no DD
no-especificado verdadeira falsa

324

captulo 7

~ e>?~' ",,<PqT
1t

m de GeladeIra (Element9SJSY)
Correlacione o elemento JSP com o seu trecho de cdigo, associando o cdigo caixa que o representa. Lembre-se de que voc ter questes "arrastar e soltar" no exame, semelhante a este exerccio; ento, no o pule!

Tipo de elemento JSP


,

Trecho de cdigo JSP

lirefiva

/}"1"4Sie e sclie cttll"l"es/'(j"de"ie.

"a CIA/XIi.

<% Float one

= new Float

(42.5); %>

='

<%! int Y

3;

%>

<%@pagei mport=Njava.util.

"
<jsp:include i<%= pagecontext

.e

g tAt

tr~bute{"foON)%

email:
~'"

${ap

""

~
'

eXlresso

voc est aqui

li>

325

exerccio de avaliao

~
17~$"~

1m de G-ela.de'lta.(Element98JSf):

C9nt1nua.c;9

~.

yoc sabe o ~ome deles, ~as :,oc~ se lembra onde eles ficam no servlet gerado? . E claro que Sim. Mas este e so maiS um reforo antes de passarmos para um captulo e um assunto diferentes. (Considerando o arquivo da classe servlet, coloque o elemento no quadro onde o cdigo gerado por ele ficar. Note que o m, em si, no representa o cdigo REAL que ser gerado.)

public

final class

BasicCounter_jsp implements

extends org.apache.jasper.runtime.HttpJspBase org.apache.jasper.runtime.JspSourceDependent

public

void _jspService(HttpServletRequest throws

request, HttpServletResponse response) java.io.IOException, ServletException {

IJl'dehldes+es 1-l's ; ll'l'eleval1+e.


A-

:11\';5

request.getAttl~it'ute

email:

${applicationScope

<%! int Y = 3; %>

326

capjitulo 7

Matriz de Avaliao RESPOSTAS

EXetc1C19S ~o

Avaliao da EL

Configurao no DD <el-ignored>
no-especificado

diretiva de pgina isELlgnored


verdadeira falsa no-especificado '"

avaliado

ignorado

'"

f) Validade do scripting
Configurao ignorado no DD
no-especificado

avaliado '"

'"

voc est

res:{Josta'sdos elementos JSP

Im de GeladeI!a (Element9SJSY)
Respostas

Tipo de elemento

JSP

Trecho de cdigo JSP

A palavra "expresso" significa "expresso scripting", e NO "expresso EL".

claro que a palavra "expresso" muito usada pelos elementos lSP Se voc encontrar a palavra "expresso", ou "expresso scripting", elas querem dizer o mesmo: uma expresso que usa a sintaxe da linguagem lava: <%= foo.getNameO %> A nica vez que a palavra "expresso" se refere EL, quando voc especificar "EL" no label ou nas descries! Portanto, considere sempre que o padro para a palavra "expresso" "scripting/ expresso lava ", e no EL.

328

captulo 7

usando

o JSP

/) ~g'; \ m
~

de Geldeltq (Element9sJSY):

C9nt1nuqy9

RESPOSTAS

CCh>1Ih>a+ribll+ '''''1>61'+ Javo..

'Ity>cr+

public

final class

BasicCounter_jsp implements

extends org.apache.jasper.runtime.HttpJspBase org.apache.jasper.runtime.JspSourceDependent

<%! int
public

y =

/}s declara)';'!s 3; %>


X4..X4.8;e.f)5~ da classe taNJ.

void _jspService(HttpServletRequest throws

request, HttpServletResponse response) java.io.IOException, ServletException {

<%=request.getAttribute(fffoo

<% F10at one = new Float

(42.5); %>

Os scrip+le+s 'tc4h> del1+r<> da h>-I-4d4 sel"vtce.

emai1:

${app1icationscope.mai1}

/}s express';es h>+"d4 sel'vie.

ii- hclJ.h>deJOi+l'c dD

(!J4+",: 4 l'deh> des+es

+1"'&

i"rl'elevll.l1+e,:;

AJor/}:

Iflf<lbre-"se tle 3ve.,

c:tlijJ

JSP

l171J FICIJr)

tle Ia.+tl) iJ.$SIW! exen:Ci"6

4 sf!rvle+ If<IlJs+rO,f'

+41J +rav-;ifJ.1J
pa.f'ff

paf'a C c:tlijlJ

Jo.v#.. l.s+e

elf<l '/;V41

da

elas se jef'ada

eSffs

elelf<lel1+lJs
I

11711J es1-lJ.lf<ltJsIf<IfJs1-f'tJ.l1dtJ-It.f!.o e:JijtJ 1-f'e.tlv;ttl..,s. st""'P/fslf<le"ff

real 5*=1'0.6PQra

'/;val

PaI' eXf""'Pl) ti Jedaf'Qg71lJ 'tive ef'Q <.%II).;1-?

3; %> 1-cN1frSe

1i1f; 3;

voc est

.. 329

teste preparatrio

fausa pata 9 cat 7e4teP~-~7

1Dado o elemento DD:


47. <jsp-property-group> 48. 49. <url-pattern>*.jsp</url-pattern> <el-ignored>true</el-ignored> 50. </jsp-property-group>

o que o elemento

faz? (Escolha todas as que se aplicam.)

O A. Todos os arquivos

com o mapeamento da extenso especificada devem ser tratados pelo container JSP como arquivos que respeitam a sintaxe XML. com o mapeamento da extenso especificada devem ter seus cdigos EL avaliados pelo container JSP. C. Por padro, NENHUM arquivo com o mapeamento da extenso especificada deve ter seus cdigos Expression Language avaliados pelo container JSP. D. Nada. Esta tag NO reconhecida pelo container. E. Embora esta tag seja vlida, ela redundante, pois o container j faz isso por padro.

O B. Todos os arquivos
O O O

2 Quais das diretivas


DA. <%@
OB.<%@ OC.<%@ OD.<%@ CJE.<%@ page page page page page

abaixo representam uma resposta HTTP do tipo "image/svg"? (Escolha todas as que se aplicam.)
type="image/svg" %> %> %> %> %>

mimeType="image/svg" language="image/svg" contentType="image/svg" pageEncoding="image/svg"

330 captulo 7

.3

Seja o JSP:
1. 2. 3. 4. 5. 6. 7. 8. 9. <%@ page import="java.util.*" %> <html><body> The people who like <%= request.getParameter(~hobby") %> are: <br> <% ArrayList al = (ArrayList) request. <% Iterator it = al.iterator(); while (it.hasNext( <%= it.next() %> <br> { %>

getAttribute(~names"); %>

10. <% } %> 11. </body></html>

Que tipos de cdigos encontramos nele? (Escolha todas as que se aplicam.)

OA.EL

O B. diretiva
O C. expresso

O D. template
O E. scriptlet

text

4: Que declaraes sobre o


que se aplicam.)

jspInit () so verdadeiras? (Escolha todas as

O A. Ele tem acesso ao Serv1etConfig. O B. Ele tem acesso ao Serv1etContext O C. S chamado uma vez.

O D. Pode

ser anulado.

voc est

5 Que tipos de objetos esto disponveis


(Escolha todas as que se aplicam.) CJA.ServletConfig CJB.servletContext [JC.JspservletConfig [J D.JspServletContext [J E.HttpServletRequest [J F. HttpServletResponse

para o mtodo j splnit

() ?

Dado: <%@ page isELIgnored="true" %>

o que acontece?

(Escolha todas as que se aplicam.)

[J A. Nada. A diretiva page NO foi definida. CJ B. A diretiva anula a avaliao que o container JSP faz do cdigo da Expression Language em todos os JSPs da aplicao. CJ C. O JSP que possui esta diretiva ser tratado pelo container JSP como um arquivo que respeita a sintaxe XML. CJ D. O JSP que possui esta diretiva NO deveria possuir nenhum cdigo da Expression Language avaliado pelo container JSP. [J E. Esta diretiva apenas cancelar a avaliao da EL se o DD declarar um elemento <el-ignored>true</el-ignored> com um padro URL que inclui este JSP.

Qual declarao referente aos JSPs verdadeira? (Escolha uma.)

[J A. Apenas o jsplnit () pode ser anulado. CJ B. Apenas o jspDestroy() pode ser anulado. C. Apenas o _j spService () pode ser anulado. O D. O j splni t () e o j spDestroy () podem ser anulados. O E. O jsplni t (), o jspDestroy () e o _jspService () podem ser anulados.

332 captulo 7

usando o JSP

8 Qual das etapas do ciclo de vida do JSP est fora de ordem?


O A. Traduzir
O
O DE. O C.Call

o JSP em servlet. B. Compilar o cdigo-fonte do servlet.


jspService()

O D. Instar
Call F.Call

a classe servlet.
jsplnit() jspDestroy()

Quais das variveis implcitas JSP so vlidas? (Escolha todas as que se aplicam.)
DA. O O stream B. context

c. exception

O D. listener
OE.application

10

Seja uma solicitao com dois parmetros: um chamado "first", que representa o primeiro nome do usurio, e o outro chamado "Iast", que representa seu ltimo nome. Qual cdigo scriptlet JSP gera os valores para estes parmetros?
DA.
<%

out.println

(request. getParameter

("first"));

out.println(request.getParameter("last"); O

%> %>

B. <% out.println(application.getlnitParameter("first"); out.println(application.getlnitParameter("last");

c.<% println(request.getParameter("first";
println(request.getParameter("last");

%> %>

OD.<%

println(application.getlnitParameter("first");

println(application.getlnitParameter("last";

voc est

333

teste preparatrio

11 Dado:
11. 12. 13. 14. He110 ${user.name}! Your number is <c:out value="${user.phone}"/>. Your address is <jsp:getProperty name="user" property="addr" <% if (user.isValid( {%>Youare valid!<% } %>

/>

Quais declaraes so verdadeiras? (Escolha todas as que se aplicam.) O A. As linhas 11 e 12 (e nenhuma outra) contm exemplos de elementos

EL.
O O O O O B. A linha 14 um exemplo de cdigo scriptlet. C. Nenhuma das linhas deste exemplo contm um template text. D. As linhas 12 e 13 incluem exemplos de aes-padro JSP. E. A linha 11 demonstra o uso incorreto da EL. F. Todas as quatro linhas deste exemplo seriam vlidas em uma pgina JSP.

12

Qual tag JSP exibir o parmetro de inicializao de contexto chamado

"javax.sql.DataSource"?
OA.<%= OB.<%= O C.<%= OD.<%= application.getAttribute(~javax.sql.DataSource") %> application.getlnitParameter(~javax.sql.DataSource") %> request.getParameter(~javax.sql.DataSource") %> contextParam.get(~javax.sql.DataSource") %>

13

Quais declaraes sobre desabilitar elementos scripting so verdadeiras? (Escolha todas as que se aplicam.) O A. Voc no pode desabilitar scripting via DD. O B. Voc s pode desabilitar scripting no nvel da aplicao. O C. Voc pode desabilitar scripting programaticamente, utilizando o atributo de diretiva de pgina isScriptingEnabled. D. Voc pode desabilitar scripting via DD usando o elemento <scripting-invalid>.

334

cap,itulo 7

14 Em

seqncia, quais so os tipos Java para os seguintes objetos implcitos

JSP:app1ication,out,request,response,session?

o A.

java. 1ang .Throwab1e java.1ang.Object java.uti1.Map java.uti1.Set java. uti1. List

[JB. javax.serv1et.Serv1etConfig java.1ang.Throwab1e java.1ang.Object javax.serv1et.jsp.PageContext java.uti1.Map [J C. javax.serv1et.Serv1etContext javax.serv1et.jsp.JspWriter javax.serv1et.Serv1etRequest javax.serv1et.Serv1etResponse javax.serv1et.http.HttpSession [JD. javax.serv1et.Serv1etContext java.io.PrintWriter javax.serv1et.Serv1etConfig java.1ang.Exception javax. serv1et.RequestDispatcher

15 Qual
uma

das opes representa um classe em um JSP? <% page page page import import

exemplo

da sintaxe usada para importar

o A.
OB.<%@ OD.<%

import="java.uti1.Date" import="java.uti1.Date" import="java.uti1.Date" java.uti1.Date; %>

%> @%> %>

[J C.<%@

[JE.<%@

file="java.uti1.Date"

%>

16

Dado

o JSP: isELIgnored="true" %>

1. <%@ page 2. <%@ prefix="c" %> 3. <c:set

tag1ib

uri=~http://java.sun.com/jsp/jsy1/core'' va1ue="LIMOZEEN"/>

var="awesomeBand"

4. $ {awesomeBand}

Qual ser a sada?

o A.
O O O

${awesomeBand}

B. LIMOZEEN C. Nenhuma D. Uma sada

exceo ser enviada porque todas as diretivastaglibdevem

preceder qualquer diretivapage.

voc est

teste preparatrio - respostas

"fausa para

cat

1i!~-~7

1Dado o elemento DD:


47. <jsp-property-group> 48. 49. <url-pattern>*.jsp</url-pattern> <el-ignored>true</el-ignored> - lJr l>f'j';" C co.Plcela <) c:lcl./lc Jas eXfl'ess'4es fell> cClrf-o.tPlel' JSP 50. </jsp-property-group>

l...

2..tJ.

.R.I' fiJ.dl'';''J c cl1m-l-o.t#iU' calcl./ltI a f.L.

o que o elemento faz? (Escolha todas as que se aplicam.) O A. Todos os arquivos com o mapeamento da extenso

especificada devem ser tratados pelo container JSP como arquivos que respeitam a sintaxe XML.

O B. Todos os arquivos

com o mapeamento da extenso especificada devem ter seus cdigos EL avaliados pelo container JSP. liZ C. Por padro, NENHUM arquivo com o mapeamento da extenso especificada deve ter seus cdigos Expression Language avaliados pelo container JSP. D. Nada. Esta tag NO reconhecida pelo container. O E. Embora esta tag seja vlida, ela redundante, pois o container j faz isso por padro.

2 Quais
O

das diretivas abaixo representam uma resposta HTTP do tipo "image/svg"? (Escolha todas as que se aplicam.)
page type="image/svg" %> %> %> %> %> - lJr IJf'j';t; /) 4pl'esePl-l-o. ffJ.NI. es=l-a di'l'e-l-tVo..
tJ.

DA. <%@
IiZc.<%@ OD.<%@ O E.<%@

B. <%@ page page page page

mimeType="image/svg" language="image/svg" contentType="image/svg" pageEncoding="image/svg"

s,-.,-I-axe

336

CB{)tLii'O

usando

o JSP

3 Seja o JSP:
1. 2. 3. 4. 5. 6. 7. 8. 9. <%@ page import="java.util.*" %> <html><body> The people who Iike <%= request.getParameter(~hobby") %> are: <br> <% ArrayList aI = (ArrayList) request. <% Iterator it = al.iterator(}; whiIe (it.hasNext()} { %> <%= it.next(} %> <br>

getAttribute(~names"}; %>

10. <% } %> 11. </body></html>

Que tipos de cdigos encontramos nele? (Escolha todas as que se aplicam.)

DA.EL
li2' B. diretiva li2' C. expresso li2' D. template text li2' E. scriptlet

- lJ'; exis.f.e L
expl'fIss;es
114

'1es.f.e J-SP'
fI

Ii...,hll

2) eJ '''5IcJ e!ee..,.f-cs scrip-h""j.

l1a~ !,...,has

3 BJ

t t>s (1"'11

d"1"eh-vo. #'/0.

",1./1

.f.e""f'II1.f.e.f.ed

P"'I' .f-"d,,'ad

4 Que declaraes
que se aplicam.) li2' A. li2' B. li2' C. li2' D.

sobre o jspInit () so verdadeiras? (Escolha todas as

Ele tem acesso ao ServletConfig. Ele tem acesso ao ServletContext S chamado uma vez. Pode ser anulado.

voc est

337

teste preparatrio - respostas

5 Que tipos de objetos esto disponveis


(Escolha todas as que se aplicam.) ~ A. ServletConfig ~ B. ServletContext CJ C.JspservletConfig CJD.JspservletContext CJE.HttpservletRequest CJ F.HttpServletResponse

para o mtodo j spIni t () ?

- Os JSPs

v/,'all1 stl'vle-l-s

siJ'lf>les e ,til'

lSSti h""'"

acess<Ii

ati; l6e-l-os siJ'lf>les Sel'v1e-I-Coill; e Sel'vle+C<liilh",-I e e Yh<t POtlC<li cedo "10 delo de vtlia p41'a !a141'1I10S s<libl't stillci-l-ases e I"es,os-l-as

6 Dado:
<%@page isELIgnored="true" %>

da Expression Language em todos os JSPs da aplicao. CJ C. O JSP que possui esta diretiva ser tratado pelo container JSP como um arquivo que respeita a sintaxe XML. ~ D. O JSP que possui esta diretiva NO deveria possuir nenhum cdigo da Expression Language avaliado pelo container JSP. E. Esta diretiva apenas cancelar a avaliao da EL se o DD declarar um elemento <el- ignored>true</ el- ignored> com um padro URL que inclui este JSP.

o que acontece? (Escolha todas as que se aplicam.) O A. Nada. A diretiva page NO foi definida. O B. A diretiva anula a avaliao que o container JSP faz do cdigo

16l '''c/llido.

;; es-A} l",col"l"e-l-lI<; p<Jl''Ipe

li till'e-h"II11<;;.Ie-l-" "pe"J"s

Qual declarao referente aos JSPs verdadeira? (Escolha uma.) o j spIni t () pode ser anulado. O B. Apenas o jspDestroy() pode ser anulado. - Le...,bl'e-se O C. Apenas o _jspService () pode ser anulado. I e tl lilctl. tie 'fpe ~ D. O jspInit() e o jspDestroy() podem ser anulados. seI' fl.J1yltlti. E. O j spIni t () , o j spDestroy () e o _j spService () podem ser anulados.

O A. Apenas

tie t/lI1

338

ca(.)itw'o

usando

o JSP

8 Qual das etapas


D D. Instar
Iitr C.

do ciclo de vida do JSP est fora de ordem?

D A. Traduzir o JSP em servlet. D B. Compilar o cdigo-fonte do servlet.


Call _jspService ()

a classe servlet.
jsplnit() jspDestroy()

DE.

-()

Call

F.Call

Quais das variveis implcitas JSP so vlidas? (Escolha todas as que se aplicam.)

DA.
Iitr

stream e P "'';., exls-!--e"" ce""" - /}s efS4es,/} et.ie+<ls 'Ry-lictJ.<lS Cl",Q.,/"s pele ce",+al",el" pal"a 6S J-sPs.

D B. context
c. exception
application

O D. listener
Iitr E.

10

Seja uma solicitao com dois parmetros: um chamado "first", que representa o primeiro nome do usurio, e o outro chamado "last", que representa seu ltimo nome. Qual cdigo scriptlet JSP gera os valores para estes parmetros? Iitr A.
<%

out.println

(request. getParameter

("first"));

D B. D

out.println(request.getParameter("last";

%> %>

<% out.println(application.getlnitParameter("first";

out.println(application.getlnitParameter("last";

C.<% println(request.getParameter("first"; %> %>

println(request.getParameter("last";

DD.<%

println(application.getlnitParameter("first";

println(application.getlnitParameter("last";

voc est

339

teste preparatrio - respostas

11 Dado:
11. Helio 12. Your 13. Your 14. <% if ${user.name}! number address is <c:out value=H${user.phone}HI>. name=HuserH are valid!<% property=HaddrH } %>

is <jsp:getProperty {%>You

I>

(user.isValid(

Quais declaraes so verdadeiras? (Escolha todas as que se aplicam.)


IilA.

As linhas 11 e 12 (e nenhuma outra) contm exemplos de elementos EL. IilB. A linha 14 um exemplo de cdigo scriptlet. C. Nenhuma das linhas deste exemplo contm um template text. O D. As linhas 12 e 13 incluem exemplos de aes-padro JSP. E. A linha 11 demonstra o uso incorreto da EL. Iil F. Todas as quatro linhas deste exemplo seriam vlidas em uma pgina JSP.

- ft pj4 C e5-/-; t"lc,u'l"e-/-a;IUJI"'1/le -/-do.5 45 '1pa-/-l"11"t.uflJsslle/WIkIYlf'14k - ft IJPf4 P e5-/-: tIlCIJt'l"ff~ pl"flle a li7t.a 12 1l41Jli7cllllll/WIa4f4rrpaJI"41J JsP, - ft IJPf4 ~ es+: Ii7CIJI"N':+4; plJl"'Il'e 4 f.L i?4 ili7t.4 V:II(J4. 12
Qual tag JSP exibir o parmetro de inicializao de contexto chamado "javax.sql.DataSource"?
O

kx-/-.

<.JsPv 2.0;
("javax. sql.DataSourceH) %> %>

p~.

A.

<%=

application.getAttribute

IilB.<%= OC.<%= O

application.getlnitParameter("javax.sql.DataSourceH) request.getParameter("javax.sql.DataSourceH) contextParam.get("javax.sql.DataSourceH) %> %>

D. <%=

IJft/.g /WIs-/-t'O, 6ls ClJl"I"ff d tJe+ I'''''pll(:l1- appllca+li?


-

ft

13

Quais declaraes sobre desabilitar elementos scripting so verdadeiras? (Escolha todas as que se aplicam.)
<.JSPv2.0; se{itJ

O A. Voc no pode desabilitar scripting via DD. O B. Voc s pode desabilitar scripting no nvel da aplicao.
desabilitar scripting programaticamente, utilizando o atributo de diretiva de pgina isScriptingEnabled. Iil D. Voc pode desabilitar scripting via DD usando o elemento
<scripting-invalid>.

3.3.3)

O C. Voc pode

- ~c s: p"e desdllt+o.l"

ele/WIel'/+tJs SCl"ip-hi75

<JsP-pl"pel"-/-yrllf> pel PP. () ele/WIel7+ psslbNt+a 311e.tesablltk/WIs 5CI"I.,:';:'''5 e. 4'51117S Jsps; deltl7,i7,,(tlpaeil";es eie fJ/(Ls pal"IJ.S!N!/WI ,,(esa!;tlt+a,,(as.

340

captuo 7

usando oJSP

14

Em

seqncia, quais so os tipos Java para os seguintes objetos implcitos

JSP:application,out,request,response,session?

o
O

A. java. lang. Throwable java.lang.Object java.util.Map java. util. Set java.util.List B. javax.servlet.ServletConfig java. lang. Throwable java.lang.Object javax.servlet.jsp.PageContext java.util.Map javax.servlet.ServletContext javax.servlet.jsp.JspWriter javax.servlet.ServletRequest javax.servlet.ServletResponse javax.servlet.http.HttpSession D. javax.servlet.ServletContext java.io.PrintWriter javax.servlet.ServletConfig java.lang.Exception javax. servlet.RequestDispatcher "'1J$+~a I) +SiM - IJ: 6pf';a de cada IJtje+1J ,....,.lIet+lJ.

~c.

15

Qual das opes representa um uma classe em um page page page import import JSP?

exemplo

da sintaxe usada para importar

(JsPv2.0jp~, l-t/t/)
%> @%> %> - fJr$ IJpfaes lJr e b $';IJ lnv'lit1asj ape'ltl.S as declIJ.1"4jaes Jav(J, pade'" (J,S+f4js <% . %:>.
11. "'e; f! I) lIPirCI)f!Xf!"'P'1) , "pj44 sli,+tlJ<:e cl)l"l'e+a.

DA. <%
OB.<%@ ~c.<%@ CJD.<% O E.<%@

import="java.util.Date" import="java.util.Date" import="java.util.Date" java.util.Date; %>

P<31'3l1e vrl" el1+l'f! "

- rr

file="java.util.Date"

%>

-fJr

f.

16

Dado

o JSP: isELIgnored="true" %>

1. <%@ page 2. <%@

taglib

uri=~http://java.sun.com/jsp/jsyl/core'' value="LIMOZEEN"/>

pre:fix="c" %> 3. <c:set var="awesomeBand" 4.

${awesomeBand}
- 0pf';a IJ:: (J, expl"f!SS';1) f.L. 'nl)f'lldlJ. p4S$all -h:X+V41"'f!n-h:. e

Qual ser a sada?

~ A.
O O O

$ {awesomeBand}

B. LIMOZEEN

C.

Nenhuma

sada

D. Uma

exceo ser enviada porque todas as diretivastaglibdevem

preceder qualquer diretivapage.

voc est

341

8 JSf sem scdpts

Pginas sem scripts

Fuja do scripting. Ser que seus webdesigners precisam mesmo saber Java? Isso justo? Ser que eles pensam que quem programa em Java para servidores tornar-se-, digamos, designer grfico? E mesmo que a equipe seja s voc, voc quer mesmo um monte de bits e pedaos de cdigos Java nos seus JSPs? Voc sabe o que significa "um pesadelo na hora da manuteno"? Escrever pginas sem scripts no s possvel, como mais fcil e mais flexvel com a nova especificao JSP 2.0, graas nova Expression Language (EL). Padronizada depois do JavaScript e do XPATH, os webdesigners sentir-se-o em casa com a EL. E voc tambm vai gostar (assim que voc se acostumar). Porm, existem algumas armadilhas ... a EL se parece com o Java, mas no . s vezes, a EL se comporta de forma diferente de como comportar-se-ia a mesma sintaxe no Java. Portanto, fique atento!

este um novo

343

objetivos do exame oficial da Sun

Construir pginas JSP usando a Expression Language (EL) e as Aes-padro


7.1 Escrever um cdigo snippet usando variveis de alto nvel na EL. Isto inclui as seguintes variveis implcitas: pageScope, requestScope, sessionScope e applicationScope; param e param Values; header e headerValues; cookies e initParam. 7.2 Escrever um cdigo snippet usando os seguintes operadores EL: property access (o operador".") e collection access (o operador "O"). 7.3 Escrever um cdigo snippet usando os seguintes operadores EL: operadores aritmticos, operadores relacionais e operadores lgicos. 7.4 Para funes EL: escrever um cdigo snippet usando uma funo EL; identificar ou criar a estrutura de arquivos TDL usada para declarar uma funo EL; e identificar ou criar um cdigo exemplo para definir uma funo EL. 8.1 Dado um objetivo de projeto, criar um cdigo snippet usando as seguintes aes-padro: jsp:useBean (com os atributos "id", "scope", "type" e "class"), jsp:getProperty e jsp:setProperty (com todos os atributos combinados).

Notas sobre a Abrangncia:

Todos os objetivos sobre este assunto so abordados completamente neste captulo. E ele bem grande! V devagar neste captulo, pois temos muitos detalhes minuciosos a encarar.

8.2 Dado um objetivo de projeto, criar um cdigo snippet usando as seguintes aespadro: jsp:include, jsp:forward e jsp:param. 6.7 Dado um objetivo de projeto especfico para a incluso de um segmento JSP em outra pgina, escrever um cdigo JSP que use o mecanismo de incluso mais apropriado (a diretiva include ou a ao-padro <jsp:include.

Neste captulo, vamos falar de AMBOS os mecanismos de include: o <jsp:include>, citado no objetivo 8.2, e a diretiva de pgina include, mencionada no objetivo 6.7 (a maioria dos objetivos da seo 6foi abordada no captulo anterior sobre JSPs).

344

JSP sem scripts

Nossa aplicao MVC depettde dos atributos


Lembra na aplicao MVC original da cerveja, o Servlet controlador interagia com o modelo (classe Java com a lgica do negcio) e criava um atributo no escopo da solicitao antes de envi-Ia view JSP. O JSP tinha que receber o atributo do escopo da solicitao e us-Io para gerar a resposta que seria enviada de volta ao cliente. Eis uma olhada rpida e simplificada de como o atributo vai do controlador para a view (imagine que o servlet se comunique com o modelo): Cdigo do servlet (controlador)
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException ("userName") _ usa o f{).,,:!i,:e+ro Je :>o/l'<::l+(u;';e de fef'h<llb.l'i Pb.I't1.Cl'iiu' a.+l"v+o 31f! d~ esc"1M da S(;;ltCl';"o.g';o tJ tJSP uSQ.":,

request. setAttribute

String

name

= request. getParameter

("name", name);

<}

RequestDispatcher

view

request.getRequestDispatcher("/result.jsp"); response); ~
t~,:o.*\I~j~Q.a fttu"t<

view. forward (request,

a vlew.

Cdigo JSP (view)


<html><body> Hello <%= request.getAttribute("name") </body></html> %> (t...el>lbl'e-se: as express6es Je sCl'tp+I~5 Use "'*,4 eXft'ess'; o.+t'lbll+/'J e exlbr-Io. Je sct'i'p+'~5 J'lo.resfos+o.. po.t'f!. 6b+ef' <l

SWIt'i

o o.f'5f.1h<fl'l+ ptU'o. " h<H-eJ"

Heno Paul

'\
ef'a

f.I

c VIJ,/{)f' IIl"

n
J'lfJ.h<e

o.+r"bl.ll-"

voc est aqui

iI>

345

atributos non-Strng

Mas, e se o atributo t'lo for ut\ta Strit'lg, e sit\t ut\ta it'lstt'lcia de Persot'l?
E no s uma Person, mas uma Person com uma propriedade "name". Estamos usando o termo "propriedade" na forma do JavaBean* no-enterprise - a classe Person tem o par de mtodos getNameO e setNameO, que de acordo com a especmcao do JavaBean quer dizer que Person tem uma propriedade chamada "name". No se esquea de que a propriedade "name" requer que a primeira letra, "n", seja alterada. Em outras palavras, o nome da propriedade o que voc obtm ao retirar o prefixo "get" ou "set" e transforma em minscula a primeira letra subseqente. Portanto, getName/setName vira simplesmente name.

foo.Person publico String public void setName(String)

o cdigo
public

servlet
void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException

foo.Person p = new foo.Person(); p.setName(~Evan"); request.setAttribute(~person", p); RequestDispatcher view = request.getRequestDispatcher("result.jsp"); view.forward(request, response);

o cdigo

JSP

<htrnl><body> Person is: <%= request.getAttribute(~person") </body></htrnl>

%>

o que

QUEREMOS:

O que CONSEGUIMOS:
Person is: foo. Person@512d66
01.. (;bvtQIllf!"Jff

Person is: Evan

Q eXpl'eSS4lJ

/ ... d,QlIIlJ/I lJ IIIf'T'(;d(;7,aJI'Q(;

,~

+".5-htl'ljQ

d{J 4+1'1"11/1+(;

*Falaremos sobre JavaBeans daqui a pouco, mas por enquanto, tenha em mente que ele s uma classe Java simples, cujos getters e setters obedecem a uma conveno de nomes.

346

JSP sem scripts

PrecisatMos de tMaiscdigo para obter o "atMe de Perso"


Enviar o resultado do getAttributeO para a declarao de exibir/escrever no nos d o que queremos - isto s roda o mtodo toStringO do objeto. E j que a classe Person no anula o ObjecttoStringO que foi herdado, bem, voc sabe o que acontece. Mas ns queremos exibir o name de Person.

o cdigo

JSP

<htrnl><body>

<% foo.Person p = (foo.Person) Person is: <%= p.getName() %>


</body></htrnl> ~ "'-.....

request.getAttribute(~personff);

%>

c 'xi"!;e

<l

t"es;;!-rad<l J

de je+AJo.!t'leO.

OU usando uma expresso


<htrnl><body> Person is: request.getAttribute(~personff .getName()

<%= foo.Person)
</body></htrnl>

%>

o que

RECEBEMOS:

Person is: Evan

Mas a recordamos aquele LEMBRETE ... Aquele que pode ser resumido em "Use Scripts e Morra" Precisamos de outra tcnica.

voc est

347

JavaBean aes padro

Penot1

UtMJavaJeat1,
de beat1

logo, usaretMos

aes-padro

Com duas aes-padro podemos elinllnar todo o script do nosso JSP (lembre-se: o scripting inclui declaraes, scriptlets e expresses) e ainda exibir o valor da propriedade name do atributo person. No se esquea de que name no um atributo - apenas o objeto person um atributo. A propriedade name apenas aquilo que retomado do mtodo getNameO de Person.

Sem aes-padro
<html><body>

(usando scripting)

t aS stw, fllle
//)."/''lil.o

s1-;;'w,os
f-

<% foo.Person p = (foo.Person) Person is: <%= p.getName() %> </body></html>

request.getAttribute(~person");

%>

Com aes-padro
<html><body> <jsp:useBean Person

(sem scripting)

id="person"

class="foo.Person" <jsp:getProperty

scope="request" name="person"

/> property="name" />

created

by

servlet:

</body></html>

348 captulo 8

JSP sem scripts

At1alisat1do a <jsp:use&eat1> e a <jsp:getProperty>


Tudo o que realmente queramos era a funcionalidade do <jsp:getProperty>, pois queramos apenas mostrar o valor da propriedade "name" de person. Mas como o Container saber o que quer dizer "person"? Se tivssemos no JSP apenas a tag <jsp:getProperty>, seria praticamente como se usssemos uma varivel no declarada chamada "person". O Container geralmente no faz idia do que voc est falando, a menos que voc inclua na pgina PRIMEIRO uma <jsp:useBean>. A <jsp:useBean> uma maneira de declarar e inicializar o objeto bean real que voc est usando em <jsp:getProperty>.

Declarando e inicializando um atributo bean com <jsp:useBean>


scope="request"/>

Obtendo o valor da propriedade

de um atributo bean com <jsp:getProperty>

<jsp:getProperty

name="person"

property="name"

/>

~
Itiel1+f-lica IGleJ1h"ftco. " vali;;" tie

T
(w S~1t.J
seffll" 'l"ic ~"
'ltllll'le=
1J.31.1tl

ti ~e-I-6 bellJ1
Ctlll'l

11"lI'IetJa f'l'fl'letJe.Gle

relll, IS+";ftliJJCftiil':

&l.IefS SlIr ti 5eml' e "lI! classe !;ee."l).

tilJl +1JlJ

//

Alc+o.: eS+4 pl"pl'fetJt!tJe J1fttlt: ~yel' fersa"! 1Jip;.cfl"ietiIJ.tie

11t:ll'le

9Sf:I.IS(~5ea,,>.

CCIl'lc fetilJ,jfJ

tJes+tlI +1JlJ. ct.all'la- se 'lll"Xe

Si'''''Plesil'le''rf-e eal' CIJ,I./Sll llJ,-Il'lI'IiI. 11 dllss/?: fJ/?:I"Sll'/ Itli ttleli'I'/i'tltl.. CC"X"

voc est

to-

349

<jsp:useBean>

A <jsp:useJea.,>

tatMbtM pode CRIAR UtMbea.,!

Se <jsp:useBean> no puder encontrar um objeto atributo chamado "person", ele pode construir um! parecido com a forma com que request.getSessionO (ou getSession(true)) funciona: ele primeiro procura por algo existente, mas caso no o encontre, ele cria um. Observe o cdigo do servlet gerado e voc ver o que est acontecendo - tem um teste ifl! Ele procura por um bean baseando-se nos valores de id e escopo na tag, e se no encontrar um, ele cria uma instncia da classe especificada em class, atribui o objeto varivel id e a configura como um atributo no escopo que voc definiu na tag.

Esta tag
<jsp:useBean id="person" scope="request" /> class="foo.Person"

Transforma-se neste cdigo no mtodo -JspService()


!JedlJ.t'tJ. (/#\a VlJf'i~';I'el baSfltJ.i'1,;/-se '1 vu.lifJl' foo.Person person

de M,

null; ~
{

i es+tJ. V4t'I{.vel
d
N:flt'4#\ 4 eM.

3ve pet'lO\l-+e 3ve (w+NJ.$ +~s

sev JSP<.tp/clvslve

de

synchronized

(request)

person = (foo.Person) REQUEST _ SCOPE) ;

jspx_page

context.getAttribute(nperson",
AI

.
J

111+a e/;+et'

<)

1J.+t'l!Jv+tJ P/li escilpiJ

\ r v ,;/ef,),lllM. '11< il<)c 1I1J.1'1(;.vel

+~e o.+t'"J,l/l

PageContext.

JlA./tS; se AJ/ttJ I.,wllet' 11#\


if (person

null) { ~

i1<)lO\e I1tJ esclJp<)",

_jspx~age_context.setAttribute(nperson",

person,

PageContext.REQUEST_SCOPE);

:,),lJ.lhle~; lJ.+d!;v-rtJ

c<)p/fljf.lt'e

IJ

11<)';1'<) lIfJe-I-fJ ctJlO\fJ1110\


'"

'1 esc"pfJ ave vlIce tlefi'J'llll.

350 capitulo 8

JSP sem scripfs

Isto pode ser uma coisa ruim - eu no QUERO ter um bean que no tenha seus valores de propriedade configurados! Se o Container cria um bean usando essa tag, o bean no ter valores de propriedade ...

Voc pode usar a <jsp:setProperty>


Mas voc j sabia que onde existe um get geralmente existe um set. A tag <jsp:setProperty> a terceira e ltima ao-padro bean. simples de us-Ia:
<jsp:useBean id="person" class="foo.Person" scope="request" <jsp:setProperty name="person" property="name" value="Fred" />

/>

voc est aqui...

351

<jsp:useBean>

com um

CO!PO

<jsp:useJeat1> pode ter Ui\tcorpo!

Se voc puser seu cdigo set (<jsp:setProperty dentro do corpo de <jsp:useBean>, a configurao da propriedade torna-se condicional! Ou seja, os valores da propriedade sero configurados apenas se um novo bean for criado. Se for encontrado um bean j existente com aquele escopo e id, o corpo da tag nunca ser executado, e assim, a propriedade no ser sobrescrita pelo seu JSP.

Com o corpo de uma <jsP:UseBean>, voc pode ter um Cdigo que Condicional. rode de forma

SOMENTE se o atributo bean no for localizado e um novo bean for criado.

Sei?< a

bfJ./f'I'fJ.! ~

<jsp:useBean

id="person"

class="foo.Person"

scope="page"

>

</jsp:useBean

>
t{VI.l!tJvel'
fJ.

~"rali?<e'1hJ 3i1e' exts+tl'

lecl.a.i?<.rJs 1;;,/" <l eJ'l+l'e der1"vf'a. e Q


I.l

+:'

':'/'5"I,/el1+l'a

<jsp:vse8efJ.'1:>

,/a C(Jl'f" '/e I e Co!JJ)ICI!)!JIrI.-. i/e 5!)


btaJ1 ..,";cfcl' e"'CM+ra.,/c

exeCII+a.,/ se c
e VIVi 'fav., fl:>l'

le,I.fJ.lVien+" '/a +",

a ca/f'p".

'1'1"4'/1:>.

r:

Por que eles no deixam que voc simplesmente especifique argumentos no construtor do bean? Por que afinal voc tem que se preocupar com a configurao de valores extras?

1) Voc TEM que ter um construtor-padro pblico. 2) Voc TEM que nomear os seus mtodos pblicos get e set iniciando com "get" (ou "is", se for booleano) e "set", seguidos pela mesma palavra (getFooO, setFoo()). O nome da propriedade ser obtido retirando-se o "get" e o "set" e trocando para minscula a primeira letra do que restar. 3) O tipo do argumento set e o tipo de retorno do get TM que ser idnticos. isto que define o tipo da propriedade.

A resposta simples: beans no podem TER construtores com argumentos! Bem, como uma classe Java, eles podem, mas quando um objeto tratado como bean, a Lei Bean diz que SOMENTE o construtor-padro pblico do bean ser invocado. Ponto final. Alis, se voc NO tiver um construtor-padro pblico na sua classe bean, tudo isso vai falhar mesmo.

1\:

int getFooO

void setFoo(int

foo)

1\: Que negcio esse de Lei Bean?

r:

a lei que segue a especificaocreakingly-ancient dos JavaBeans. Estamosfalando de JavaBeans,e NO de Enterprise JavaBeans (EJB), que no tem nada a ver (v at a figura).A especificaosimples para JavaBeans no-enterprisedefine o que uma classe precisa para ser um JavaBean. Emboraa especificaoseja, de fato, um tanto complexa,as nicas coisas que voc precisa saber para usar beans com JSP e servletsso estas poucas regras (mostramosapenas aquelas que se aplicam ao que estamos estudandocom servletse JSPs):

4) O nome e o tipo da propriedade derivam do get e set, e NO de um membro na classe. Por exemplo, s porque voc tem uma varivel privada int foo NO significa nada em termos de propriedades. Voc pode dar s suas variveis o nome que bem entender. O nome da propriedade "foo" vem dos mtodos. Em outras palavras, voc tem uma propriedade simplesmente porque voc tem o get e o set. Como voc os implementar fica sob sua responsabilidade. 5) Para uso com JSPs, o tipo da propriedade DEVE ser ou uma String, ou uma primitiva. Caso contrrio, ele ainda poder ser um bean, mas voc no poder confiar apenas nas aespadro e ter que usar scripts.

352 capfuio 8

JSP sem scripts

o servlet

gerado quat1do <jsp:useJeat1> tet\1 Ut\1corpo

simples. O Container coloca o cdigo extra para configurao da propriedade dentro do teste if.

o cdigo

no -ispServiceO

COM o corpo <jsp:useBean>


Pr6cllI'a f~'" illt'la+rlbv+ extsh:Plh: c" " PI"lt'le li! esc"f"
do.

person ~ SCOPE) ; if

(foo.Person)

jspx_page

context.getAttribute(nperson",

"
'"
0.<>

+~.
tJe+ btJ!l"

PageContext.PAGE
'1<>\16

(person person

== null) I

<:

5e "';6 II!Xis-h,.

I}It'lo.l'l"4
"I!Plt.(I"";

<>

crte "' 0. "6i/0. i""S+~ct4.


person,

esc(Jf espedflcad6.
;

= new foo.person();~
context.setAttribute(nperson",

jspx_page

PageContext.PAGE_SCOPE)

voc est

353

referncias polmrfcas

Voc sabe fazer refermcias

politMrficas para beatls?

Quando voc escreve um <jsp:useBean>, o atributo da classe determina a classe do novo objeto (se algum foi criado). Ele tambm determina o tipo da varivel de referncia usada no servlet gerado.

A maneira ATUAL no JSP

<jsp:useBean scope="page"
Servlet gerado

id="person"

class=
() a+ri"!J(J+lI tia elas se "
,~"-

/>

'7tJ.+as reprli!sli!'7+tJ.
Ao.

tJ.

", relere'7'''a f. li -hPfJ tio person

= null;

\{ie+fJ
o atributo de perso~

Ii
if

cdigo

para

recuperar

(person == null) { = new

~--~~ ?

person

Mas ... e se quisermos que o tipo de referncia seja diferente do verdadeiro tipo do objeto? Ns alteraramos a classe Person para tom-Ia abstrata e criaramos uma subclasse concreta Employee. Imagine que queremos que o tipo de referncia seja Person e o novo tipo do objeto seja Employee.

package

foo;

public ab . S ract cl PrlVate St. ass Person rlng name;

I
I

public Void this.name_SetNamerString -name;

public Strin return g getName r) name; . class EmP~oyee publlc . t eTC\plD, private ln

exten d 5 person

ID\int .d setEmp lic vOl pub ID=empID; this.emp

empID)

. etempID \) blic lnt 9 pu return emplD;

354

JSP sem scripts

Adieiot1at1do UlIt atributo ~

a <jsp:useJeat1>
cksseabs+ra+a ~

Com as alteraes que acabamos de fazer na classe Person, estaremos em apuros se o atributo no for localizado: Nosso JSP original

class Person String getNameO void setName(String)

<jsp:useBean

id="person"

class="foo.Person"

scope="page"l>

Tem este resultado


java.lang.lnstantiationError: foo.Person

class Person String getNameO void setName(String)

PerstlP? D.JtlN. ~ ds+ro.h.l

Porque o Container tenta:

f)!;vio.",e#l.f-e)

voc "1" po;;{e el'rar


Ctl,rlY<l1el' o.l1;;{o.

V"'~ ",as

<)

new foo. Person ();+e17:j.~ !;aseo."';;{(l- se 1M 0.+1'1'/11.1+6 ;;(a elas se l7a +tJ.j.

Precisamos transformar o tipo de varivel de referncia em Person, e o objeto, uma instncia da classe Employee. Faremos isso adicionando um atributo type tag. Nosso novo JSP com um type
<jsp:useBean id~"person" type~"foo.Person"

class~"foo.Employee"

scope~"page">

~ null;

) //
o atributo de person

Ii
if

cdigo para recuperar (person == null) { ~ new

----~>-

person

;~---

o type pode ser um tipo de classe, um tipo abstrato ou uma interface qualquer coisa que voc possa usar como um tipo de referncia declarada para o tipo de classe do objeto bean. Voc no pode violar as regras de tipos do Java, claro. Se o tipo da classe no puder ser atribudo ao tipo de referncia, voc est "ferrado". Isso significa que a class deve ser implementao concreta do type.

voc est

li'

355

tipos sem a class

Usai1do

type setlt a class

o que acontece se declaramos um type, mas no uma class? Faz diferena se o tipo abstrato ou concreto?

JSP
<jsp:useBean id="person"

'"

/seht

cllJ.ss) 4pel1lJ.s~7fe
scope~"page"/>

type="foo.Person"

Resultado, caso o atributo person j exista no escopo da "page" Funciona perfeitamente.

Resultado, caso o atributo person NO exista no escopo da "page"


Java. lang. InstantiationException: bean person no encontrado no escopo

'"

AlAo FUAlCZOAlA!!

f:

No seu exemplo, "foo.Person" um tipo abstrato, por isso, BVIO que ele no pode ser instanciado. E se voc alterar o type para "foo.Employee"? Ele vai usar o type para a referncia E o tipo do objeto?

No existe uma regra para preveno que diga: "se voc no encontrar o objeto, use o type para a referncia E para o objeto." No, NO assim que funciona. Observao importante: se for usar o type sem a class, melhor ter CERTEZA de que o bean j esteja armazenado como um atributo - no escopo - e com a id que voc especificou na tag.

1\:

NO! No vai funcionar. Se o Container descobre que o bean no existe e v s um atributo tipo sem uma classe, ele sabe que voc ofereceu a ele apenas METADE do que ele precisa - o tipo de referncia, mas no o tipo do objeto. Ou seja, voc no disse a ele o propsito de criar uma nova instncia!

356 captulo 8

padro para "pageN o na . <jsp:getProperty> , o Cont'amer usa p o padro tag <jsp:useBean> da "page". ' nem na

o a~b~o

s~voce nao especificar um esco

escopo apoma

COtltO

Isto
<jsp:useBean id="person" class="foo.Employee" scope="page"j>

o mesmo que isto


<jsp:useBean id=Hperson" class="foo.Employee"j>

No confunda ~

com class!

Observe este cdigo:


<jsp:useBean id="person" type="foo.Employee" class="foo.person"/>

Prepare-se para reconhecer que ele NUNCAfuncionar!

Voc vai receber um belo:


class for JSP

org.apache.jaSper.JasperException: Unable to compile foo.Person is abstract; cannot be instantiated Person = new foo.Person();

Esteja CERTO de lembrar que:

type = = tipo de referncia class = = tipo do objeto

Ou, explicando de outra forma: type O que voc

DE(LARA (pode ser abstrato) class o que voc INSTANCIA (tem que ser concreto) type x = nova classO

Agora, voc deve estar pensando: "Bem, class sempre classe, mas type no tem que ser _ type pode ser uma interface. Portanto, CLARO que eles usaram 'class' para representar aquilo que SEMPRE tem que ser classe e 'type' para aquilo que pode ser interfaces tambm." E voc estaria certo. Mas voc tambm est pensando, "claro, nem TUDO na especijicap tem o nome mais intuitivo e bvio possvel; portanto, melhor eu ficar esperto". As vezes (como em security <auth-constraint, o nome de uma coisa o oposto do que ela realmente . Porm, neste caso, class classe e type ... tipo.

voc est

exerccos sobre

para Bean

Observe esta ao-padro:


<jsp:useBean value="Fred" </jsp:useBean Name id="person" type="foo.Employee" >

<jsp:setProperty

name-"person"

property="name"

/>
> name="person" property="name"

is: <jsp:getProperty

I>

Person String getNameO oid setName(String)

Agora, imagine que um servlet atue e encaminhe a solicitao ao JSP que possui o cdigo acima. Tente descobrir o que este JSP faria para cada um dos dois exemplos de cdigo servlet. (Respostas no final deste captulo.)

O que acontece se o cdigo do servlet se parecer com:


foo.Person p = new foo.Employee();

p.setName(~Evan"); request.setAttribute(~person", p);

e
A-i>l!;U 116paC6ff

O que acontece se o cdigo do servlet se parecer com:


foo.Person p = new foo.Person();

as classes es.f.';6 n H
f6 ,.)

p.setName(~Evan"); request.setAttribute(~person", p);

358

captuo B

Acabei de pensar numa coisa... suponha que no estejamos usando um servlet controlador e o formulrio HTML v direto ao JSP... existe uma forma em que eu possa usar os parmetros da solicitao para configurar uma propriedade bean, SEM usar script?

b,do direto da solicitao ao JSP setMpassar por UtM servlet ...


Imagine que este seja o nosso formulrio:

<html><body>

It sllcl-l-tl.{ val !JI/tiro


~ tl.JsP.

<form action=~TestBean.jsp">
name: <input type=~text" name~~userName"> ID#: <input type~~text" name=~userID"> <input type="submit"> </form> </body></html>

Sabemos que podemos fazer isso, combinando aes-padro com scripting:


<jsp:useBean id=~person" type=~foo.Person" class=~foo.Employee"/>

<% person.setName(request.getParameter(~userName";

%>

Podemos at mesmo fazer isto, com o scripting DENTRO de uma ao-padro:


<jsp:useBean id=~person" type=~foo.Person" class~~foo.Employee">

<jsp:setProperty name=~person" property=~name" value=~<%= request.qetParameter(~userName") %>" />


</jsp:useBean>
...

Si~

V6Ct!

Sr.t}

Ve'7d6 VlI'ltl

express';e.!JAlr/ttJ
JU.f5JU.O.

dtl.

'9SP:Se.f-R.4pt!J"-Iy> (~f.lese e'7c"Jrf.J"tl de"J-I-rill

d" c"rp<J

de VlI'ltl

-I-~'9sp:vse8ea'7.Sl~ lel"

voc est

usando param

o atributo

paratM d UtMa ajuda

muto simples. Voc pode enviar um parmetro de solicitao direto para um bean, sem scripts, usando um atributo param.

Dentro de TestBean.jsp
<jsp;useBean id~"person" type~"foo.Person" class~"foo.Employee"> param="userName" />

<jsp;setProperty </jsp;useBean>

name~"person"

property~"name"

<html><body> <for.m action="TestBean.jsp"> narne: <input type="textU name="userNamefr> 1D#; <input type="text" name="user1D"> <input type="submit"> </form> </body></html>

360

Mas espere! Ele fica ainda tttelhor...


E tudo que voc tem a fazer ter certeza de que o nome do campo de entrada de dados (o qual se toma o nome do parmetro da solicitao) seja o mesmo que o nome da propriedade no seu bean. A, na tag <jsp:setProperty>, voc no precisar especificar o atributo param. Se voc nomear a propriedade e no especificar um valor ou param, voc estar dizendo ao Container que obtenha o valor do parmetro da solicitao cujo nome seja idntico.

Se alterarmos o HTML para que o nome do campo de entrada de dados coincida com o nome da propriedade:

<html><body> <form action="TestBean.jsp"> name: <input type="text" name="name"> ID#: <input type~"text" name~"userID"> <input type="submit"> </form> </body></html>

Temos que fazer ISTO


<jsp:useBean id="person" type="foo.Person" class="foo.Employee"> I>

<jsp:setProperty </jsp:useBean>

name~"person"

property~"name"

voc est

propriedades

e parmetros

da soieifao

Se voc agetttar, ele MELHORA ainda tMais ...


Observe o que acontece se voc fizer com que TODOS os nomes dos parmetros da solicitao coincidam com os nomes das propriedades do bean. O bean person (que uma instncia de foo.Employee), na verdade possui duas propriedades--name e empID.

Se alterarmos o HTML novamente

A50t'4l.l1rJL.t80S os fat'~e-J.t'os c,,*, os J'lo*,es tias ft'oft'tetlatles

cotJ'lcliJe*, tio betJ.J'I.

<htrnl><body> <form action="TestBean.jsp"> name: <input type="text" name="name"> ID#: <input type~"text" name="empID"> <input type="subrnit"> </forrn> </body></htrnl>

Teremos que fazer isto


<jsp:useBean id="person" type~"foo.Person" class~"foo.Ernployee"> <jsp:setProperty name~"person" property="*" I> </jsp:useBean>

Eu quero que voc faa uma varredura pelos parmetros da solicitao e encontre algum que coincida com os nomes das propriedades do bean, alm de configurar o VALOR das propriedades para que seja igual ao valor do parmetro da solicitao correspondente ...

JSP

Container

362 capitulo 8

As tags do beatl COtlverteiftas propriedades priiftitivas autoiftaticaiftetlte


Se voc j conhece o JavaBeans h algum tempo, isto no surpresa alguma. As propriedades do JavaBeanpodem ser qualquer coisa, mas se forem Strings ou primitivas, todo o esforo feito por voc. Tudo bem - voc mesmo no tem que fazer a anlise e a converso.

Se colocarmos type Employee (em vez de Person)


<html><body> <jsp:useBean id="person" type="foo.Employee" class="foo.Employee" <jsp:setProperty name="person" property="*" /> </jsp:useBean> Person is: <jsp:getProperty name="person" property~"name" /> ID is: <jsp:getProperty name="person" property="empID" /> </body></html> >

Tudo funciona

A ac;9 <:)sp:setl't9peltj>
recebe 9 patmett9 s91lCltac;9,C9n'ette-9 1nt e passa este mt:9d9 set d9 a'Lue1apt9pdedade.
Person is: Kathy 10: 343 ~
A-5,,1""J

a fI"6fl"l'eeiadf! e...,Ib
+a""bJ1.

IVI'/ci'J16t1

voc est

converso prmitva

f etguntas Id'l9tlS r:

N9 ex1st<;;m

Tudo certo, estou considerando que o cdigo do Container esteja fazendo algo como Integer.parselnt("343"). Ou seja, voc no vai receber um NumberFormatException se o usurio digitar algo que no possa ser transformado em int? Por exemplo, se o usurio digitar "trs" no campo 10 do employee?

r:

Se uma propriedade de um bean no tem que ser uma String ou uma primitiva, ento COMO voc configuraria a propriedade sem usar scripts? O valor do atributo da tag ser sempre String, certo?

1\: possvel

1\: Bem pensado. Sim, com certeza algo dar


errado se o parmetro da solicitao para a propriedade emplO no puder ser analisada dentro de um int. Voc precisa validar o contedo do campo para ter certeza de que possui apenas caracteres numricos. Voc pode enviar primeiro os dados do formulrio para um servlet, em vez de envi-Ios direto para o JSP. Mas se voc est determinado a envi-Ios diretamente ao JSP - e voc no quer scripts -, basta usar JavaScript no formulrio HTML para verificar o campo antes de enviar a solicitao. Se voc no sabe JavaScript (que, na verdade, no tem quase NADA a ver com Java), uma linguagem baseada em scripts que roda no lado do cliente. Em outras palavras, no browser. Uma busca rpida na internet por "validao de campo JavaScript" deve trazer alguns scripts que voc pode usar para impedir que usurios entrem com, digamos, alguma coisa diferente de nmeros em um campo de entrada de dados.

(mas seria *muito* trabalhoso) criar uma classe especial, chamada editor de propriedades, que suporte o bean. Ela recebe o valor da sua String e descobre como transform10 em algo que possa ser usado para configurar um tipo mais complexo. Mas, isto parte da especificao JavaBeans, no da especificao JSP. E tambm, se o valor do atributo da tag <jsp:setProperty> for uma expresso, em vez de uma String literal, e SE tal expresso converter um objeto que seja como o tipo da propriedade do bean, a provavelmente funcionar. Se voc passar uma expresso que converta Oog, por exemplo, o mtodo setDog(Oog) do bean Person ser chamado. Mas observe, isto quer dizer que o objeto Oog j deve existir. De qualquer forma, melhor voc NO tentar construir novas coisas no seu JSP! Tentar fugir da criao e configurao de tipos de dados relativamente complexos vai ser difcil sem scripts. (E nada disso cai na prova.)

A converso automtica String-primitiva NO funciona se voc usar scripts! Ela d erro, mesmo que a expresso esteja DENTRO da tag <jsp:setProperty>.
Se voc usar a tag de ao-padro <jsp:setProperty> com a propriedade asterisco, OU simplesmente o nome de uma propriedade sem valor ou sem o atributo param (que significa que o nome da propriedade coincide com o nome do parmetro da solicitao), OU usar um atributo param para indicar que o parmetro da solicitao cujo valor deve ser atribudo propriedade do bean, OU usar um valor literal, a converso automtica de String para int funciona. Cada um dos exemplos abaixo converte automaticamente:
<jsp:setProperty <jsp:setProperty <jsp:setProperty <jsp:setProperty name~"person" name~"person" name~"person" name="person" property~"*" I> I> value="343" property="empID" property="empID" property~"empID"

MAS. .. se voc usar scripts, a converso automtica NO funciona:


<jsp:setProperty name~"person" getParameter ("empID") %>"1> property="empID" value~"<%=

JSP sem scripts

qu?! Sinto-me TO aliviada em descobrir como muito mais fcil usar as tags, em vez de scripts. Os benefcios pra mim so gigantescos.

As tags de aes-padro do bean podem ser mais fceis para quem no programador.
Novamente, os beneficios de usarmos tags no lugar dos scripts tm mais a ver com os webdesigners que com voc (o programador lava). Embora at os programadores lava achem as tags mais fceis de serem mantidas do que os elementos hard-coded do scripting lava. Com as tags relacionadas a bean, o designer precisa apenas das informaes bsicas de identificao (nome do atributo, escopo e o nome da propriedade). verdade, eles tm que conhecer tambm o nome completamente qualificado da classe, mas pelo que consta para eles, isso apenas um nome com pontos (.) dentro. O webdesigner no precisa ter qualquer conhecimento sobre o que acontece por trs disto, e eles consideram beans como registros com campos. voc quem diz aos designers o registro (a classe e o identificador) e os campos (as propriedades). Alm disso, as aes-padro do bean no so to elegantes como poderiam ser. E por isso que nossa histria sobre pginas sem scripts no termina aqui. Continue lendo ...

voc est

propriedades

do

Mas, e se a propriedade for 111FERENfE da String ou prit\titiva?


Sabemos o quanto fcil exibir um atributo quando este, em si, uma String. A, ns criamos um atributo que no era um objeto String (uma instncia do bean Person). Mas no queramos exibir o atributo (person) queramos exibir uma propriedade do atributo (no nosso exemplo, o nome e o empID de person). Isso funcionou bem, pois as aes-padro conseguem tratar as propriedades primitivas e Strings. Portanto, ns sabemos que as aes-padro podem lidar com atributos de quaisquer tipos, desde que as propriedades do atributo sejam Strings ou primitivas. Mas, e se no forem? E se o bean tiver uma propriedade que no seja nem String, nem primitiva? E se a propriedade for um outro tipo de Objeto? Um tipo de Objeto com suas propriedades especificas? E se o que quisermos exibir for justamente a propriedade desta propriedade?

Al.f.a: Pef'SMI

tll>\a classe

cJ'lcl"e.f.ailes+-e ext"Y"/.

String getNameO void setName(String)

public Dog getDogO ublic void setDo o

Person tem uma propriedade String "name". Person tem uma propriedade Dog "dog". Dog tem uma propriedade String "na me"

E se quisermos exibir o nome do cachorro da pessoa?

Cdigo servlet
public void doPost(HttpServletRequest request, throws HttpServletResponse response) IOException, ServletException

tl'aVl J'7:s Cf"il~I>\"S /11>\ b(J5J t)..f.t'/jf.l{I>\()S " e/e Person (); foo. Person p = new foo . p. setName ("Evan"); ~

.fi) O
(11)\ J'7"l>\e e ct.al>\tJ.l>\<lsse
<15

A
e'1>\

el'S"',

foo.Dog dog("Spike") = new foo.Dog{); dog. setName ; p. setDog (dog) ; request. setAttribute

PersaJ'7) call1fJ "'111 o..f.I'l!J/I.f.c a SDIi"cl.f.aj';a, RequestDispatcher view ~ request.getRequestDispatcher("result.jsp"); view.forward(request, response);

("person", p);

C-

.Il.. rrf"'''1/6ve
f>1'(JfrleaJe

Ae"s.,,,,

il j>tl"tl tl S'Vtl -I-eht Vht VI/I",,, P"',f


PeI'S4J'7 (pel1as

JfJ5J CfJ;r/i"jVl'all1as

366 captulo 8

JSP sem scripts

rema.,do

exibir a propriedade da propriedade

Sabemos que podemos fazer isto com scripts, mas ser que conseguimos, usando as aes-padro do bean? O que acontece se colocarmos "dog" como propriedade na tag <jsp:getProperty>?

Sem aes-padro

(usando scripting)

FI.II1ciI1a perfei+o./II1e~

lloIas

+iVf!1loI6S 31.1e lIsar V/II1 scrip+.

<htrnl><body> <%= foo.Person) </body></htrnl>

. request.getAttr1bute("person".getDog()

~ .getName() %>

Com aes-padro
<htrnl><body> <jsp:useBean Dog's

(sem scripting)

id~"person"

class~"foo.Person" name="person"

scope~"request" property="dog"

I> />

narne is: <jsp:getProperty

</body></htrnl>

/ Mas
3!/I)./

ue ti u
Jtlj

VfJlt1rJe

o que

QUEREMOS

O que CONSEGUIMOS
DOg'5 name is: foo.Dog@799338

Dog's name is: Spike

"lvdtl ti 3",e rece!?elloltls'ftlt resvl+ad" dtl "":+<:;d +.5+ri"I1J de D5'

Voc no pode dizer: property="dog.name"


No podemos combinar as aes-padro do bean que funcionaro, dado o cdigo servlet original, pois Dog no um atributo! Dog uma propriedade do atributo. Logo, voc pode exibir Dog, mas voc no pode navegar at a propriedade name da propriedade Dog do atributo Person. A tag <jsp:getProperty> permite que voc acesse apenas as propriedades do atributo do bean. Isto no vale para propriedades aninhadas, s quais voc queira uma propriedade de uma propriedade, em vez de uma propriedade de um atributo.

voc est

p.

367

salvamento EL

A Expressiot' Lat'guage (EU salva o dia!


Sim, bem na hora de nos salvar, a JSP Expression Language (EL) foi adicionada especificao JSP 2.0, livrando-nos da tirania dos scripts. Veja como nosso JSP ficou simples e bonito agora ...

Cdigo JSP sem script, usando EL


<html><body>

A EL facilita a exibio de propriedades aninhadas ... ou seja, propriedades de propriedadesl

Dog'sname

is:
f
1.

${person.dog.name}
f
SSfJ! AlfJS se31er Jec!arQJJ\()S () 3C1e persI1 ele sl"w;plesJJ\el1+e

</body></html>

sijl1tllca

sde.

Isto:

Substitui isto:
<%=
foo.Person) request.getAttribute(~person" .getDog().getName()

%>

Voc no precisa saber TUDO sobre EL.

o exame no espera que voc seja um cara: "EL-manaco". Tudo o que voc geralmenteusa, ou o que pode cair na prova, abordado nas prximas pginas. Assim, se voc quiser: estudar a especificao EL, sacrifique a si mesmo. Mas lembre-se de que no fomos NS que o induzimos a isso.

368

JSP sem scrpfs

At1alisat1do a JSP Expressiot1 Lat1guage (EU


A sintaxe e o alcance da linguagem so bem simples. A parte enganosa que a EL se parece um pouco com o Java, mas se comporta de maneira diferente. Voc vai perceber daqui a pouco, quando chegarmos ao operador C]. E voc encontrar coisas que no funcionariam no Java, mas que funcionam com a EL e vice-versa. Basta no tentar associar as regras de sintaxe/linguagem Java com a EL e voc se dar bem. Nas pginas a seguir, tente pensar na EL como se fosse uma maneira de acessarmos objetos Java sem usar Java.

As expresses EL esto SEMPRE dentro de chaves, precedidas pelo smbolo cifro ("$")
${person.name}

A primeira varivel na expresso ou um objeto implcito, ou um atributo.

${firstThing.secondThing}
OBJETO IMPLCITO EL
pageScope requestScope sessionScope applicationScope param paramValues

/~

ATRIBUTO
Se a fl"'!\ett'fi. ciSQ ~a
no reques page sctope no scope no session scope no application scope

eXfNI!SS4ti il.- /lJl' y~ a+1'11J1I+ e/e flJde seI'

'tids
es.f.es S4 ~e+s de

~cltle e . J Vit'l "..,-/'lgl/"1""" -I.


fJ.l"ltIaje'lad6
t'it'l

it'ltJ.pefi.ltle~+ti header
headerValues cookie

Pe +lJds

DS D~e+Ds t"Y",:C"+es,) ~4C : VItI

3va/vel"

Vit'l

des

tJ.pe~fJ.s fQ5I!Cc~x+ ~afefi.II>,e~D.

esc4fs dtsflJ'Iwels,

i/e:
I

Vltlfi.l"e/et'~Cl"a.

. .
ImtParam pageContext ~

1"1!ll./ ,M c~e+D f~eCc'l.f.eX+!

( D

fl

p~eCc'l.f.eX+

e VII>, fJ.Vll.qt'll.~)

(I.-eit'lbI"e.f.e Os ~e+cs ii"fld+s S it'lesII>,S JlsfM:vets f~eC~x+.

l.- ~4C S4lJ

c'?Jv~+"

ffi.l'fi. sui,+s

Js~
voc est . 369

respostas do exercido

Usatldo

operador pomo (J para aeessar

propriedades e t\1apear valores


A primeira varivel ou um objeto implcito, ou um atributo. E o que vem do lado direito do ponto ser ou um valor map (se a primeira varivel for um map), ou uma propriedade bean, caso a primeira varivel seja um atributo que seja JavaBean.

o Se a expresso

possuir uma varivel seguida por um ponto, a varivel da esquerda TEM QUE ser um Map ou um bean. $ {person.name}

Q.uand9 a v'at'i<lvelest d9 lad9 escrue1"d9cI9 p0nt9, 9U um IVlap (algo C9IHchaves), 9U um bean


(31.1::0

~\
java.uti I.Map um bean

C9m ploptledades). IndependentementE'

st9

vetdade,

de a yad<lyel Set um um 9l:Jet9 Implclt9 9U um atdbut9.

O que estiver do lado direito do ponto TEM QUE ser uma chave de Map ou uma propriedade bean. $ {person.name}

.)~
llname"
I

I\Evan"

getNameO setNameO

java.util.Map

E o que est do lado direito deve seguir as regras non:nais do Java para a nomenclatura dos identificadores.

${person.name}

'-.,:

Deve iniciar com uma letra, _, ou $. Depois do primeiro caractere, voc pode incluir nmeros. No pode ser uma palavra-chave ,Java.

370:aotuo

JSP sem scrpls

o operador

[] setttelhame ao pomo, s que tttelhor

o operador ponto s funciona quando o que est direita for uma propriedade bean ou uma chave map para o que est esquerda. E pronto. Porm, o operador [] muito mais poderoso e flexvel...
Isto: $ {person["name"] }

O mesmo que isto:


$ {person.name}

Cl

A verso simples do operador ponto s funciona porque person um bean e name uma propriedade de person. Mas e se person for um array? Ou uma List? Ou, e se name for algo que no possamos expressar de acordo com as regras normais de nomenclatura Java?

voc est

371

mas

o [ 1 melhor

o [ ] d a voc

tMais

op~es ...

Quando voc usa o operador ponto, o que vai esquerda s pode ser ou um Map, ou um bean, e o que vai direita tem que seguir as regras Java para nomenclatura de identificadores. Porm, com o C], o que vai esquerda tambm pode ser uma List ou um array (de qualquer tipo). Isso tambm significa que a parte da direita pode ser um nmero, ou qualquer coisa que resolva para um nmero, ou um identificador que no respeite as regras de nomes Java. Por exemplo, voc pode ter uma chave Map que seja uma String com pontos no nome ("com.foo.trouble").

Se a expresso tiver uma varivel seguida de colchetes ("[]"), a varivel da esquerda~pode ser um Map, um bean, uma List ou um array. ${musicList[~something"] }

~)\~
java.util.Map umbean java.util.List umarray

Se o que vem dentro dos colchetes for uma String literal (ou seja, entre aspas), ele pode ser uma chave map ou uma propriedade bean, ou ainda um ndice dentro de uma List ou array. ${musicList[~snmething"] }

java.util.Map

getSongListO setSongListO

1:"Zero 7", 2:"BT"


um array

1: "Zero 7", 2:"BT'

372

captulo 8

JSP sem scrpts

Usando o operador [ ] eotlt Utltarray

No servlet
String[] favoriteMusic ~ {"Zero request.setAttribute("musicList", 7", "Tahiti 80", favoriteMusic); "BT", "Frou Frou"};

NoJSP
Music is: $ {musicList}

Music

is:

[Ljava.lang.

String;@d29dd9

First

song is: ${musicList[O]}

l.f,.

First

song

is:

Zero

Isso uma piada, no ?! Ou ento, tem algo mais forte nessa bebida ... eu poderia JURAR que aquilo eram aspas em volta do ndice do array, e isso no est certo, meu camarada ...

Second

song is: ${musicList["l"]}

Second

song

is: Tahiti

80

voc est

li>

373

acessando ists

e arrays

UiM

ndice String for~do no ittt para os arrays e Usts

A EL para acessarmos um array idntica EL para acessarmos uma List. Lembrem-se amigos, isto NO Java. Na EL, o operador [] NO o operador para acesso ao array. No, ele apenas chamado de operador []. (Ns juramos, procure ele na especificao - ele no tem nome! Apenas o smbolo []. Como o Prince ... parecido.) Se ele realmente TIVESSE um nome, seria operador de acesso s propriedades do array/List/Map/bean.

No servlet
java.util.ArrayList favoriteFood ~ new java.util.ArrayList(); favoriteFood.add("chai ice chream"); favoriteFood.add("fajitas") ; favoriteFood.add("thai pizza"); favoriteFood.add("anything in dark chocolate"); request.setAttribute("favoriteFood", favoriteFood);

NoJSP
Foods are: $ {favoriteFood}

Obvi"o.w..e.rl-e) +05+1'1'1'1;0

.:1

/}1'1',l.-lS+

-I-ew.. 1Iw..belo

1J.'lllla,xlJ.

Se o ~ ue e:,tNer fi esquerda ~
0J'

itas,

thai pizza,

anything

d95 colcbetes 191'um ltr'li 9U uma L'151; - e se 9 ndIce uma Sttl'n,g lIteral - 9 ? T9tac. I' J . e 9 pata c lUt.
>

First

food

is ${favoriteFood[O]}

I:,to No tunc19nada:
${favoriteFood[~one"]}

f9terp:e ~<one"n9 p9de 'lrat um luto V9c tet um ett9, Ca59 9 ndIce no
Second food is ${favoriteFood["l"]}

p955a set t9tad9.


4.ili"+<l) w..lIl+ eS'6l1tst+lJ) w..o.s +114 bew.. se

~
Second food i8 fajitas

1M'

as si"w..~ile

IIII'/d<ll'/IJ.) v <lll w..eIJ.C<lS+VIJ'IIJ.f'


C<l1J'l

tssc,

374 captulo 8

JSP sem scripts

Encare os fatos, menino-ponto. Sou muito mais legal que voc. Voc sabe o que a especificao fala a seu respeito? Ela te chama de "um operador de convenincia". Isso muito engraado.

Ah, qu isso! Fala srio, ALGUEM ainda usa arrays? Arrays e lists so to ... "2003". Lineares. Chatos.

voc est

li'-

375

[] e o ponto

Para beat1s e Maps, voc pode usar atftbos os operadores


Para JavaBeans e Maps, voc pode usar tanto o operador [], como o operador de convenincia ponto. Pense nas chaves Map da mesma forma que voc pensa nos nomes de propriedades em um bean. Voc pede pela chave ou pelo nome da propriedade, e recebe o valor de uma ou de outra.

No servlet
java.util.Map musicMap = new java.util.HashMap();

musicMap.put

("AmbientO,

"Zero

7");

Crte VhI

/f.4.l1,f; adlclt>l1e

ele a'Jvhlll.S

musicMap.put("Surf", "Tahiti 80"); musicMap.put("DJ", "8T"); musicMap.put("Indie", "Travis"); request.setAttribute("musicMap", musicMap);

ct,,~ves S+t'tnjS
+t'R.l1sfe.t"h1f;

e (Jtje+4S; e

1"$+4 ehl VhI R.+t'fbl/+4

de s4lfcr+o.{G.(J.

NoJSP
Ambient is: $ {musicMap.Ambient}

is:

Zero

Ambient

is:

Arnbient is:

Zero

376

captuo 8

JSP sem scripts

Se NO for u~a String literal, ela convertida


Se no houver aspas dentro dos colchetes, o Container avalia o que est nos colchetes, procurando por um atributo ligado quele nome e substitui o valor do atributo. (Se existir um objeto implcito com o mesmo nome, o objeto implcito prevalecer.)
Seli<\

'"
as aspas e""
A-Ii<\bletrl-)

IS+ AiA-o nen/,(,I""

fVJ';ciona!!

J: 3ve ;/;" ex,sh

Music

is: $ {musicMap [Ambient] }

a+l'tbv+" blH'Iti cl.IJ.""tJ.ti" fJr""blen.f) , / resvl+ati e 1'1(,1/t ,.

Encontre um atributo chamado "Ambient". Use o VALOR deste atributo com chave no Map, ou retome nulo.

No servlet
musicMap.put
rnusicMap = new java.util.HashMap(); "Zero 7/'); musicMap.put("Surf", "Tahiti 80"); musicMap.put("DJ", "BT"); rnusicMap.put("Indie", "Frou Frou/l); java.util.Map

("Ambient/1,

request.setAttribute("rnusicMap", request.setAttribute("Genre",

musicMap); "Ambient");

Isto

FUNCIONA

no JSP
, cti.lcvllJ.

Music

is ${musicMap[G~~re]

}pal'a.

Music

is $ {musicMap["Ambient"]

porque EXISTE um atributo na solicitao chamado "Genre" com um valor "Ambient", "Ambient" uma chave para musicMap.

Isto

NO

funciona no JSP (dado o servlet acima)

Music

is $ {muslcMap ["Genre"] }

1'/4"

""vtia

Music

is $ {musicMap ["Genre"] }

porque NO existe nenhuma chave em musicMap chamada "Genre". Com as aspas, o Container no tentou efetuar a converso e simplesmente considerou que era o nome de uma chave literal.

1.S+4 ~ (I""a

I
I
J'I(}'S

vlJ.hiia) ""as
pt'{!ClSIJ.Ii<\(},S.

ave

J'l4

14.; (},

voc est aqui ~

377

expresses aninhadas

Voc pode usar expresses attinhadas detttro dos colchetes


tudo expresses na EL. Voc aninha expresses em
quaisquer nveis. Ou seja, voc pode inserir uma expresso complexa dentro de outra expresso complexa, e outra, e outra, e outra ... E as expresses so avaliadas dos colchetes mais internos para fora. Esta parte parecer-lhe- bastante intuitiva, pois igual forma como aninhamos o cdigo Java dentro dos parnteses. A armadilha est em observar pelas aspas X sem aspas.

No servlet
java.util.Map musicMap = new java.util.HashMap(); musicMap.put("Ambient", "Zero 7"); musicMap.put("Surf", "Tahiti 80");

musicMap.put

("DJ" , \'BT") i
"Frou Frou"}i ("musicMap" , musicMap);

musicMap.put("Indie", request. setAttribute

String [] musicTypes

= {"Ambient", request.setAttribute("MusicType",

"Surf"

"DJ", "IndieU}

musicTypes);

Isto FUNCIONA no JSP

Music

is ${musicMap[MusicType[O]]}

Music

is ${musiCMap["Ambient"]l

I -..........---is Zero 7

Music

is: Zero

Music

378

captulo 8

JSP sem scripts

Voc t1o pode fazer

$ {foo .1}

Com beans e Maps, voc pode usar o operador ponto, mas s se o que vier depois do ponto for um identificador Java legtimo.

Isto
$ {musicMap.Ambient}

Mas

isto

${musicMap[~Ambient"l}

o mesmo que isto


${musicLst[~l"l }

Se voc no for usar isto para um nome de varivel no seu cdigo Java, NO o coloque depois do ponto.

NO PODE ser transformado


${musicLst.l}

nisto

o que vai ser exibido?


Dado o cdigo servlet abaixo, tente descobrir o que ser exibido (ou se for ocorrer um erro, apenas escreva, voc sabe, "erro"). Respostas no final da pgina.
java.util.ArrayList nums new java.util.ArrayList(); nums.add(~l"); nums.add(~2"); nums.add(~3") ; request.setAttribute(~nurnbers", nums); = {~Zero 7", ~Tahiti 80", ~BT", String[] favoriteMusic request.setAttribute(~musicList", favoriteMusic);

~Frou

Frou"};

$ {musicList [nurnbers[O]] }

${musicList[numbers[O]+l])

r
}

(Fltu"eil'it:i$

il'iiUS

s"bl'l!

t:iS

ff!!I'AtiN!S

Ire~.)

iL a'JViI'iASf~l"'o.s

e
~

${musicList[numbers[~2"]]

${musicList[numbers[nurnbers[l]]]}

voc est

'"'

379

exerccio gigante sobre EL

~$';; \ m. de &lldeltl
~ No se surpreenda se cair uma questo assim na prova (se bem que na prova oficial isso parecer mais ... apavorante). Estude as trs classes nesta pgina, o cdigo servlet na pgina seguinte e construa, a partir do Im de Geladeira, a EL cujo resultado exibido no browser. (Vire a pgina para ver as respostas. Mas NO ANTES de voc finalizar o exerccio, principalmente se voc for fazer o exame.)

foo.Toy package foo; public class Toy { private String name; public void setName(String) name) { this.name=name;

}
public String getNameO { retumname; }

foo.Person package foo; public class Person { private Dog dog; private String name; public void setDog(Dog dog) { this.dog=dog; } public Dog getDogO { retum dog; } public void setName(String name) { this.name=name; } public String getNameO { retumname; } }

foo.Dog package foo; public class Dog { private String name; private Toy[] toys; public void setName(String name) { this.name=name; } public String getNameO { retumname;

}
public void setToys(Toy[] toys) { this.toys=toys; } public Toy[] getToysO { retumname; }

::;.espostas do exerccio anterior: 1) Tahti 80 2) BT 3) Frou Frou 4) Frou Frou

380

captulo 8

JSP sem scrpts

cdigo Servlet
foo.Person p = new foo.Person(); p.setNarne("Leelu"); foo.Dog d ~ new foo.Dog(); d.setNarne("Clyde"); foo.Toy ti = new foo.Toy(); tl.setNarne("stick"); foo.Toy t2 = new foo.Toy(); t2.setNarne("neighbor's cat"); foo.Toy t3 = new foo.Toy(); t3.setNarne("Barbie=doll head"); d.setToys(new foo.Toy[]{tl, t2, t3}); p. setDog (d); request.setAttribute("person", p);

Crie a EL para este resultado:

toy are: cat, head and a Barbie

stick, doll

.name

${person.name}

and a ${person.dog.toys.name} ~

toys

L....;.J I. toys Ir:;;-Ig

toys

"name"] [I

toys ["name"]

voc est

li"

381

respostas

do exercicio

Im de &hldeltq Resp9stqs

~ ;' I
s.fa na4 e ~ IJAJICIJr f.,,.. .. a Je N:f>I'4JII"1/" OS es.f.e IIS4PJJ4eSffs '" (.. "L Je eXf>l'f!SSa() l'eslll.f~J()J ,1.$. 4 t5'1"c4 extsffl1.fe I ~" f '" ' as. "}fel'e/c,6 Je boPJvs; eScreva

fJ.

/ N IIJI' t.Jtlel'f!wn: f~_ <'es3vf!jfJ. S , t.s)J as ave extbt< es f'esv,.f.aJ,

cdigo Servlet
foo.Person p = new foo.Person(); p.setName("Leelu") ; foo.Dog d = new foo.Dog(); d.setName("Clyde"); foo.Toy tl = new foo.Toy(); tl.setName("stick"); foo.Toy t2 = new foo.Toy(); t2.setName("neighbor's cat"); foo.Toy t3 ~ new foo.Toy(); t3.setName("Barbie~doll head"); d.setToys(new foo.Toy[]{tl, t2, t3}); p.setDog(d) ; request.setAttribute("person", p);

Crie

a EL para este resultado:


dog Clyde's toy are: stick, dalI

Leelu's

neighbor's head

cat, and a Barbie

1.$.{p.e.r.s.o.n ..n.am_e.lIG6

${person.dog.name} Gl

toys are: I ${person.dog.toys EJarJ

I ${person.dog. IltoYS[llll .nameIrJBj${person.

'61tOYSIElDEJD
.name),

${person.name}'s dog $(person.dog.name}'s toys are: $(person.dog.toys[O] ${person.dog.toys[l] .name}, and a ${person.dog.toys[2] .name}

r:;:l~ ~L:J EJ
toys["name"l

I ${person.dog.

toys. ["name"ll

382 capJ'tuloB

JSP sem scripts

o caso

do comedo ausettte

Cl'nc9 ml'nut9s ~ MIste:t19S9S

A Documents-R-Us criou um sistema de gerenciamento de contedo usado basicamente para criar tutoriais para os aplicativos desktop. Parte dos aplicativos permite que os desenvolvedores do contedo criem partes de contedo do tipo "Dica do Dia" (Tip ofthe Day), que so armazenadas no atributo currentTip no escopo da solicitao. Por exemplo, se a dica fosse "Lave seus cabelos dia sim, dia no" (Wash your hair every other day), ento, a tela incluiria uma caixa como esta:

o cdigo
<div <b>Tip

JSP para esta caixa de dica :

class='tipBox'> of the Day:</b> <br /> <br />

${pageContent.currentTip} </div>

Um novo cliente est tentando criar um tutorial usando o sistema, mas parece no poder fazer com que as dicas sejam exibidas corretamente. Por exemplo, a dica "<b></b>tags make things boldl" apresentada assim:

"O que est havendo", exclama Tawny, a principal desenvolvedora JSP do cliente. "Para onde foi o incio da dica?" Por que as tags em negrito no foram exibidas?". Ela envia um relatrio de erro imediatamente para a Documents-R-Us.

o que

voc acha? As tags em negrito foram enviadas para ofluxo da sada? Por que no esto sendo exibidas?

voc est

I?

383

puro html

El apresettta o mistrio

o texto bruto, inclusive o

HfMl
<div class=TtipBox'> <b>Tip of the Day:</b>
<brJ> <br/>

resolvido quando voc v o HTML real que gerado ...

Portanto, a parte "<b></b>" da dica est sendo enviada para o fluxo de s';!da, mas o navegador da Web simplesmente est apresentando-a como HTML bruto - colocando em negrito um espao vazio na pgina. Assim, claro, o usurio no v as tags "<b></b>" na tela.

o HTMI.. que gerado


<div class=!tipBox1> of ~he D3y:</b> <br/> <br/>

~2gS 82xe
</div>

t~lngs beld!

o mesmo
<div

ocorre para as tags da expresso JSP... 1V~43i/e iss ava.fiase!"~ +f"a+o.~ c,,~ HrM.L fD.~f"itlJ ftl!"+D.I1+()J ai/a/Slle!" +D.j HrM.L tJ.fresel1+o.~o.J class=ftipBox'>
af
the Day:</b> <br/> <br
#l" ext!Ji"~f1. C4~L\ +ex-l-IJ.

<b>Tip

<%= pageContent.getCurrentTip() </div>


() ~eS~4

'13{1i.lJ~ +ex-l-t;

C<l~

... e para a ao padro jsp:getProperty


<div class='tipBox'> <b>Tip of the Day:</b> <br> <br/> <jsp:getProperty </div> name='pageContent'

<.r><./r> e <.b></ b> tJ.f,..ese~{(~tlJ l1i extbt~1J CIJ~IJ+ex-l-" c,,~v~.

property='currentTip'

!>

EXERCITE SUA :MENTE


Tudo bem, ento a string de dica est sendo enviada para o fluxo de sada, mas a Documents-R-Us deseja converter os caracteres HTML especiais em um formato que seja apresentado devidamente em suas dicas. Portanto, queremos enviar "&lt;" para que o usurio veja o caractere < real no navegador e "&gt;" para produzir o caractere >. Como voc faria isso?
384 c8oj'tulo 8

JSP sem scrpts

Os objetos itMplcitos da EL Lembre-se, a EL possui alguns objetos implcitos. Mas que no so os mesmos objetos implcitos do JSP (exceto um, o pageContext). Eis uma relao rpida; vamos estudar alguns deles mais detalhadamente algumas pginas adiante. Voc ir observar que todos eles, exceto um (o pageContext de novo), so simples Maps pares nome/valor.

pageScope requestScope sessionScope applicationScope

U"" JlA.ap 05 a.f-l'lbfl-/-05 o escopo.

param paramValues

JlA.apS pal'o. 4S pru:;""e.f-I's a sollct.f-a{.

header headerValues

JlA.aps paro. 45 t,efJ.ers a soiict-/-aJ';o.

L_ I" I" Ooot.t.t"t. . es-n: e l-11I:1I sera "I" 3f11!! e

cookie

ti""

JlA.appal'a C4fJl:les?

u""

~ap

tJS pal'~dl's

I",l-/-

ctJl"lhx.f-

initParam (AJl}o par~e.f-I's

I"'l.f- d servle-/-/;

I"

I} ~J'jica cdsa

ave !J-o ~ V""


real atJ

I!!

pageContext "''''' real eal - """a reler~cl"a


pajeCJr!.ex-lj 4 '/;/lal (I"" bea;;. Observe ;;41

para PtJ.jeCMhx.f.. voc est


l?

385

parmetros

e parmetros

Vafues

PartMetros

de

solicita~o t1a

EL

Muito fcil. objeto implcito param timo quando voc sabe que possui apenas um parmetro para aquele nome de parmetro especfico. Use os param Values quando voc tiver mais de um valor de parmetro para um nome de parmetro dado. // //
e"'fIb -hl'cJ cada v~ ,... /.1
J

No formulrio HTML
<form action="TestBean.jsp"> Name: <input type="text" ID#: <input type="text" name="name"> name="empID">

() "a-"\e ec I
dis valet'es)

7.1

c sev
IMde-hi"

valct' (lI1ic(;.'-{as c ptJ.r4-"\ffi"c


,.

166ti

se c (,IS(,ltJ.l'i"4 preenchel'

1J.-"\gesoS

ca"'Y's tJ.n.fes de dica!' J1bch


~

SI./b-"\I-+,

First food: <input type="text" name="food"> Second food: <input type="text" name="food"> <input </form> type="submit">

,.

LeJ>lbre-

se:

<I

ftJ.i"tJ.-"\ e apel14S (/-"\ 4ap

tis

l1oJ>leSe ValN!S d<lptt.i"M..e+rc. () al./e es+: ~ tli"rei+4 d P(J~(J veJ>ltics #'/-"\es especll.i"ctJ.dos
f
;I"

NoJSP
Request Request Request param param param name empID food is: $ {param. name} <br>

I'I(JSctl.;"y>!>s tie el'lr'rtt.da tie tiatis de Itll'J>lillt'I'IfJ,.

is: $ {param. empID} is: ${param.food}

<br> ~

i~bl'l< peSStlJ>l

<br>

drlerel1.fes vall'es ptv'a


Ao

/1'

fI

<l

A"

First food request param: ${paramValues.food[O]} <br> ,) ,. Second food request param: $ {paramValues .food[l]} <br> petie (lSfJ.r tl c~e+<I i,w;plld+ Request param name: ${paramValues.name[O]}

ptJ.l'a~e+rl:l

le

lce ti.!..,da

ftJ;I'!'~ slity>/es) ~tJ.S


fl.peJ'lQ.stl fri"~erl'() Va/tM".

No browser do cliente (o cliente preenche


o formulrio e clica em subn1it)

A resposta

Name: Fluffy First food:1Sushi Second food: IMacaroni

ID#: ~14_23
I

Request param name is: Fluffy Request param empID is: 423 Request param food is: Sushi First food request param: Sushi Second food request param: Macaroni Request param name: Fluffy

& Cheese

I (Submi0

& Cheese

386

JSP sem scripfs

se voc quiser ",ais

i. fo""a~es da solicita~o?

E se voc quiser, por exemplo, a informao do servidor contida no header "host" da solicitao? Se voc olhar na API HttpServletRequest, encontrar um mtodo getHeader(String). Sabemos que, se ns passarmos "host" para o mtodo getHeaderO, obteremos algo como "10calhost:8080" (pois onde o servidor est).

Obtendo

o header

"host" ti aJe+~ i'~/:Ci'.f.~ "ea.lel' IP,<I.~"" IIIP, 14'f .le .f.t:>(l~sIJS t.ea.lel's. se
IJ

Sabemos que podemos fazer isto com scripting


Host is: <%= request.getHeader(~host")

%>

a IJpel'a.lI/)/' .le acessc ptJ.l'tJ. ftJ.ssal' Mas com a EL, temos o objeto implcito header
Host Host is: ${'header[~host"]}
IJ

6 17,,""'e d6 t.eader e

IJ

vaIeI' 3"e e/e

exibi'I':.(IJIJ.f.a: exis-fe h""b~",


etje.f.1J irlpl:c".f.1J t.eade,.Valves

is: ${header~host}

ptJ.l'a "ea.lers

te,*,

vtl.llJl'es.

Obtendo o mtodo de solicitao

HTTP

Bem, este um pouco mais complicado ... existe um mtodo naAPI HttpServletRequest para getMethodO, que retoma GET, POST, etc. Mas como eu consigo isto usando a EL? Sabemos que podemos fazer isto com scripting
Method is: <%= request.getMethod()

%>

Mas com a EL, isto NO funciona


Method is: $ {request.method}

IJ-o! Al-ti! Al-ti! Al"


"fie.f." '>y:ld.f.c I"elleS.f./

fx.Isf.

E isto NO funciona
Method is: $ {requestScope.method}

Voc consegue imaginar como fazer isto?


Dica: observe os outros objetos implcitos.

voc est

IW

387

os map scopes NO so

ems

o requestScope

NO o objeto request

o req~e.stS~ope ~mplci!o apenas um Map dos atributos do escopo da,sohcitaao, n~o o objeto request em si! O que voc deseja (o m~todo HTTP) e uma ?~opriedade do objeto request, no um atnbuto do escopo sohcltao. Em outras palavras, voc quer algo .que vem da chamada do mtodo get no objeto request (se
cons1d:ra~os o objeto request um bean).
Mas nao eXiste nenhum objeto implcito request apenas requestScope! O que fazer? ' Voc precisa de algo mais ...

Use o requestScoPe Para obter Os ATRIBUTOS da SOlicitao, e no as PROPRIEDADES. pageContext. Para obter as propriedades, voc precisar do

Use o pageContext para obter todo o resto ...


Method is: ${pagecontext.request.method}

o pageContext P~ssui uma propriedade request O request pOSSUi uma propriedade method

No confunda os objetos de Map scope com os objetos aos quais os atributos esto associados.
muito fcil imaginar que, digamos, o applicationScope seja uma referncia para o ServletContext, pois ali que os atributos do escopo da aplicao so associados. Mas, assim como o requestScope e o objeto request, o Map scope para os atributos de escopo da aplicao apenas um mapeamento de atributos e nada mais. Voc no pode trat-Io como um Contexto Servlet; portanto, no espere receber as propriedades do ServletContext a partir do objeto implcito applicationScope!

388

JSP sem scripts

Os objetos itflplcitos de escopo podetfl salv-Io


Se tudo o que voc precisa exibir o nome de person, e voc realmente no est preocupado em saber a qual escopo person ertence (ou at est, mas sabe que existe apenas um person nos quatro escopos), basta usar:

$ {person.name}
Ou, se voc estiver muito preocupado com eventuais conflitos de nome, voc pode especificar qual person voc quer:

$ {requestScope.person.name}
Mas, existe outra razo para voc querer introduzir o atributo com o objeto implcito do escopo? Alm de controlar ... escopos? Imagine esta situao: se voc possui um nome que no esteja entre aspas dentro de colchetes [], isso significa que ele respeita as normas de nomenclatura Java, certo? At aqui, tudo bem, pois person um nome de varivel absolutamente aceitvel em Java. Mas isto assim, porque em algum lugar algum disse: request.setAttribute(~person", p);

Mas um nome de atributo

uma

5tring!

As Strings no seguem o padro para nomes de variveis em Java! O que significa que algum poderia dizer: request.setAttribute(~foo.person", IJ-o!
12.cet+c hlt4S

p);

cef'+ahllf!l'/+e

uJ

u/

CCPI+12.plef'acho.

A voc estaria em apuros, pois ISTO no funcionaria:

3vIi!

h,U.l

li! VhI fJ.+f'tbil+o~

rle fJ.'$IIh1o. coisa; 1/ C(JhI Vhltl U pf'0pl'terlo.rle Ct;J'I+afl'/el' "+f'tbv+a pef's(JJ'I M.as

$ { foo
t;
VhI

.person . name }

/)' it<hl12.IS n em;Pl+f'tt


h,a

Mas voc agradeceria aos objetos de escopo, pois os objetos de escopo permitem que voc mude para o operador [], que aceita nomes de String que no respeitam os padres Java.

Perlet+!

{J sal'

4~e+ll

N!?pes+5cpe

pllsslbflt+a-i1(Js fJ.+l'bil-l-

cillCfJ.f' l111hlf!rlc

1f!11+f'e aspas.

voc est aqui ~

389

mais dois obietcis

Recebet1do Cookies e it1it paratMs


Ns vimos todos os objetos implcitos, exceto os cookies e os init params, mas aqui esto eles. E claro, qualquer um deles pode cair na prova.

Exibindo o valor do Cookie "userName"


Sabemos que podemos fazer isto com scripting
Is+ ~ ltIet",tic/c/'s< AJlto pSS(lt p<>i"s<> tje+ (l1tI it'I~(Jti 1iit'l(JS 311e C.M/r.ie e

<% Cookie[] for if


%>

cookies

~ request.getCookies();

N!3I/es+

(int i ~ O; i < cookies.length; i++) { ((cookies [i] .getName ()) .equals ("userName") out.println(cookies[i] .getValue();

5e+CJ:te(c(J(Ji:teAJf),it'le)!

{ !rhr, Qt'I', c""f'le+6 / ti


l'epf!+Jr
tJ.<l

!M15 tiele "'tS it'Iesit'l(JS.

Mas com a EL, temos o objeto implcito Cookie


$ {cookie .userName. value}

/4.lIIrf)
vu.l(J1' seI':

it'Ia.is f:ctl.ltpf!I'Jt1.S l'&tlt'i'/b.titJ

lNleft1.

ti 1'J(Jit'le f!

ti(J /4.ap i'/it'les IVb.ltJl'es

ti c./r.te.

Exibindo o valor de um parmetro init do contexto


Temos que configurar o parmetro no DD
'" 3(1f! Y"Ce (;l'l'liJflf'f), tlS

<context-param> <param-name>mainEmail</param-name> <param-value>likewecare@wickedlysmart. </context-param> Sabemos que podemos fazer isto com scripting
email

'" +.l'S com</param-value>ptJ.t'b.h1t'


(PfU,(J.

tie CtJ17

+t X+.

+etia a

tJ.pIfCD.5'i,,).

dtlel't'''J+t

des Inl+ pllrait'lS

d<> sel'vle+.
%>

is: <%= application.getlnitParameter(nrnainEmail")

E com a EL ainda mais fcil email is: $ {initParam.mainEmail}

I d t- do a params I O initParam da EL NAO e _ ~s ma configurados que usam <mlt-param>.

E' .

e con.(unde os init params do servlet so configurados usando qu ':!, . ms de contexto usam <context<init-param>, enqu~n~o ~;~e.ops para" d EL para params de contexto! param> mas o implzclto lnzt aram a. . dores ' d .' enr que os cna Se eles tivessem nos consulta o, mamas ,~ug p "mas eles da especijicao colocassem o nome de context aram ... esqueceram de nos consultar novamente.
ISSO

390

c8.ptulo 8

JSP sem scripts

Ela t1o eot1heee as fut10es EL Quando voc precisar de uma ajudinha extra de, digamos, um mtodo Java e no quiser usar scripting, voc pode usar uma funo EL. uma maneira fcil de escrever uma expresso EL simples, que chama um mtodo esttico em uma classe Java simples que voc cria. Tudo o que o mtodo retomar ser usado na expresso. De fato, isto requer um pouquinho mais de trabalho, mas as funes daro a voc muito mais ...funcionalidade.

voc est

391

funes na EL

Il11agitleque voc queira o seu JSP para jogar dados


Voc chegou concluso de que seria incrvel ter um servio de jogos de dados on-line. Assim, em vez de caar os dados reais atrs da mesa e debaixo das almofadas do sof, um usurio iria at a sua pgina da internet, clicaria no jogo de dados virtual e... pronto! Os dados rolariam!! ( claro que voc nem imagina que uma busca no Google provavelmente trar a voc por volta de uns 4.420 sites sobre este tema).

o Crie uma classe Java com um mtodo esttico

pblico.

Isto s uma classe Java simples e regular. O mtodo DEVE ser pblico e esttico, e pode ter argumentos. Ele deveria (mas no requerido) ter um tipo de retomo no-void. Afinal, a questo principal cham-Io a partir de um JSP e obter algo de volta que voc possa usar como parte da expresso ou para exibir. Insira o arquivo de classe no diretrio IWEB-INF/classes (fazendo com que coincida com o diretrio apropriado do pacote, tal qual voc faria com qualquer outra classe).

f) Crie um arquivo Tag Library Descriptor (TLD).


Para uma funo EL, o TLD oferece um mapeamento entre a classe Java que define a funo e o JSP que chama a funo. Desta maneira, o nome da funo e o nome do mtodo em si podem ser diferentes. Por exemplo, voc pode ter a uma classe cujo nome do mtodo seja bem estranho, e talvez voc queira atribuir um nome mais bvio ou intuitivo para os webdesigners usando a EL. Nenhum problema - o TLD diz: "esta a classe Java, esta a assinatura do mtodo para a funo (incluindo o tipo do retomo) e este o nome que usaremos nas expresses EL". Em outras palavras, o nome usado na EL no precisa ser igual ao nome do mtodo, e no TLD que voc mapeia isso. Coloque o arquivo TLD dentro do diretrio /WEB-INF. Atribua a ele uma extenso .tId. (Existem outros lugares onde o TLD pode ficar; ns falaremos sobre isso nos dois captulos seguintes.)

e
o

Coloque uma diretiva taglib no seu JSP.


A diretiva taglib diz ao Container: "eu vou usar este TLD e, no JSP, quando eu quiser usar uma funo deste TLD, vou comear seu nome com ..." Em outras palavras, ele permite que voc defina o namespace. Voc pode usar funes de mais de um TLD, mesmo que elas tenham o mesmo nome. A diretiva taglib semelhante a dar a todas as suas funes nomes totalmente qualificados. Voc invoca a funo fornecendo o nome da funo E o prefixo do TLD. O prefixo pode ser o que voc quiser.

Use a EL para invocar a funo.


Esta a parte fcil. Voc chama a funo atravs de uma expresso usando $ {prefix:nameO}.

392 captulo 8

JSP sem scripts

A classe function, o TLD e o JSP

A classe com a funao _


Package roo;

o Itt.f-,, IlIl'Ic.f-tcJ1vivi ser ptbllc

es+:.f-tc.

public class Di~ _ PUblic ~~erol~er { ~tat~ int return (in~) E211di~ () } L Math.random()

Arquivo Tag Library Descriptor (TDL)


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

AJA-o se precllpe

C",,",

<taglib xmlns="http://java.sun.com/xml/ns/j2ee" ~/ xmlns="http://www.w3.org/20Cl/XMLSchema-instance" ,~ xsi:schemaLocation="http://java.sun.com/xml/ns/j;V~e/webjsptaglibrary 2 O.xsd" version~"2.0"> ///

.f-v1)ls.f-" el1.f-r" a +0.5 <+RJIi'b :>. Fa!arelttlJs ltta1s s!Jre aS rLVs 1'/6S P":XiIl<lIJS IS

-<tlib-version>1.2</tlib-version> <uri>DiceFunctions</uri> -~-~____ <function> ~" ~/

~/

<name>~ol.lIt</name> . <funct~on-calss>foo.D~Rol1er</funct~on-class> <function-signaturr int rolldice ()/ </function-signature> </function> . "_,, "

/< -',,_.

/Z-.

cap:.f-I.I!()s.

"

o I/rt 114{rM'va

.f-RJllb

\\

il'r!crll<la a CI1.f-oJl1erN
'"

</taglib>

,,

nl)lI<IeI) "ft..!J '&ve AJA-o preCisa ser I) II<Ie'SII<II) nl)lI<Ie I) A-Jt1IJIvob) alie' c

C"I1+at"el" pl'eclsa para alie fSSil. sdef' a alia/

1I<I:+6d" ct.all<lal'&lIan6 6

J.sp t;'JV6CtU'
/
() pl"ellx6 iJlt;,e e apel1as

I.!

IW'1fjQ.6

U...

OJSP

I:.ape/ttJc 3Ve'vstu'ell<laS AJ5rAf~l;'~ paf'fJ.3l1f!

pSStl.iJlcS1;,1I:.l"l><.al" a lIl><. rL.!J SI:.bre "


6(1'+-1"1)

(CI<$6

vI:.c I'f!a/w,el'lf.e ,,",ais de yw.J.

pC$$va

voc est

. 393

distribuindo com uma funo

Vistribuitldo

utMa aplicao

COtMas

futl~esestticas

A nica informao nova aqui o arquivo "myFunctions.tld". Ele deve ficar em algum lugar no WEB-INF ou em um dos seus subdiretrios (a menos que ele tenha sido distribudo em um arquivo JAR, mas falaremos sobre isso mais adiante). Aqui, devido a esta aplicao ser to simples, ns temos o DD (web.xml) e o TLD (myFunctions.tld) no topo do WEB-INF. Mas voc poderia organiz-Ios em subdiretrios. O importante que a classe com a funo esttica DEVE estar A c1a")se C9m q tunC(9 disponvel para a aplicao, portanto ... por hora, voc sabe que colocando dentro do WEB-INF/classes funcionar. E lembre-se (9 mt9d9 estfttle9 de que na diretiva taglib do JSP ns especificamos um URI que coincide com o URI declarado no TLD. Por enquanto, considere pblk9) deve estar o URI como simplesmente o nome que voc escolheu para o dlsp9nvel pm'q q TLD. s um nome. No prximo captulo sobre o uso de tags qplkq9 exatqnlente customizadas, trataremos em detalhes dos TLDs e URIs.
<%@ taglib prefix="mine" uri="DiceFunctions"%>

[sI-< ~ , ".h.r." , ~v "" "".,,,,\.~

<vri>

nP.

C9m9 q5 clq5ses set\' let, bean e l1stenet. Ou se Jq, dentt9 d9 \VEB-t~/ ~ .


v nl~'''ID''I <-t.~'LJ=d

11

nslHt 9 m~u'N9 1LD em qlrUnl lutat dentt9 d9 \VEB-NF e assegure-se de crpe a d'ltetlva tqgllb n9 JSY P9SSUqum at1but9 " o "da C9nl lIt1 ~ue C9111C1 1 o 9 element9 <Ut1> n9

f) JS? 3",e /i>!V~C<l


<l

f(lJ1{;~!.L.. ~

TLD.

myFunctions. tdl

f) 17_lJ
itleratl"
" /

3ve tleclal"tJ. tJ.eM;$" se

1"'l'Ic+taI'lJ a tJ.ssli>!a+vl"l1. .Ia ( " 1'16it1( tia IVi1fll.".


AI

web.xml

DiceRoller.class 394

JSP sem scripts

N9 ex1stem

Yerguntls dl9tl8

r:

Uma expresso scriptlet comum TEM QUE retomar alguma coisa. Se voc diz <"Ia= foo.getFooO "Ia>, o getFooO NO deve ter um tipo void de retorno. (Pelo menos, foi o que voc disse antes.) Ento, estou achando que o mesmo acontece com as funes EL?

30 nome do MTODO
o o r no igual ao nome da Veja lst9. FUNO!
T

1\: No! NO acontece

o mesmo com as funes EL, embora todos acreditem que sim ... curiosamente. Imagine o seguinte: voc est chamando uma funo EL que no retoma nada, ento voc est chamando-a apenas para despertar seus efeitos colaterais! Considerando que parte do objetivo da EL reduzir a quantidade da lgica em um JSP (um JSP que deve ser a VIEW!), invocar uma funo EL s para desencadear seus efeitos colaterais no parece uma boa idia. Como o Container encontrou o TLD? O URI no coincide nem com o caminho, nem

Guarde bem as relaes entre a classe, o TLD e o,JSP Mais importante, lembre-se de que o nome do l!ETODO NO precisa coincidir com o nome da FUN~o. .0. que voc usa na EL para invocar afimo deve comcldlr com o elemento <name> na declarao <fimction> no elemento <function-signature> est ali para TLD.

infonnar ao Container que mtodo chamar quando o JSP usar o <name>. E o nico lugar onde o nome da classe aparece (al~m da prpria declarao class) no elemento <functlOnclass>. Oh, ej que estamosfalando sobre isso ... voc per~ebeu que tudo na tag <function> leva a palavra <functlOn>, EXCETO na tag <name>? Portanto, no se engane:

r:

com o nome do arquivo TLD. Foi um milagre? a pergunta que espervamos que algum fizesse. Sim, voc est certo, ns nunca informamos ao Container exatamente onde encontrar o arquivo TLD em si. Quando a aplicao distribuda, o Container varre o WEB-INF e seus subdiretrios (ou os arquivos JAR dentro do WEB-INF/lib) procura dos arquivos .tld. Quando encontra algum, ele l o URI e cria um mapeamento que diz: "O TLD com este URI , na verdade, este arquivo neste local. .." Existe um pouco mais dessa histria que falaremos no prximo captulo.

1\: Justamente

< funct ion>

\\

<function-name>rollIt</fnctionname>
<function-class> foo.DiceRoller</functionclass> <function-signature> int rollDice () </function-signature> </function>

A tag correta para o nome da funo <name>!

r:

Uma funo argumentos?

EL pode conter

. <functlon>

'" J /V"f'1it\C-fl

I,

<n~~>rollIt</~~e>

1\: Certamente.

Apenas lembre-se de especificar o nome da classe totalmente qualificada (a menos que ela seja uma primitiva) para cada argumento no TLD. Uma funo que emprega um Map seria:

<function-class> foo.DiceRoller</functionclass> <function-signature> int rollDice () </function-signature> </function>

<function-signature> int rollDice(java.util.Map) </function-signature>

voc est

395

operadores EL

E algu.,s outros operadores EL ...


Voc provavelmente no far (e nem deveria) clculos e utilizar lgica na EL. No se esquea de que o JSP a View e a tarefa da View devolver a resposta, e no tomar Decises Importantes ou efetuar Processamento Pesado. Se voc precisar de funcionalidade de verdade, esta uma tarefa para o Controlador e o Modelo. Se a funcionalidade exigida for menor, voc tem as tags customizadas (incluindo as tags JSTL) e as funes EL. Porm ... para os pequenos trabalhos, podemos precisar algumas vezes de alguma aritmtica ou um simples teste booliano. Portanto, olhando por este prisma, temos aqui os mais importantes operadores aritmticos, lgicos e relacionais da EL.

Aritmticos (5)
Adio: Subtrao: Multiplicao: Diviso: Resto:

Lgicos (3)
AND: OR: NOT:

&&eand
I1

! enot
VeJa 1&9!

e or

Relacionais (6)
Igual: Diferente: Menor Maior Menor Maior que: que: ou igual a: ou igual a:

==eeq !=ene <elt


>egt <= e le >=e ge

No use as palavras reservadas da EL como identificadores!

Vocj deve ter visto 11 delas nesta pgina _ as "palavras" alternati;a~ de al~ns 1~s operadores relacionais, IOglcos e antmetzcOS. Mas existem mais algumas: true uma literal booleana false
nuU

a OUTRA literal booleana significa ... nulo (reservada para "o futuro")

instanceof empty

um operador que checa se algo nulo ou vazio (por exemplo, $(empty A}) . retorna verdadeiro se Afor nulo. ou ~azlO (voc ver isto funcionando mms adzante neste captulo)

396 C8lJj'tulo 8

JSP sem scripts

Observe o cdigo servlet e descubra o que vai ser exibido ao lado de cada expresso EL. Voc ter que adivinhar algumas linhas, j que no vimos todas as regras possveis. Este exerccio vai te ajudar a entender como a EL se comporta. Dica: a EL flexvel e tem bom corao. Outra dica: as nove respostas corretas esto impressas abaixo, de cabea para baixo, mas NO esto em ordem. Pelo menos, se voc precisar mesmo de ajuda, elas esto a. E voc poder ir por eliminao para descobrir onde se encaixam.

Dado o cdigo servlet:


String num ~ "2"; request.setAttribute(~nQ~"r nQm); Integer i = new Integer(3); request.setAttribute("integer", i); java.util.ArrayList list = new java.util.ArrayList(); list.add("true") ; list.add("false"); list.add("2") ; list.add("la"); request.setAttribute("list", list);

o que

ser exibido em cada uma destas lacunas?


${num > 3} le 12} [integer] list["l"]

CPJSl"Jere 3ue a

classe

tLlJ bea'1

e a

Ir.m{i t"IlI-k)

t!s.f.';1J tL;'Sptin:vei's.

${integer

$ {requestScope ${list[a] ${num ${num

ne 4 and and true}

6 le num

I I false}

II

> integer} integer-l}

<jsp:useBean class~"foo.Dog" id~"myDog" > <jsp:setProperty name="myDog" property~"name" value="${list[l]}" /> </jsp:useBean> ${myDog.name $(42 div a} and true}

voc est aqui ~

397

operador EL res;posta'S

Ap9nte seu lpIS Resp9sta5


Dado o cdigo servlet:
String num = n2"; request.setAttribute(~num", num); Integer i ~ new Integer(3); request.setAttribute(~integer", i); java.util.ArrayList list ~ new java.util.ArrayList(); list.add(~true"); list.add(~false"); list.add(~2") ; list.add(~10") ; request.setAttribute(~list", list);

${num

> 3} 1e 12} . f"f'o. <l sel Vall:Jr [integer] ne Li and

${integer

atPJda/b valer de 'L'I-k5er eJ


6 1e num
...

I~t
fa1se}

$ {requestScope ${list[O]

II

I I 1ist[~1"]

and true} Vgtl se IIcce CCJ'lse511e J~sc(Jf;t'tr

f . lse

${num ${num

> integer} integer-1}

a ftlt'tl ff'oble~s

rl/ando vce

ibe~
e

I/StU'

....

devera

C<l~

Sfa"'fnci'a nc ex. ~e.

<jsp:useBean c1ass="foo.Dog" id="myDog" > <jsp:setProperty name~"myDog" property~"name" value="${list[l]}" /> </jsp:useBean> ${myDog.name ${42 div O} and true}

.51~ vc f<lde JeV~<l+tli

1/.$'41' V~4

iL den+r<l

398

JSP sem scripts

A EL trata os valores .,ulos graciosatMetrte


Uma deciso fundamental no projeto com que os desenvolvedores da EL se depararam foi tratar os valores nulos sem gerar excees. Por que? Porque eles pensaram que " melhor exibir uma pgina incompleta, do que exibir uma pgina de erro ao usurio". Considere que no exista nenhum atributo chamado "foo", mas que EXISTA um atributo chamado "bar", e que este "bar" no possua uma propriedade ou chave chamada "foo".

EL
${foo}

o que exibe
A EL aceIta 9 ze19. Ela
trata >/ql9tes desc9nbecld9s
${foo[bar] }

ou nu19s de a pfb1na mnda eXIbida, meSm9 se puder enc9nttar UIlla


7
AJ4S eXj>ress';es

${bar[foo] }

ser

${foo.bar}

${7 + foo}

pt9ptledade/lttibut9 n9me C,9n:~te na


41',--I-iO\-l-'-c4s;a

${7

foo)

Infinito

Na adtmtka.

a EL

-1-1"4-1-0. /liO\4 Vb.I'I-:'vel ${7 - foo}

>/aJ9t nu19 como Nas exptesses 19J;kas, a EL ttata 9 >/q]9t nu19 C9nJ9
~~ p.' '.. 1:CUS9 ~,

desctJJ'jt.ecMo. u u

CtliO\6

;e1"6
${7 % foo} Exceo

${7 < foo}

falso

${7

foo}

falso

${foo

foo}

verdadeiro

NAS eXj>l"essces
A

..., IC5i'cfJ.S; /
ctJiO\C 'a/se ,

L -I-I"a-l-b. "'iO\" val"l-:'vel u u

${7

!= foo}

verdadeiro

desctJJ'jt.ecMa

${true

and foo}

falso

${true

or foo)

verdadeiro

${not

foo}

verdadeiro

voc est

!P

399

EL reviso

Reviso da Expressiot1 Lat1guage (EU do JSP

p{unos DEBAil
As expresses EL esto sempre entre chaves e precedidas por um smbolo cifro ($): $ {expresso} . A primeira varivel nomeada na expresso ou um objeto implcito, ou um atributo em um dos quatro escopos (page, request, session ou application). O operador ponto permite que voc acesse os valores usando uma chave Map ou um nome de propriedade bean. Por exemplo, ${foo.bar} fornece o valor de bar, onde bar O nome da chave Map no Map foo, ou bar propriedade do beanfoo. O que vier direita do operador ponto, deve seguir as regras normais de nomenclatura lava para os identificadores! (Ou seja, devem comear com uma letra, um underscore ou o smbolo cifro, podendo incluir nmeros depois do primeiro caractere e nada mais, etc.) Voc NUNCA pode colocar nada direita do ponto que no seja vlido como identificador lava. Por exemplo, voc no pode dizer $ {foo.1}. O operador [] mais poderoso que o ponto, pois permite que voc acesse arrays e Lists, e coloque expresses incluindo variveis conhecidas dentro dos colchetes, alm de permitir aninh-Ios em qualquer nvel que voc queira. Por exemplo, se musicList uma ArrayList, voc pode acessar o primeiro valor na lista dizendo $ {musicList[O]} OU $ {musicList["O"]}. A EL no liga se o ndice da lista vier entre aspas. Se o que estiver dentro dos colchetes no vier entre aspas, o Container avalia. Se estiver entre aspas e no for um ndice dentro de um array ou List, o Container ir enxerg-Io como o nome literal de uma propriedade ou chave. Todos os objetos implcitos da EL so mapeamentos, exceto um. Atravs dos objetos implcitos de mapeamento voc pode obter os atributos de qualquer um dos quatro escopos, dos valores dos parmetros da solicitao, valores do header, dos cookies e dos parmetros init de contexto. O nico objeto implcito no-mapeamento o pageContext, que uma referncia ao ... objeto PageContext. No confunda os objetos implcitos de escopo da EL (os mapeamentos dos atributos) com os objetos com os quais os atributos so ligados. Ou seja, no confunda o objeto implcito requestScope com o objeto implcito request do JSP em si. A nica maneira de acessar o objeto request atravs do objeto implcito pageContext. (Embora parte do que voc queira da solicitao j esteja disponvel por intermdio de outros objetos implcitos da EL, como o param/paramValues, header/ headerValues e cookie.) As funes EL permitem que voc chame um mtodo esttico pblico em uma classe Java simples. O nome da funo no precisa coincidir com o nome do mtodo em questo! Por exemplo, ${foo.roUItO}no significa que deve ter um mtodo chamado roUItO numa classe que tenha uma funo. O nome da funo (por exemplo, roUItO) mapeado para um mtodo esttico verdadeiro, usando um arquivo TLD (Tag Library Descriptor). Declara uma funo usando o elemento <function>, inclusive o <name> da funo (rollltO), o <function-class> totalmente qualificado e o <function-signature>, que inclui o tipo do retomo, bem como o nome do mtodo e a lista de argumentos. Para usar uma funo no JSP, voc deve declarar o namespace usando uma diretiva taglib. Inclua um atributo inicial na diretiva taglib, para informar ao Container o TLD no qual a funo que voc est chamando possa ser encontrado. Exemplo:
<%@ taglib prefix~"mine"

uri=" /WEB-INF/foo. tld"%>

400

capI'tuloB

JSP sem scripts

est

401

layout emplates

Os pedaos reutilizveis do tetMplate


Voc tem headers em cada pgina do seu site. Eles so sempre os mesmos. Voc tem o mesmo footer em todas as pginas tambm. Seria muita tolice criar as mesmas tags para os headers e footers em cada JSP da sua aplicao, no seria? Se voc est pensando como um programador Java (que voc certamente ), sabe que fazer isso como dispensar todas as funcionalidades 00. A sensao de ter todos aqueles cdigos duplicados provavelmente o enlouquece. O que acontece se o designer do site fizer, digamos, uma singela alterao no header ou no footer? Voc ter que replicar esta mudana em todos os lugares. Relaxe. Existe um recurso para cuidar disso no JSP chamado include. Voc escreve o seu JSP normalmente; porm, em vez de colocar o trecho que se repete explicitamente dentro do JSP que voc est criando, voc manda o Container incluir o outro arquivo na pgina existente, no lugar que voc escolher. como dizer: <html><body> <!--insira o arquivo header aqui--> Bem-vindo ao nosso site ... Bl, bl, bl, mais cdigo aqui ... <!--insira o arquivo footer aqui--> </body></html> Nesta sesso, ns veremos dois mecanismos de include diferentes: a diretiva include e a ao-padro <jsp:include/>.

402

JSP sem scripts

A diretiva it1clude
A diretiva inc1ude diz ao Container o seguinte: copie tudo do arquivo includo e cole neste arquivo, bem aqui ...

Arquivo header padro ("Header.jsp")


<html><body> <img src~"images/Web-Services.jpg" <em><strong>We know how to make </body></html> > <br> SOAP suck

less.</strong></em>

<br>

We kJIOW how to make SOAP Sllck less.

o JSP da aplicao
<html><body> <%@ <br> include

("Contact.jsp")

file="Header.jsp"%>

<em>We can help.</em> <br><br> Contact us ato ${initParam.mainEmail} </body></html>

We /aww

llOW

to make SOAP Sllck less.

We can help. Contact tiS at: likewecare@wickedlysmart.com

voc est

403

<jsp:include>

A aeo~padro <jsp:it1clude>
A ao-padro <jsp:include> aparece para fazer o mesmo que a diretiva include.

Arquivo header padro ("Header.jsp")


<html><body> <img src~"images/Web-Services.jpg" <em><strong>We know how to make </body></htrnl> > <br> SOAP suck

less.</strong></em>

<br>

We

bow how to mL1ke SOM suck less.

Um JSP da aplicao ("Contact.jsp")


<html><body> <jsp:include <br> <em>We can help.</em> <br><br> Contact tiS at: ${initParam.mainEmail} </body></html> page="Header.jsp"

We

know how to mL1ke SOAP suck less.

We can help. Contact tiS at: likewecare@wickedlysmart.com

404

JSP sem scripls

Eles NO so os l\1esl\10S ...


A ao-padro <jsp:include I> e a diretiva include parecem idnticas, e geralmente do o mesmo resultado, mas d uma olhada nos servlets gerados. Ns tiramos este cdigo direto do mtodo jspServiceO do cdigo servlet gerado do Tomcat ...

Cdigo servlet gerado para o arquivo header


out.write(~\r<html>\r<body>\r<img <br>\r<em><strong>We know how </body>\r</html>\r"); src=\"images/Web-Services.jpg\" > to make SAP suck less.</strong></em> <br>\r\r

Servlet gerado para o JSP usando a diretiva include


.s+e +I"ect.4 e~ ~er'-+c
out.write(~<html><body>\r");

: .><A-rA-M..lJr.

~fl41 44 5ei"4ti4 pela p:'li7a Heatlel"jsp,


out.write(~\r<html>\r<body>\r<img <br>\r<em><strong>We know how </body>\r</html>\r"); src=\"images/Web-Services.jpg\" > to make SOAP suck less.</strong></em>

<br>\r\r

out.write(~\r<br>\r\r\r<em>We can help.</em> <br><br>\r\rContact us at: ~); out.writejava.lang.String) org.apache.jasper.runtime.PageContextImpl. proprietaryEvaluate(~${initPararn.rnainErnail}",java.lang.String.class, (PageContextl_jspx_page_context, null, false); out.write(~\r\r\r</body></html>");

A- tltre+tv4 HeQder jsp I}AJrS

'i7cltltie i"e-hra. 6 Ci1+e,ftlc d Qr311tv e C/(JCQ 174 P~/i7Q C.a~+4C+js p

Si/e eS+4 laS4

+nduy.

Servlet gerado para o JSP usando a ao-padro <jsp:include I>


out.write(~<html><body>\r"l;

A-i/t

tlllel"e"t+e!

() "I"ulV(J(Jl"ij'i74! HelJ.tlel"jsp

V4t

den+-I" d servle+
org.apache. jasper.runtime.JspRuntimeLibrary.include

5en.tl(J. .~ ve; dts s(J; -h1"tclim4 C(J""'''1I~4

espcle de Ct,4~4dlJ. tie I"lIP/+,w.e


(reques t, response, ~Header.jsp", out, false);

out.write(~\r<br>\r\r\r<em>We can help.</em> <br><br>\r\rContact us at: ~); out.writejava.lang.String) org.apache.jasper.runtime.PageContextImpl. proprietaryEvaluate(~${initParam.mainEmail}", java.lang.String.class, PageContext) jspx_page context, null, false)); out.write(~\r\r\r</body></html>");

voc est aqui.

405

d/retive /nclude VS, ao-padro

A diretiva include acotttece no tltotltettto da traduo


O

<jsp:include> acotttece no yunntlte

Com a diretiva include, NO h diferena se voc abrir sua pgina JSP e colar o contedo do "Header.jsp". Em outras palavras, isto to dificil quanto voc duplicar o cdigo do arquivo header no seu outro JSP. Apenas o Container faz isso para voc no momento da traduo, para que voc no precise duplicar o cdigo em todo lugar. Voc pode escrever todo o seu cdigo com uma diretiva include, e o Container vai se encarregar da tarefa de copiar o cdigo header dentro de cada JSP, antes de traduzir e compilar o servlet gerado. Mas, com o <jsp:include> a histria completamente diferente. Em vez de copiar o cdigo-fonte do "Header.jsp", a ao-padro include insere a resposta de "Header.jsp" no runtime. O mais importante para o <jsp:include> que o Container esteja criando um RequestDispatcher do atributo da pgina e aplicando o mtodo includeO. O JSP despachado/includo roda sobre os mesmos objetos request e response, dentro da mesma thread.

r:

Ento por que voc no usa sempre o <jsp:include>? Desta forma, voc pode garantir que ter sempre contedo atualizado?

r:
I\:

Eu tentei isso no Tomcat: criei um HTML esttico e o inclu com a diretiva. Em

Existe um problema extra de performance a cada <jsp:include>. Por outro lado, com a diretiva, o problema s acontece uma vez - quando a pgina includa traduzida. Portanto, se voc est seguro de que no ambiente de produo o seu arquivo no vai mudar, a diretiva pode ser a soluo. claro que ainda existe o problema de que a classe servlet gerada torna-se um pouco maior quando voc usa a diretiva.

I\: Pense nisso.

seguida, alterei o HTML, sem redistribuir nem nada, e.a sada do JSP reproduziu a alterao. Portanto, se este for o caso, quando usarei ento o <jsp:include>?

Ahhh ... voc tem um Container gente boa (Tomcat 5). Sim, a maioria dos Containers atuais tem uma forma de detectar quando os arquivos includos sofreram alteraes, e eles refazem a traduo perfeita do arquivo includo e tudo mais. O problema que A ESPECIFICAO NO GARANTE ISSO! Ento, se voc escrever um cdigo que dependa disso, sua aplicao no vai, necessariamente, ser compatvel com outros Containers.

406

JSP sem scripts

A diretiva it1clude t1a prh\teira solicitao


Com a diretiva include, o Container tem bastante trabalho a fazer, mas apenas na primeira solicitao. A partir da segunda solicitao, no existir mais sobrecarga no runtime. faz uma solicitao ao Contact.jsp que ainda no foi traduzido . O Container l a pgina Contact.jsp para dar incio ao processo de traduo.

o cliente

u\\jO

. solicita o Contact.jsp

(e, ~

Container

O Container v a diretiva include, mistura o cdigofonte de Header.jsp e Contact.jsp, e cria/traduz o resultado num arquivofonte lava para o servlet gerado. Header.jsp

e
Compila para Contaet -Jsp.c1ass Contaet -Jsp.java Contamer

Contaet.jsp

Header.jsp

O Container compila o arquivo-fonte traduzido em uma classe servlet. At aqui, um servlet como outro qualquer, e o passo anterior no ocorrer novamente, a menos que o Contact.jsp seja alterado (ou caso seu Container seja inteligente o suficiente para detectar que o Header.jsp includo sofreu alterao) . Para concluir a solicitao, o Container carrega a classe recm-compilada, inicializa o servlet (instancia o servlet e chama initO no novo objeto), aloca uma thread para a solicitao e chama o mtodo jspServiceO. A partir da segunda solicitao, o Container s realizar o passo (C): alocar uma thread e chamar o mtodo jspServiceO. voc est
ll>

Contact.jsp

407

a ao padro <jsp:nclude>

A ao-padro <jsp:it1clude> t1a pritMeirasolicitao

o
solicita,Q CO,ntact.jSp
\O""

.~o Af'\'
.

I ...

,GET

~cm

I~

. ..

o cliente faz uma solicitao ao Contact.jsp que ainda no foi traduzido. O Container l a pgina Contact.jsp para dar incio ao processo de traduo.

Contact.Jsp

Container Cliente Header.jsp compila para O Container v a ao-padro include e utiliza-a para inserir uma chamada a um mtodo no cdigo do servlet gerado que, no runtime, combinar Contact -Jsp.c1ass dinamicamente a resposta vindo do Header.jsp, com a resposta vinda do Contact.jsp. O Container gera servlets para ambos os JSPs. (Isto no determinado pela especificao, portanto, estamos apenas mostrando um exemplo de como isso funcionaria.) O Container compila o arquivofonte traduzido em uma classe servlet. At aqui, um servlet como outro qualquer. O arquivo de classe do servlet gerado carregado na NM do Container e inicializado. Em seguida, o Container aloca uma thread para a solicitao e chama o mtodo jspServiceO do JSP.

Contact -Jsp.java Contact.jsp Container

Header.jsp

compila

Header.jsp

Contact-Jsp.java Contact-Jsp.c1ass

RequestDispatcher

O servlet Contact atinge o mtodo que faz o include dinmico e algo acontece (dependendo do fabricante)! Tudo com que devemos nos preocupar se a resposta gerada pelo servlet Header esteja combinada com a resposta do servlet Contact (no local apropriado). (NO MOSlRADO: em algum momento, o Header.jsp traduzido e compilado, e a classe do servlet gerado carregada e inicializada.)

408

cap,ftu/o

JSP sem scripts

Os nomes dos atributos para a diretiva include e <jsp:include/> so diferentes


Guarde isto! Observe os atributos para os dois mecanismos de include ... o que est diferente?
<%@ include <jsp:include file=IfHeader.jsp"%> page="Header.jsp" I>

A diretiva include

sensvel localizao!
E e~ta... a NICA diretiva para a qual a pos:a~ no JSP realmente faz dijrena. A dlretzva page, por exemplo, pode ser colocada em qualquer lugar na pgina, embora, por conveno, a maioria das pessoas coloque as diretivas page no topo.

Sim! O atributo da diretiva file, mas o atributo da ao-padro page! Para ajud-Io a memorizar, a diretiva include <%@ includefile="foojsp"%> usada apenas no momento da traduo (assim como Mas a diretiva include informa ao todas as diretivas). E no momento da traduo, o Container exatamente ONDE inserir Container s se preocupa com files - jsp para java, e afonte do arquivo includo! Por java para .class. exemplo, se voc estiver incluindo Porm, a ao-padro <jsp:include page= "joojsp">, bem como todas as aes-padro, roda no momento da um cabeal~o e um roda p, o cdigo solicitao, quando o Container est preocupado com parecer-se-a com o seguinte: as pages que sero executadas.

f:

<htrnl><body> <%@ include <em>We Contact file="Header.html"%> <br><br> <br>

O JSP que foi includo pode possuir seu prprio contedo dinmico? Em seus exemplos, o HeaderJsp poderia ter sido tambm uma pgina esttica Header.htmn

<br>

can help.</em>

1\: Sendo um JSP, sim, ele pode ser dinmico (mas voc est certo, no nosso exemplo poderiamos ter colocado o
headerem uma pgina esttica HTML e teria funcionado exatamente da mesma forma). Mas existem algumas pequenas limitaes: uma pgina includa NO PODE alterar o cdigo do status da resposta, nem criar headers (o que significa dizer que ele no pode, digamos, chamar o addCookies()). Voc no receber um erro se o JSP includo tentar fazer algo que ele no possa. Voc simplesmente no ter aquilo que solicitou.

us at: ${initParam.mainEmail} file="Footer.html"%>

<%@ include

</bodY></htrnl>

Is+()

f:

(aJ'!+es as +lJ.js
...

Mas, se o que foi includo for dinmico, e se voc estiver usando adiretiva include esttica, isto significa que a parte dinmica ser calculada uma nica vez?

+eltl

3i/e

Vlf" J'!() f"()o/'

seu

f()f"

aI 3lJe lI()ce 3f1ell'a 3V(, o/'tu'eSIl.

~I!)-I-et".t.+1tI1 de.

1\: Vamos imaginar que voc inclua um JSP que possua


uma expresso, que chama a funo ro/Ift, que gera um nmero aleatrio. Lembre-se, com a diretiva include, essa expresso EL simplesmente copiada para dentro do JSP incluido. Assim, cada vez que aquela pgina for acessada, a expresso EL roda e um novo nmero aleatrio gerado. Pense assim: com a diretiva include, a fonte da parle includa torna-se PARTE da pgina com a diretiva include.

J5~ ltI.t'"$e.s <>1'"$


e

s'e. c()ltI!n"J'lb.1.e.sel>\ ttl>\ll it".l1de p~;"J'la

A PJ5IAD FAz !JIFJe.IJIt!


IJIl+ut"o.lltle~

J '"

a SSP:I"J'lc!ttJe> rAA-18fA-1

~ SfJ'!swel e.QlIi() J"

a l'"slf"") ('ltIb,,!"t< t'"$+ srJa 1>\0.1'"$ dtl'e-I-flla fi. P~/'J'!fJ..

3(.1(' ,.

voc est aqui...

409

componentes reutiizveis

OL! Voc OLHOU direitinho o cdigo do servlet gerado para a diretiva include? Ns temos HTML aninhado e tags BODY! Isso est errado e feio.

HUtH. Ela tetH razo ...


Pense no que fizemos. Construmos uma pgina para o header, "Header. jsp". Era um belo JSP sozinho, completo, com seus BTML de abertura e fechamento e suas tags BODY Em seguida, criamos o "Contact,jsp", o qual tinha, tambm, lindas tags para abertura e fechamento. Bem, ns havamos dito que quecom existe no arquivo includo copiado dentro datudo pgina o include? Isso significa tudo. (praticamente) para O cdigo abaixo, do porque servlet gerado, NO funciona em todos os browsers. Funcionou no nosso demos sorte.
out. write ("<html><body>\r"); out. write ("\r<html>\r<bodY>\r ~<img src=\"images/web-services.jpg\" <br>r<em><strong>We know how to make </strong></em> <br>\r\r > SOAP

suck

less.

</bodY>\r</html>\r") ;
can help.</em> us ato "); org.apache.jasper.runtime.

out.write("\r<br>\r\r\r<em>we <br><br>\r\rcontact out.write((java.lang.String)

pagecontextlmPl.proprietarYEValuate("${initparam. mainEmail)", java.lang.String.class, pageCoDtext)_jspx_page_context, aut. write null, false;

("\r\r\r</bodY></html>,,);

410

cap,!w/o 8

JSP sem scripts

A IMat1eira COlMOUEVERAMOS ter feito

isso

Aqui ns removemos as tags de abertura e fechamento dos arquivos includos. Isto significa que os arquivos includos no podero mais gerar pginas HTML sozinhos. Agora, eles dependem de serem includos em alguma parte mais importante. Algo com as tags <html><body> e </body></html>. Mas esse o problema, voc est criando estes pedaos reutilizveis para que voc possa definir layouts a partir de pedaos menores, sem precisar duplicar o cdigo na mo. Estes blocos reutilizveis no devem viver sozinhos.

O arquivo Header ("Header.jspf")

<imd src="images/Web-Services.jpg" <em><strong>We know how to make

> <br> SOAP suck

less.</strong></em>

<br>

Contact.jsp
<html><body> <%@ include file="Header.jsp"%> <br>

<em>We can help.</em> <br><br> Contact us at: $ {initParam.mainEmail} <%@ include file="Footer.html"%>

</body></html>

o arquivo

Footer ("Footer.html")
page</a>

<a href="index.html">home

~s+e

1"~C!.It"S{j Gl~ I"~"I>\"VE'I"

se apltctJ. ti

"s "I>\~Cb.#ii"s"l>\{j$ Gle l"i1c!tlGle:


WecanhelP.~8
.

tiS at: hkewecare@

<gsP;I"i1c!tIe>

e Glll"e-hv

l"i1cltlGle

e
voc est

411

usando <jsp:param />

Custoittizattdo

O cottfedo ittCIUdoCOitt<jsp:paraitt>

Tudo bem, voc tem um header que deve aparecer sempre igual em cada pgina. Mas e se voc quiser customizar parte do header? E se voc quiser, por exemplo, uma legenda sensvel ao contexto que seja parte do header, mas que seja alterada de acordo com a pgina? Voc tem algumas opes. A maneira pouco inteligente: coloque a informao da legenda na pagina principal. Ou seja, a primeira coisa na pgina depois do include para o header. A maneira inteligente: passe a informao da legenda como um novo parmetro de solicitao para a pgina includa! Porque assim legal: se a informao da legenda deve fazer parte do header, mas um trecho que muda, voc ainda deseja que a parte header do template decida como aquela legenda deva aparecer na pgina resultante. Em outras palavras, deixe que a pessoa que criou o header decida como a legenda dever ser exibida!

o JSP

que faz o include

<html><body>

r~~~~~ Observe . sell'\ baNa


~~

de lect.ti.lI'\e-rf,,!

<jsp:include page="Header.jspf" > <jsp:param name="subTitle" value="We </ jsp :incl ude>

take

the sting

out of SOAP."

/>

<br> <em>Web Services Support Group.</em> Contact us at: ${initParam.mainEmail} </body></html> <br><br>

o header includo que USA o novo param ("Header.jspf")


<img src~"images/Web-Services.jpg" > <br> <em><strong>${param.subTitle}</strong></em>

<br>

Pal'a " fJ.1'1ptv" ';"c1V:"'''; (; "(U'~e+I'(;

c'1lljvl"a Cll'\

<js":,,al'fJ.lI't> ~ C"1I'\66lu A-L.6lllJe. tlf./+I''' "fJ.I"~e+1'6 slte"+"-i;'"

A-3v,~ es.ffJ.II't"s f/StI.'1 a L. pal'a ,,!J';';-16,

AJtl.ftl.: " C6l'1Cet.ftli! "tl.l'all'ts 1'1";'" ItI.; Si!~" Cll't il'e-/lvIJ. l;"c!lIf?
fJ.

've ;;';IJ l;"~lca)~


se ~/lc4 A-PAJJ,S <jsp:tJ1dvtie>.

P61".f41'/.fo; ele ~ 41';1J-,,41''';6

412

capi;tulo 8

JSP sem scripls

A ao~padro <jsp:forward>
Voc PODE encaminhar de um JSP para outro. Ou de um JSP para um servlet. Ou de um JSP para qualquer outro recurso na sua aplicao. claro que nem sempre voc desejar fazer isso em produo, pois se voc estiver usando o MVC, a View vai ser a View! E a View no controla a lgica. Ou seja, no deveria ser tarefa da View descobrir se o visitante est logado ou no. Outro indivduo (o Controlador) deveria ter tomado essa deciso antes de fazer o forward para a View. Porm, vamos ignorar por enquanto todo esse coerente julgamento do MVC, e ver como poderamos ter feito isso se tivssemos que enviar de uma pgina JSP para outro elemento. Por que se preocupar se voc jamais far isso? Bem, voc pode se deparar algum dia com um problema para o qual o <jsp:forward> possa ser uma boa soluo. Alm disso, como em muita coisa aqui no livro (e na prova), o uso do <jsp:forward> est ai Escondido em zilhes de JSPs que voc possa estar mantendo um dia (ou, de preferncia, recriando).

voc est aqui ~

413

usando <jsp:forward />

Imagine que voc um JSP sendo chamado para uma solicitao que inclui o parmetro userName. J que voc est esperando por aquele parmetro, voc quer checar primeiro se este parmetro no nulo. Se no for, sem problemas, conclua a solicitao. Mas se o parmetro userName for nulo, voc quer parar por aqui e entregar toda a solicitao a outro indivduo - como um outro JSP que solicitar o userName. Por enquanto, sabemos que isso possvel com scripting:

J5P com um encaminhamento condicional (Hello.jsp)


<html><body> Welcome to our page! <% if (request.getParameter("userName")

</body></html>

J5P para o qual a solicitao

encaminhada

(Handlelt.jsp)

<html><body> We're sorry ... you need

to log in again.
J' J'

<form action="Hello.jsp" method="get"> Name: <input name="userName" type="text"> <input name="Submit" type="submit"> </form> </body></html>

"IfJl.Ja ~a"s e J lle V~4 PlJ.jtFtfJI.

receite

<)

IFtpV+

J lISlI:riC

.Ia St:I/ict+IJ.,/.t:I e; e~
Sf511i'JfJ.j (!

JsP ave fJl.cdlJ.~(!S Je

ver ..lfe!l6dsp.

414

JSP sem scripts

C0t\10 fut1ciot1a ... Na primeira vez que voc solicita o Hello.jsp, o JSP faz o teste condicional, descobre que no h valor para userName e encaminha para o HandleIt.jsp. Considerando que o usurio tenha digitado um nome no campo name, a segunda solicitao no far o encaminhamento, j que o parmetro userName possui um valor no-nulo.

Primeira solicitao para o Hello.jsp

We're sorry ...you need to log in again. Name:1 Johannes 1~~mtiB>

Segunda solicitao para o Hello.jsp

Welcome to OUI page! Hello Johannes

Como pode a frase "Welcome to our page!" no ter aparecido na primeira vez?

voc est

415

~~"'!~~'N'~i';,,,.,;,.,,'.:-

.~

<jsp:forward I> ao-padro

COtM O <jsp:forward>, do encatMinhatMemo

O buffer

IitMpO ANfES

Quando ocorre um encaminhamento, o recurso para o qual a solicitao foi encaminhada inicia com o buffer limpo para respostas! Logo, aquilo que foi escrito na resposta antes do encaminhamento descartado.

N9 ex1stfi'm

Yetguntas ldl9tas

f:

Isto faz sentido se a pgina estiver bufferizada ... pois o que voc escrever ser enviado ao buffer, e o Container apenas ir limp10.Mas, e se voc mandar a resposta ANTES de fazer o encaminhamento? Por exemplo, o que acontece se voc escrever algo e, em seguida, chamar o flushO no objeto out?

NADA d9 'Lue -Y9oo escte-yet ~ d9 encamlnhament9 apateoot, se ele t9t teallz.ad9.

F\: Tudo

bem, sabemos que voc est perguntando isso por simples curiosidade, j que isto seria um extremo absurdo e completamente sem sentido. Mas voc sabe disso.

Mas voc tambm sabe que coisas extravagantes podem cair na prova, j que aquele seu colega de trabalho preguioso pode incluir uma maluquice dessas no seu cdigo. Porm, voc j deve saber a resposta. Se voc escreve algo como:
<html><body> Welcome to our page! <% out.flush(); %> <% if (request.getParameter("userName") null) { %> <jsp:forward page="HandleIt.jsp" <% } %> HelIo ${param.userName} </body></html>

/>

o Container

envia, com obedincia, a frase "Welcome to our page!" como resposta e s ento v o que foi encaminhado. Xi! J era. E um IlIegalStateException ocorre. Contudo, ningum v a exceo! O cliente v simplesmente 'Welcome to our page!" ... e nada mais. O forward envia uma exceo, mas j tarde para o Container reter a resposta, e o cliente v que recebeu o flush e pronto. O forward e o resto da pgina atual no acontecem. Fim de papo para aquela pgina. Por isso, nunca faa um flush-e-forward!

416

C8m'tulo 8

JSP sem scrpts

Ela no conhece as tags JSfL


Quando voc precisar de mais funcionalidade, algo alm do que voc conseguiria com as aes-padro e a EL, voc no tem que recorrer a scripting. No prximo captulo, voc aprender a usar a JSP Standard Tag Library 1.1 (JSTL 1.1), para fazer tudo o que voc pode precisar, usando uma combinao de tags e EL. Aqui, daremos uma rpida olhada em como faramos nosso encaminhamento condicional sem scripting.
%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" <html><body> Welcome to our page! "'--Jec!'lf'a vIOla dlf'e+-illfl. +-tJjllb

IS+-tJ
Si//; s-I-l-l-i/l e

ave

/ "\ 1.da f"lOIe a !;lbllc-n::c'l

tJf,Je

ffSff li de
SCf"'lp-l-!e-l-.

i<C:if
HelIo

<jsp:forward page="Handlelt.jsp" /> </c:if>test="${empty param.userName}" > $ {param.userName}

as +-tJ.is se tfC"W/-I"tJ.IOI.

A-PNM,:st-l-e lIeCpf'Vfl.lle1IOleP'1 -n:: ,

</body></html>

capa; de fa;e . ls-I-o /lIJ'J(;;it:.I1f1. J lIc I1';C p6S$lIl Jsrt- 1111. SlIl1. apltcl1.li,).
hN!IOICS

tsse 116 pl':.lflIOl6

voc est aqui ~

417

bean ao-padro

Reviso - aes~padro relacionadas ao bean

A ao-padro ~sp:useBean> define uma varivel que possui uma referncia ou para um atributo bean existente, ou, caso o bean ainda no exista, um novo bean. O ~sp:useBean> TEM QUE ter um atributo "id", que declara o nome da varivel que ser usada neste JSP para se referir ao bean. Se voc no incluir um atributo "scope" com a ~sp:useBean>, o escopo ser page por padro.

O atributo "class" opcional e declara o tipo da classe que ser usada, caso um novo bean seja criado. O tipo tem que ser pblico, no-abstrato e possuir um construtor-padro pblico. Se voc colocar um atributo "type" em <jsp:useBean>, bean aceite a converso. ele tem que ser um type para o qual o

Se voc tiver um atributo "type" e NO tiver um atributo "class", o bean j dever existir, j que voc no especificou o tipo da classe que deveria ser instancia para o novo bean. A tag <j sp:useBean> pode ter um corpo, e tudo que existir no corpo rodar APENAS se um novo bean for criado como resultado de <jsp:useBean> (o que significa que nenhum bean com aquele "id" foi encontrado no escopo ou padro especificado). A principal tarefa do <jsp:useBean> <j sp: setProperty>. configurar as propriedades do novo bean, usando

O <jsp:setProperty> deve ter um atributo "name" (que deve coincidir com o "id" do <jsp:useBean e um atributo "property". O atributo "property" deve ser o nome real da propriedade ou o asterisco (*). Se voc no incluir um atributo "value", o Container s configurar o valor da propriedade se existir um parmetro de solicitao com um nome que coincida com o nome da propriedade. Se voc usar o asterisco (*) no atributo "property", o Container ir atribuir o valor de todas as propriedades que possurem um parmetro de solicitao com este nome (outras propriedades no sero afetadas). Se o nome do parmetro da solicitao for diferente do nome da propriedade, e voc quiser configurar o valor da propriedade igual ao valor do parmetro da solicitao, voc pode usar o atributo "param" na tag <jsp:setProperty>. Se voc especificar um atributo "type" em <jsp:useBean>, voc poder especificar propriedades em <jsp:setProperty> SOMENTE nas propriedades do "type", mas NO naquelas que s aparecem no tipo verdadeiro da "class". (Ou seja, as regras de polimorfismo e Java se aplicam.) Os valores das propriedades podem ser Strings ou primitivas, e a ao-padro <jsp:setProperty> far as converses automaticamente.

418 capjrtulo 8

JSP sem scripts

Reviso - o it1clude

r~~~->-o>~~--P.ONTI~SDE BALA'
Voc pode criar uma pgina com componentes reutilizveis, usando um dos dois mecanismos de include: a diretiva include ou a ao-padro <jsp:include>. A diretiva include faz a incluso no momento da traduo, apenas uma vez. Portanto, a diretiva include considerada o mecanismo apropriado para incluso de contedo que possivelmente no mudar aps a distribuio. O que a diretiva include faz copiar tudo de dentro do arquivo includo e colar na pgina que contm o include. O Container mescla o contedo dos arquivos includos e compila apenas um para o servlet gerado. No momento do runtime, a pgina com o include roda exatamente como se voc tivesse digitado todo o contedo da origem em um nico arquivo. A ao-padro <jsp:include> inclui a resposta da pgina includa na pgina original, no momento do runtime. Por isso, a ao-padro include, ao contrrio da diretiva, considerada adequada para a incluso de contedo que possa ser alterado aps a distribuio. Ambos os mecanismos podem incluir elementos dinmicos (cdigo JSP com expresses EL, por exemplo), assim como pginas HTML estticas. A diretiva include a nica diretiva sensvel posio. O contedo includo inserido na pgina no local exato da diretiva. Os atributos para a diretiva include e a ao-padro include recebem nomes distintos: a diretiva usa "file" como atributo, e a ao-padro usa "page". Em seus componentes reutilizveis, certifique-se de remover as tags de abertura e fechamento. Seno, o resultado ter tags de abertura e fechamento aninhadas, as quais nem todos os browsers podem tratar. Crie e construa seus blocos reutilizveis, ciente de que eles sero includos/inseridos em algum lugar. Voc pode personalizar um arquivo includo configurando (ou substituindo) um parmetro de uma solicitao, usando a ao-padro <jsp:param> dentro do corpo da <jsp:include>. Ns no mostramos isso neste captulo, mas a tag <jsp:param> tambm pode ser usada dentro da tag <jsp:forward>. OS NICOS lugares onde faz sentido incluirmos uma <jsp:param> so, ou dentro da <jsp:include>, ou dentro da <jsp:forward>. Se o nome do param usado em <jsp:param> j tiver um valor como parmetro de solicitao, o novo valor ir sobrescrever o anterior. Ou ento, um outro parmetro de solicitao ser adicionado solicitao. O recurso includo tem algumas limitaes: ele no pode alterar o cdigo de status da resposta e nem configurar headers. A ao-padro <jsp:forward> encaminha a solicitao (como se fosse um RequestDispatcher) para um outro recurso na mesma aplicao web. Quando acontece um encaminhamento, o buffer da resposta limpo antes! O recurso para o qual a solicitao foi encaminhada inicia com uma sada limpa. Portanto, tudo o que foi escrito na resposta antes do encaminhamento ser descartado. Se voc processar a resposta antes do encaminhamento (chamando out.flushO, por exemplo), o cliente receber aquilo que foi alvo do flush, mas assim rn?'crnr. O encaminhamento no acontecer e o restante da pgina no ser processado.

voc est

. 419

respostas

dos exerccios

SEJA 9 C91ltalnet
I\esp9sta5
Ai+a: /tallt HIYt~ c/ass;
fI

IJIYt .fy>e; lYtas ~t~t,Vbl


1Ib1

I's+" AiPreJ tspeci'ltca alie ele 1st< ftlje.

esc"p". O

3ve Observe esta ao-padro:

Sij"t"li'ctI.

<jsp:useBean id="person" type="foo.Employee" scope="request" > /> <jsp:setProperty name="person" property="name" value="Fred" sp:useBean > Name is: <jsp:getProperty name="person" property="name" />

O COJe.PeJ p/vp/caNula!':! Ai'; fJ.,Ji'ap/+a et;lceOi!'VIII eCl'fc ,Jen+I"IJ Je lIlIItl <jSf:vse$eal'/>; "-Se che:'(J,f"blS' a+ a'l/II~ lrebltJ$ exlbi'r ivfJ.I'I.

+tlj

se lIc

o que acontece
foo.Person

se o cdigo do servlet se parecer com:

+rllfIl' VIII ~7F'e e nenhYIII elas s! I-elll!lre- se;


,Ji/.
IJ

p = new foo.Employee();

c(Jf"p" se

+a; r(J,Ja.PrPAiPrS

p.setName(~Evan") ; request.setAttribute(~person", p);

n<>V<I belVl; ffJt' cl'ra.,J" 1111I acol"t'er

apel'li/.SlJlII (sebl dus;


/1.11'

Jec!f),f"(J,J

o que acontece
foo.Person

se o cdigo do servlet se parecer com:

p = new foo.Person();

Person String getNameO void setName(String)

p.setName(~Evan"); request.setAttribute(~person", p);

Ala verJaJe;

esH

servle-!-

J: e!'l'tJ "li/. c{JWtpllafl(j.IJ~s


.5~;;;

-!-rtAf'aceallls lJbI fI.lC<l;pats es-!-a &lIes+';" es-!-: blai"spaf'a C01.4PIl-/}/Jo}e.; !J.bs+rfJ;+a e for
t'1II

ve; Je S~IA CJ?+at"'ier.A-,1<!rtJ.., -hu:;,Pef'SM


1'1';"

i'ss

f(J,Jf!blDS t"'is+al'lcl-t.-/a.

Employee int getEmpIDO void setEmpID(int)


A-lIIbfJ.S tlS ela$SU
IV // /,

es+(J.{J PIe. p(J,C<lH f<ltJ

420

capitulo 8

JSP sem scripts

Yausa pata 9 cat

1Dado um formulrio

HTML que usa checkboxes para permitir que o usurio selecione diferentes valores para um parmetro chamado hobbies. Quais expresses EL calculam o primeiro valor do parmetro hobbies? (Escolha todas as que se aplicam.)

DA.

${param.hobbi.es} ${paramValue.hobbi.es} ${paramValues.hobbi.es[O]} ${paramValues.hobbi.es[l]} $ {paramValues $ {paramValues [hobbi.es] [O]} [hobbi.es] [I]}

DB.

O c.
DD. DE.

OE
2

Considerando uma aplicao que guarde o endereo de correio eletrnico do webmaster no parmetro de inicializao do contexto do servlet chamado maser-email. Quais ativam tal valor? (Escolha todas as que se aplicam.)

o A.
DB.

<a href='mai.lto: $ {i.ni.tParam.master-emai.l} '> emai.l me</a> <a href='mai.lto:${contextParam.master-emai.l}'> emai.l me</a> <a href='mai.lto:${i.ni.tParam['master-emai.l']}'> emai.l me</a> <a href='mai.lto:${contextParam['master-emai.l']}'> emai.l me</a>

O C.
DD.

voc est aqui

li>

421

teste

3 Dada a seguinte classe lava:


1. package 2. public 3. 4. com.mycompany; class MyFunctions String helIo (String name) { public static return "HelIo "+name;

5.
6 .

Esta classe representa o handler para uma funo que parte de uma tag library.
<%@ taglib uri="http://mycompany.com.tags" prefix="comp" %>

Qual Tag Library Descriptor define esta funo customizada para que ela possa ser usada em uma expresso EL?

o A.

<taglib>

<tag> <name>Hello</name> <tag-class>com.mycompany.MyFunctions</tag-class> <body-content>JSP</body-content> </tag> </taglib>

O B.

<taglib> <function> <name>Hello</name> <function-class>com.mycompany.MyFunctions</function-class> <function-signature>java.lang.String </function-signature> </function> </taglib> hello(java.lang.String)

C.

<web-app> <servlet> <servlet-name>hello</servlet-name> <servlet-c1ass>com.mycompany.MyFunctions</servlet-class> </servlet> </web-app>

O D.

<taglib> <function> <name>Hello</name> <function-class>com. mycompany. MyFunctions</function-cla ss>

<function-signature>hello(java.lang.String)</function-signature> </function> </taglib>

422

ca,ot,u/o 8

JSP sem scripts

4 Dado:
1. package 2. public 3. 4. 5. 6. com.example; class TheBean private public public public int value; TheBean() { value = 42; } value; = v;

int getValue() void

{ return v)

setValue(int

{ value

7.

Considere que nenhuma instncia do TheBean tenha sido criada ainda. Quais as declaraes da ao-padro JSP que criam uma nova instncia deste bean e a armazena no escopo da solicitao? (Escolha todas as que se aplicam.)

o A.
O B. O C.
O D.

<j sp: useBean

name="myBean"

type="com.example.TheBean" <jsp:makeBean name="myBean"

/>

type="com.example.TheBean" <jsp:useBean id="myBean"

/>

class="com.example.TheBean" scope="request" <jsp:makeBean

/>

id="myBean"

class="com.example.TheBean" scope="request"

/>

5 Considere
O A.

uma arquitetura Modelo 1 na qual uma pgina JSP trata todas as funes do controlador, e que o controlador JSP precisa despachar a solicitao para uma outra pgina JSP. Qual cdigo da ao-padro realizaria esta tarefa?
<j sp: forward <jsp:forward <jsp:dispatch <jsp:dispatch page="view. jsp"

/>
/> /> />

O B. O C.
OD.

file="view.jsp" page="view.jsp" file="view.jsp"

voc est aqui

t>

423

teste preparatro

Dado:

11.
12. 13. 14. 15.

<% java.uti1.List 1ist.add("a"); 1ist.add("2") 1ist.add("c"); ;

1ist

new java.uti1.ArrayList();

request.setAttribute("list",list); request.setAttribute("listldx", "1");

16.
17. %>

18. <%- insira

o cdigo

aqui -%>

Quais das opes, que se inseridas na linha 18, so vlidas e calculam o valor de "c"? (Escolha todas as que se aplicam.)

DA.

${list.2} ${list[2]} ${list.1istldx+l} ${list[listldx+l]} ${list['listldx' + l]}

D B.
[J C.

D D.
DE. DF.

${list[list['listldx']]}

'7

Quais declaraes sobre os operadores EL " . " (ponto) e "[ ]" so verdadeiras? (Escolha todas as que se aplicam.) DA.
${foo.bar}

equivale a

${foo[bar]}

[J B. ${foo.bar} equivale a ${foo["bar"]} [J C. ${foo ["5"]} uma sintaxe vlida se foo


for um D D. DE. DF.
Map ${header.User-Agent}

equivalea equivale a for

${header[User-Agent]} $ {header.User-Agent}

${header["User-Agent"]} $ {foo [5]} List

uma sintaxe vlida se


array

foo

uma

ou um

424

captulo 8

JSP sem scripts

8 Considere
${l01
%

uma pgina JSP com a seguinte linha:


10}

O que ser exibido?

OCo DE. oD. oB.

10 10} DA.

%%

10 1 101 1001 {101

Seja:
10. $ {param.firstname} 11. $ {param.midd1ename} 12. $ {param. lastname} 13. ${paramValues.lastname[O]}

Qual ser a sada resultante desta poro de pgina JSP ao passarmos a query string
?firstname=John&lastname=Doe?

DA.

John Doe John Doe Doe John John null Doe null Doe Doe

oB. O C. oD.

O E.

Ocorrer uma null point exception.

10

Quais opes representam o uso correto de variveis EL implcitas? (Escolha todas as que se aplicam.)

O A. oB.
OCo

$ {cookies .foo} ${initParam.foo} ${pageContext.foo} ${requestScope.foo} $ {header ["User-Agent"] $ {requestDispatcher.foo} ${pageContext.request.requestURI} }

oD.
DE.

DF.

O G.

voc est

fi'>

425

teste preparatrio

11 O que

verdade sobre a ao-padro <jsp:useBean>?

(Escolha todas as que se aplicam.)

A. O atributo id opcional. scope requerido. scope opcional e padro em class, quanto o type

O B. O atributo O C. O atributo
request.

O D. Tanto o atributo
requerido.

podem ser especificados, mas pelo menos um

O E. correto

incluir os atributos class e type,

mesmo que seus valores NO sejam iguais.

12

Como voc incluiria um contedo dinmico em JSP, similar ao server-side include (SSI)? (Escolha todas as que se aplicam.)
1\.

<%@include

file="/segments/footer.jspf" page="/segments/footer.jspf" page="/segments/footer.jspf" dispatcher ;

%> /> />

B. <jsp:forward

O C.

<jsp:include

D. RequestDispatcher

= request.getRequestDispatcher(~/segments/footer.jspf"); dispatcher.include(request,response)

13

Considerando uma pgina HTML com rich text e layout grfico, qual ao-padro JSP pode ser usada para importar uma figura para dentro da pgina JSP?

01\.

<jsp:image

page="logo.png"

/>

O B. O C. O D.
O E.
426
C8IJtU/O

<jsp:image

file="logo.png"

/>

<jsp:include

page="logo.png"

/>

<jsp:include

file="logo.png"

/>

Isto NO possvel usando-se uma ao-padro JSP.

JSP sem scripts

14 Considere:
1. package 2. public 3. 4. com.example; class MyFunctions string repeat(int x, String str) { public static

// corpo

do mtodo

5.

6. ) e dado o JSP:
1. <%@ taglib uri="/WEB-INF/myfuncts" o cdigo aqui prefix="my"

%>

2. <%-- insira

--%>

Qual a funo de chamada EL correta, se inserida na linha 2 do JSP?

DA.

${repeat(2, ${repeat("2",

"420" "420" "420" "420")}

OB.

O C.
O D. O E.

${my:repeat(2, ${my:repeat("2",

Uma chamada vlida NO PODE ser determinada.

15 Seja:
10. public 11. 12. 13. 14. 15. 16. class MyBean { params; objects; private private private public public public java.util.Map java.util.List String name; getParams() { return name; } objects; params; }

java.util.Map String

getName () { return getObjects()

java.util.List

{ return

17.
Qual das opes geraria erros (considere que um atributo chamado mybean seja encontrado, e do tipo MyBean)? (Escolha todas as que se aplicam.)

DA.

$ {mybean.name} $ {mybean["name"] }

O B.
elc. elD. elE.

${mybean.objects.a} ${mybean["params"] .a}

${mybean.params["a"]} ${mybean["objects"] .a}

DF.

voc est

427

teste preparatrio

16

Dada a pgina JSP:


1. The user has sufficiently logged in or out: 2. ${param.loggedln or param.loggedOut}. Se a requisio incluir a query string "loggedOut=true", declarao?

qual ser o resultado desta

DA.

The user has sufficiently false. user has sufficiently

logged logged

in or out: in or out:

OB.The true.

OC.The user has sufficiently logged in or out: ${param.loggedln or param.loggedOut}. OD.The user has sufficiently logged param.loggedln or param.loggedOut. in or out: in or out:

oor E.The user true.


11 O que verdade
O A. Podemos
[ ] for usado.

has sufficiently

logged

sobre os operadores de acesso EL? (Escolha todas as que se aplicam.) usar o operador [ ] sempre que o operador.

(ponto) for usado. B. Podemos usar o operador. (ponto) sempre que o operador

O C. Se o operador.

(ponto) for usado para acessar uma

propriedade inexistente de um bean, ocorrer uma exceo de runtime.

o D. Existem algumas
18

situaes em que o operador. (ponto)

deve ser usado, e outras em que devemos usar o operador [ ].

O seguinte fragmento de cdigo encontrado em uma pgina JSP: <jsp:include page="/jspf/header.html"/> Esta pgina JSP parte de uma aplicao web cujo contexto raiz myapp. Considerando que o nome do diretrio-pai myapp, qual seria o caminho para o arquivo header.htrnl?

DA.
[lB. ele. elD.

/header. html /jspf/header.html /myapp/jspf/header.html /includes/jspf/header.html

428

capitulo

JSP sem scripts

19

Um revendedor de jias on-line deseja personalizar seu catlogo on-line para os usurios que esto conectados. Ele deseja mostrar um produto especial para a pedra associada ao ms de aniversrio do usurio. As ofertas especiais da empresa so armazenadas como Map<String, Special[ ]> identificadas como specials no escopo do aplicativo e atualizadas diariamente. H um bean armazenado como um atributo no escopo da sesso chamado userInfo. Chamar getBirthdate( ).getMonth( ) nesse bean retomar a pedra associada ao ms de aniversrio do usurio. Qual dos seguintes fragmentos de cdigo poderia recuperar corretamente as devidas ofertas especiais?

[JA.

${applicationScope[userlnfo.birthdate.month.specials]} ${applicationScope.specials[userlnfo.birthdate.month]} ${applicationScope[~specials"] .userlnfo.birthdate.month} .specials}

[]B.
[J C.
[] D.

${applicationScope[~userlnfo.birthdate.month"]

20

Um aplicativo baseado na Web para um revendedor de aluguel filmes on-line maior armazena List<Movie> como um atributo sesso para conter os filmes que o usurio solicitou. Um trailer filme aleatrio incorporado a partir desta lista deve ser exibido pgina principal dos usurios sempre que ela for exibida.

de da do na

A gerncia acha que um recurso parecido ser necessrio em um futuro prximo nas outras pginas que exibem listas de filmes. Um vdeo contnuo conseguido com o HTML comum, exatamente como adicionar imagens a uma pgina, mas com tags mais complexas. A equipe de desenvolvimento precisa de uma soluo que seja flexvel e sustentvel. Uma possvel soluo criar uma funo EL. As seguintes instrues so de uma reunio da equipe relativas s funes EL como uma soluo para este problema. Quais instrues so verdadeiras? (Escolha tudo que se aplica.)

[J A. As funes

EL no podem resolver este problema porque no podem recuperar os atributos da sesso. a funo EL no deve ser declarado esttico para lhe fornecer acesso ao escopo da sesso.

[J B. O mtodo que implementa

O C. A funo EL pode aceitar um parmetro java.util.List

que permitir lista de filmes necessria ser transmitida usando EL. lava usando uma funo EL, que mais difcil de manter.

O D. Voc pode ter que escrever as tags HTML no meio do cdigo

voc est

429

teste

Yausa pata

9 cat

1 Dado um formulrio

HTML que usa checkboxes para permitir que o usurio selecione diferentes valores para um parmetro chamado hobbies. Quais expresses EL calculam o primeiro valor do parmetro hobbies? (Escolha todas as que se aplicam.)

Iitr A. [] B. Iitr C.
[] D. [] E.

$ {param.hobbies} ${paramValue.hobbies} ${paramValues.hobbies[O]} ${paramValues.hobbies[l]} $ {paramValues $ {paramValues [hobbies] [O]} [hobbies] [1]}
11-

/ cr/;c $/ es.f-:

inccrre.f-a)

fcr31/f!.

nrc exls-l-e tl

lIari"tlvel
-

r....,lIei/-a fQralOlValve, cs tJ.rr'1s

11- fgr lJ es/-: r17cc/"f'e/-a,; fCl'1pe sc IPlJextJ.JlJs CCIOl

O,

[]F.

II-s cf!j6es

e F tJ.ft'esen.ftJ.1OI SIPl.fIllM

IPlcarr&u..

Z Considerando uma aplicao que guarde o endereo de correio eletrnico do webmaster no


parmetro de inicializao do contexto do servlet chamado master-email. Quais ativam tal valor? (Escolha todas as que se aplicam.)

[] A.

<a href='mailto: ${initParam.master-erMJ~.f~,OJ email me</a> <a href='mailto:${contextParam.master-email}'> email me</a> <a href='mailto:${initParam['master-email']}'> email me</a> <a href='mailto:${contextParam['master-email']}'> email me</a>

se!j6es

2,2,3 e 2.3.'-/)

[]B.
~C.

[]D.

11- fs';"

A- -I-ePl.f1ll Sl/b.f/'alr

f!lOIatl

.Ia

IOIIIIS-l-eI'.

II-s CfS6es

8 e lJ es-P;(}

IPleI'N!./-as) fCf'3ve eCI7.fex-fPar.lOI.

exi"s.fe

a vo.l'l-:'ve/ l....,lel/-a

430

JSP sem scripts

.3 Dada a seguinte classe lava:


1. package 2. public 3. 4. com .mycompany; class MyFunctions String hello(String name) {

public

static

return

~Hello

~+name;

5.
6. Esta classe representa o handler para uma funo que parte de uma tag library.
<%@ taglib uri=flhttp://mycompany.com.tagsfl prefix="comp" %>

Qual Tag Library Descriptor define esta funo customizada para que ela possa ser usada em uma expresso EL?

A.

<taglib>

<tag> <name>Hello</name> <tag-class>com.mycompany.MyFunctions</tag-class> <body-content>JSP</body-content> </tag> </taglib>

~ B.

<taglib> <function> <name>Hello</name> <function-class>com.mycompany.MyFunctions</function-class> <function-signature>java.lang.String </function-signature> </function> </taglib> hello(java.lang.String)

O C.

<web-app> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.mycompany.MyFunctions</servlet-class> </servlet> </web-app>

O D.

<taglib> <function> <name>Hello</name> <function-class>com.mycompany.MyFunctions</function-class> <function-signature>hello(java.lang.String)</function-signature> </function> </taglib>

voc est

431

teste preparatrio - respostas

4- Dado:
1. package 2. public 3. 4. 5. 6. com.example; class TheBean

private public public public

int value; TheBean() { value = 42; } value; = v;

int getValue() void

{ return v)

setValue(int

{ value

7.

Considere que nenhuma instncia do TheBean tenha sido criada ainda. Quais as declaraes da ao-padro JSP que criam uma nova instncia deste bean e a armazena no escopo da solicitao? (Escolha todas as que se aplicam.)

DA.

<jsp:useBean

name="myBean"

type="com.example.TheBean"

It '" A I I /> - n "P5a" n e ll'/lI!/lJa., p"r'tlte o


a+rt!Jlrf" Ijpe Al/}t>

DB.
l\d' c.

<jsp:makeBean

name="myBean"

IIsadlJ p41"a
IJ

type="com.example.TheBean" <jsp:useBean id="myBean"

/> crliJ,l"lt\S tllt\Q "7lJlla'i<Js+~cto. e


o.+rt!Jv.f-c de esc"pc fl'ectsa eSfect/tee.d" ptl,(r,,).

seI"

class="com.example.TheBean" scope="request"

((lJ !J.{>c"7.f-ar faro. a f~,i<Ja-

/>

DD.

<jsp:makeBean

id="myBean"

- Ir

IJfjc

class="com. example. TheBean" scope="request"

8 'i1v:IMa fCl"

.f-"dcs cs

/>

It\"h-vcs

a"7.fel",-"res J/~/li<\ (c fa+e (e

3VejSf:lt\lJ.1:e8ea"7 Al{Jro

fllt\a +0-5 N!4/.

Jl. Cfj4C "'1\" I - n V e 'i1't,.lJ.lld4) f"I"'lle


jsp:lt\a1:e8eall1 Al{Jro w

(lll>\tI, hq ~ real.

5 Considere
l\d' A.

uma arquitetura Modelo 1 na qual uma pgina JSP trata todas as funes do controlador, e que o controlador JSP precisa despachar a solicitao para uma outra pgina JSP. Qual cdigo da ao-padro realizaria esta tarefa?
<j sp: forward <jsp:forward <jsp:dispatch <jsp:dispatch page="view. jsp"

/>
/>
/>

DB.

file="view.jsp" page="view.jsp" file="view.jsp"

D C.

DD.

/>

- {Jr "'fSe A- es+: cCN'e.f-a (p~.

7-770).
(J

Jl. ""$l" I "" ftJI"wtJ.t'd 1'/4C '" f"S SI/t IJIt\IJ.-rl'lbv-ro I J - n tJPsa telP/Vo,ltd4; p(Jf'1/1e a aS4" ftle.

- {Jrs cps';es C tej) so 'i1V:IMtJ.S;plJt'3I1e ;,lJ exls.fe

Clllt\41'/dIJ dt''spll+et..

432

cap,itulo 8

JSP sem scripls

6 Dado:
11.
12. 13. 14. 15. 16. 17.
<%

java.util.List list.add("a"); list.add("2"); list.add("c") ;

list = new java.util.ArrayList{);

(JsPv2.0) se,';" 2.J,L/)

request. setAttribute request. setAttribute

("list" , list); ("listIdx" , "1");

%>
o cdigo aqui -%>

18. <%- insira

Quais das opes, que se inseridas na linha 18, so vlidas e calculam o valor de "c"? (Escolha todas as que se aplicam.)

DA.
lilJ"B.

${list.2} ${list[2]} ${list.listIdx+1} ${list[listIdx+1]} ${list['listIdx' + 1]}

O c.
lilJ"D.

- A-s "fj6eS

A-

f C fSh6

tI1C61"f'ffaS; f61'1Jl.if
(111\

" 4ffl"adM' f",rl-{) "'';" ftldf ser I/so.dcC"II\


ft'lf'lt-hV6. - A- "fS';tl

DE.
lilJ"F.

fS+:

f",c"t'l"e+~ f""fpe

Ots+Idx .;./)

${list[list['listIdx']]}

+6""'4.-se VII\o. s+I'I"'5'

'1 Quais
DA.

declaraes sobre os operadores EL " ." (ponto) e "[ ]" so verdadeiras? (Escolha todas as que se aplicam.)
${foo.bar} ${foo.bar} ${foo ["5"]} Map

equivale a equivale a

${foo[bar]} ${foo["bar"]} foo

lilJ"B. lilJ"C.

uma sintaxe vlida se

forum

O D. $ {header. User-Agent}
${header[User-Agent]}

equivale a equivale a for

O E. $ {header. User-Agent}
${header["User-Agent"]}

lilJ"F.

${foo [5]} List

uma sintaxe vlida se


array

foo

uma

ou um

voc est

433

teste preparatrio - respostas

8 Considere
${101

uma pgina JSP com a seguinte linha:

% 10}

O que ser exibido?


M"

A.

1
10
1001 101 {101
%

O B.
O e.
D.

-1Jr f4IJr es+: corre+tJ.. D cpertJ.dor ~tJd l'e+N'tJ.6 res+o de v~tJ.diVis4.


10
%

DE.

10}

Seja:
10. $ {param.firstname} 11. $ {param.midd1ename} 12. $ {param. 1astname} 13. ${paramVa1ues.lastname[O]}

Qual ser a sada resultante desta poro de pgina JSP ao passarmos a query string
?firstname=John&lastname=Doe?

DA.
M" B.

John Doe John Doe Doe John null Doe John nu11 Doe Doe

O C.
DD.

e "p/valida) pt'Jf'~ve ti 11~t,{], ;' p/(Jh;eti" VSVtit'IC. C e j) Stl i~V:/tJtJ.s;fe,t'3!e "tv/e,.

;' ;'

13' .! rtJ.h;beh;
Q

lijo;t.a

77 extbe

O E.

Ocorrer uma null point exception.

10

Quais opes representam o uso correto de variveis EL implcitas? (Escolha todas as que se aplicam.)

(J:so '? li ;' rVb-.u;PtiJ


${cookies.foo} ${initParam.foo} ${pageContext.foo}

DA.
M"B.

De.
M"D.
M" E.

-1Jr Pf46 lJr ;' /u u vtJ.t'Ii!l.vel e u,(JUe - lJr Dflt1 C I~CDf'l'e+~ pl'fpe ;'
e v!!'; K.-tap e

${requestScope.foo}

p~eC6Pl"hx+
${header[~User-Agent"]} p"S Sll!" Vh;tJ. -

n u
f

DF.
M" G.
${requestDispatcher.foo}

-1 ep:;4tJ
li!!';

I~C61'I'e+a; pal'3!e iS+


i"y>lc;l+.

$ {pageContext. request. requestURI} AllJro

434

JSP sem scrpts

11 O que verdade sobre a ao-padro <jsp:useBean>? (Escolha todas as que se aplicam.)

o A. O atributo id opcional.
O B. O atributo scope requerido. O C. O atributo scope opcional e padro em
request.

<.J'sPv2..0Jf:5 7-703 e 7-70'!)


lJr IJfj';(J lJr es+:

IilD. Tanto o atributo class,

IilE. correto incluir os atributos class

quanto o type podem ser especificados, mas pelo menos um requerido. e type, mesmo que seus valores NO sejam iguais.

tl1cIJl'l'e+aJ

fIJI'3ve

tl I"d e reavel'Ma.

IJrs "fj';eS

f"rve

l'f1CIJI'N:+asJ / '" " sCIJfe e (Jfcl"IJI?a! e e ffJ.JI'(J,{J m~

G e C es+"

ftljl),C..

12

Como voc incluiria um contedo dinmico em JSP, similar ao server-side include (SSI)? (Escolha todas as que se aplicam.) DA. <%@ include file=" /segments/footer.
<.

J1.5P v..2.

OJ SeSfJ.6 '" .;> r :..,I

I)

jspf" %> jspf" />


-1Jr (Jbc(J r J lJr f.s+t

O .... B. <jsp: forward


~

page="/segments/footer.

~ C.<jsp:include page="/segments/footer.jspf" /> DD.RequestDispatcher dispatcher . = request.getRequestDispatcher(~/segments/footer.jspf"); dispatcher.include(request,response) ;


-1Jr 6fJ6!J es+al'la C6rl'e+a se i'ss61.,sse IIA>\ SViJ.S'1;'+iJ.xe s': serve fiJ.N~ C.,1OI6 I1iJ.fj CJ A>\iJ.S'

i (.ISo.tlA>\iIdll'e-r"lllil
1),c/vJe
JO

~~~

,we sel've

flli.l'fl.

1),c/vtes

13 Considerando uma pgina HTML com rich text e layout grfico, qual ao-padro JSP pode ser
usada para importar uma figura para dentro da pgina JSP? DA. <jsp:image page="logo.png" /> O .. B . <j sp: image file=" logo. png" />
seg., S-,I
e

I)

/),v:IMiJ.sJ f<ll''l.ve U cl.QlOIattJ. l/;;tlje

"';(J

O .. . C.

<jsp:include

page="logo.png"

VIOItJ. (U;IJ-fIli.Jl'6 IJffIJ C es+: Gie iJ.sl1+axe

O D.

IilE.Isto NO possvel usando-se uma


ao-padro JSP.

<jsp: include file="logo .png" />

lJ'lCal'F'(~+iJ.J'16 felIJ 1c.+IJ eNiJ.ttJ.J "S


(J

ta iJ.ja '1C!vde es+al'

IOIfl.S p61'Slle l1IJ IJJ., seJ"/+ttJ i"V'dl'+i1.r

taJIJs bl1f1I'/t:,S t6 aI'SIIi"VIJ te .'IOI~e/;;pfl.l'a CM.fetJt tc

J,Sp'
Itle.

-I} 6pl;'(J !J es+:


s+fl. fl.l'svlve

'1CIJI'I"e+c.J P61'file capdcs~ peiS

afc 1),c!vJe l1o Qcel+c. li/;;Q+l'l!;tI+IJ s:vel Jw.pOI'.fa1'

1/1010, feI'5vi1+a

fJ-o pcs

C()J1.fetJtete nenl.vl!<;

bl1:I'/t:, PQI'c. til!<; J,SP.t ave 5f.1'f. Vl!<;fJ. I"SP6S+a

#nl.{L,
voc est
il"

435

14 Considere:
1. package 2. public 3. 4. 5. com.examp1e; c1ass MyFunctions String repeat(int x, String str) { pub1ic static

// corpo

do mtodo

6. } e dado o JSP:
1. <%@ 2. <%-taglib insira uri="/WEB-INF/myfuncts" o cdigo aqui --%> prefix="my"

%>

Qual a funo de chamada EL correta, se inserida na linha 2 do JSP?

[]A. []B.
Dc.
DD.
&"ir

${repeat(2, ${repeat(~2",

~420")} ~420")} ~420")} ~420")}

-It <>'{;'D l. es-/-: cI:U"I'e-fa,j},i,/l)l'lf'I.a{;'D


lf'I.tJ.pe&llf'l.el1'f-" '1ecess:rlQ. AJ/J-tJ : umt.ecMa.

tie

${my:repeat(2, ${my:repeat(~2",

E. Uma chamada vlida NO PODE ser determinada.

15 Seja:
10. public class MyBean { 11. private java.util.Map 12. 13. 14. 15. 16. 17. private private public public public java.util.List String name; getParams() { return getObjects() { return name; } objects; params; }

(J5PIl2-.0),~. 1-(.8)
params; objects;

java.util.Map String

getName()

java.util.List

{ return

Qual das opes geraria erros (considere que um atributo chamado mybean seja encontrado, e do tipo MyBean)? (Escolha todas as que se aplicam.)

DA.

$ {mybean.name} ${mybean[~name"]} ${mybean.objects.a} ${mybean[~params"l.a} ${mybean.params[~a"]} ${mybean[~objects"] .a}

[]B.
&"ir

c.
E.
F.

DD.
[]
&"ir

~ ~ - ~s ",ges C e F CQlIStlt'lUJ errcs. AJlttJ 3l1e c

It lel-t'a

HH
tl

Vlf'l.tl pr"prletiatie
fi ()tjecrs I fi
$V

titl LlS+'; e cc'?stilef'tJ.l'lti

'1tl e li'" MtJ.pJ vlf'l.abusca l'Ia sera

'"

exec(.jf-tula (a cI'l+t':l'l'L; tias cps';es lJ e i,).

436

ca~)tulo 8

JSP sem scripts

16 Dada a pgina JSP:


1. The user has sufficiently logged in or out: 2. ${param.loggedln or param.loggedOUt}. Se a requisio incluir a query string "loggedOUt=true", qual ser o resultado desta declarao?

DA. The user has sufficiently logged in or out:


false. ~B.The user has sufficiently true. logged in or out:

- fi ~P';~ ~ es-l-: C~J"I"e-ffJ.Jf!"3Uf!


fJ.

o C.The user has sufficiently logged in or out: ${param.loggedln or param.loggedOUt}.


OD.The user has sufficiently logged in or out: param.loggedln or param.loggedOUt. [) E.The user has sufficiently true.

expl"essa~

,.,

"L.

<:

3"e usa

<)

nar N

I'e-far'lo.r: ~v

-I-I'Vf!; se ~II

t:l

1655eG/II1)

a 1t:l55eG/()v-l- foI'

-I-,.U(.

logged in or out: or

17 O que verdade sobre os operadores de acesso EL? (Escolha todas as que se aplicam.)
~ A. Podemos usar o operador [ ] sempre que o operador. (ponto) for usado. O B. Podemos usar o operador .(ponto) sempre que o operador [] for usado. O C. Se o operador. (ponto) for usado para acessar uma propriedade inexistente de um bean, ocorrer uma exceo de runtime. O D. Existem algumas situaes em que o operador . (ponto) deve ser usado, e outras em que devemos usar o operador [ ].

(J5Pv2..0)pt.,. 7-(,9)

- fi 6fi';6

~ es-l-:

I;'C61"1"e-f<l;

IVl'lc"ltll'lo.l": pOf'1i'e apel'lo.s t:l [] 416aCeSS4f'1f\6S; a) L.ts+s e af''''s; e

b)

lf\apf!fAlf\el'l-!-os,) 11';6 es~alf\

e'1f\

3ve o-s chaves esU'i"-I-as.

bel>\

- fi Cptj';6 P es-l-:
pt:lf'3ve

I;'C61"f'e-f<l; p61'1-1-6

c 6pef'atl61'

p<!le seI' +1"fJ.l1sI61'I>\o.tllJ 114 <!lfel'atl61'

r].

18 <jsp:include O seguinte fragmento de cdigo encontrado em uma pgina JSP: (J5Pv 2..0) page="/jspf/header.html"/>
Esta pgina JSP parte de uma aplicao web cujo contexto raiz myapp. Considerando que o nome do diretrio-pai myapp,qual seria o caminho para o arquivo
header.html?

O A. /header.html [) B. /jspf/header.html ~ C. /myapp/jspf/header.html [) D. /includes/jspf/header.html


voc est

437

teste

pre'pai,at(kio

19

Um :evendedor de j,~ason-line _deseja personalizar seu .catlogo (J,SPv 2.0 sec+lc"J 2.3.'-/) on-lme para os usuanos que estao conectados. Ele deseja mostrar um produto especial para a pedra associada ao ms de aniversrio do usurio. As ofertas especiais da empresa so armazenadas comoO!'+';''1 8 CIJI"'I"''!.c+'}l"dl"t'!.v'!.s "111' M ap< S tnng, SpeCla . l[] > 1 'd entI'fi ca d as como specIa . Is no escopo d o -I-~ M"f'<5-1-l"t"j, r f/ 5pl'!do./[]> INJ'" aplicativo e amalizadas diariamente. "f'!'Z'C,1l"IJ'I i L SU'!,'!.. "r' -r'!.'1 1l-r-t'"ff:""f"r'S . " Se1H um bean armazenado como um atributo no escopo da sesso -I-he ",,,,,./-h lia/v'!. 11'0'" +he IIsers chamado userInfo. Chamar getBirthdate( ).getMonth( ) nesse bean !JFI'+t.dllJ ll'1d
'!.

'.t

retomar a pedra associada ao ms de aniversrio do usurio. Qual dos seguintes fragmentos de cdigo poderia recuperar corretamente as devidas ofertas especiais?

IIS'!.S -I-i.o.+ ilS .f.t.,e ):e7

+e
"VI"'

seo.f'Ct,

leI' o. 5,ecto./ [ 1,), .ft.e lt1ap. A-ssv""),5 a ",ai,;h


1'$

lellJ?d ,;, +t.e lt1a'j

5ff.da! []

"s I"'dvl"'",ellf. C(;I/M !le IIsed ,,, a c:

n,,-s

u..

D A.
~B.

$ {applicationScope

Iel"'act, [userlnfo. birthdate. month. sp~JKl.f

-I-~ +e

l+el'a+e $pectals.

<>vef' +t.e

${applicationScope.specials[userlnfo.birthdate.month]} ${applicationScope[~specials"] .userlnfo.birthdate.month} .specials}

[J C. [J D. 20

${applicationScope[~userlnfo.birthdate.month"]

Um aplicativo baseado na Web para um revendedor de aluguel de filmes on-line maior armazena List<Movie> como um atributo da sesso para conter os filmes que o usurio solicitou. Um trailer do filme aleatrio incorporado a partir desta lista deve ser exibido na pgina principal dos usurios sempre que ela for exibida. A gerncia acha que um recurso parecido ser necessrio em um futuro prximo nas outras pginas que exibem listas de filmes. Um vdeo contnuo conseguido com o HTML comum, exatamente como adicionar imagens a uma pgina, mas com tags mais complexas. A equipe de desenvolvimento precisa de uma soluo que seja flexvel e sustentvel. Uma possvel soluo criar uma funo EL. As seguintes instrues so de uma reunio da equipe relativas s funes EL como uma soluo para este problema. Quais instrues so verdadeiras? (Escolha mdo que se aplica.)
passe" as III"c-l-,;, .
11

V J'''"P

2 O secri(m 2 /)

I,
.!:>,

-H.e "'''V'''!. IlS+ co." !?e pOJ'Il",e+er


-1-"

-I-he

8; ~ellfs
1""'f1'!.1I1!e",./-f..

+t.a.f
1PoiIs.f.

fV'l,d . ",J'ls

al"'llJs

be .tecla"ed

pvb/te a""l s+a.f.,'c,

[J A. As funes

-Op-h;'''' C; o. Lts+ "',. lIe posse.t +'" -H.e fll'1c-h;'i/. 1)''';'5 S'" p""IIMes

EL no podem resolver este problema porque no podem recuperar os atributos da sesso. a funo EL no deve ser declarado

II ,..el"'e

f!eMb!'!.

sell/f,;,,,

[J B. o mtodo que implementa

-1-1,1<1'/ ei/e -10.+ l'e311,res rI/I"' U. !I,IIIe-h;,,,, f", h'm.tle sesst,,'1 se(;pe as l" "'p-h;,,,,s
o.

a",.l b.

esttico para lhe fornecer acesso ao escopo da sesso. ...,. 1/. il. -rhe I !;'5~s"r' I l"'el<S"" ",,,r ; vp.,.,cn ~ C. A funo EL pode aceitar um parmetro java.util.List que -I-IJd.,,(;se 0.'" f.. ;Y",c-h'l'/ as +t.e permitir lista de filmes necessria ser transmitida usando EL. +,,-1-0.1s"III-I-I"<"1.rt,e +ea", ct."s'!. -1-"
r? llLI , . . D. Voce pode ter que escrever as tags HTML no meIO do cdIgo Java usando uma funo EL, que mais &ficil de manter.
IIse o. -I-~f"le as .f.t.,e s"lv-/-,;,'1 !?v-l-I-he" a/s" c/'eo..f.ed a" L Iv"c-/-,"'" -H.a-l-o.cc'!.p-l-s o. C"lIec-/-,"'" o.",.l 1'e+vl""'lS a l"o."d_ "li"'!?'!./, !lased " -I-to'!. sl-;e "I-H.e c",lIec-h"",

438

9 USqnd9 a]Srr

As Tags Customizadas so poderosas


Voc quer dizer que eu enviei, todo este tempo, os scriptlets de escrita para coisas que no posso fazer com a EL e as aes padres, quando poderia ter usado JSTL?

D
O

Em alguns casos, voc precisa de mais do que a EL ou aes-padro.

E se

voc quisesse fazer um loop atravs dos dados de um array, exibindo em seguida um item por linha em uma tabela HTML? Voc sabe que poderia escrever isso em dois segundos, usando um loop for em um scriptlet. Mas voc est tentando evitar os scripts. Sem problema. Quando a EL e as aes-padro no forem suficientes, voc pode usar tags customizadas. Elas so to fceis de usar em um JSP quanto as aes-padro. Melhor ainda, algum j escreveu boa parte das tags de que voc mais provavelmente precisar, e as juntou na JSTL (JSP Standard Tag Library, ou Biblioteca de Tags JSP Padro). Neste captulo, aprenderemos a usartags customizadas, e no captulo seguinte, aprenderemos a criar as nossas prprias tags.

este

urn novo

439

objetivos do exame oficial da Sun

6i
Construir pginas JSP usando bibliotecas de tags
9.1 Descrever a sintaxe e a semntica da diretiva 'taglib': para uma biblioteca de tags padro e para uma biblioteca de Tag Files. 9.2 Dado um objetivo de design, criar a estrutura da tag customizada para atingir esse objetivo. 9.3 Identificar a sintaxe da tag e descrever a semntica da ao das seguintes tags JSTL v1.1: (a) tags centrais: out, set, remove e catch, (b) tags condicionais: if, choose, when e otherwise, (c) tags de iterao: forEach, e (d) relacionada URL: url.

Notas sobre

a Abrangncia:

Todos os objetivos desta seo so cobertos neste captulo, embora parte do contedo seja coberta novamente no prximo captulo (Desenvolvendo Tags Customizadas).

Instalando a JSTL 1.1


A JSTL 1.1 NO faz parte da especificao JSP 2.0! Ter acesso s APIs dos Servlets e JSP no significa que voc tem acesso JSTL. Antes de poder usar a JSTL, voc precisa instalar o arquivo 'jstl.jar' no diretrio WEBINF/lib do seu aplicativo web. Isso significa que cada aplicativo web precisa de uma cpia. No Tomcat 5*, a JSTL j se encontra nas aplicaes de exemplo que vm includas com o Tomcat, ento tudo o que voc precisa fazer copi-Ia de algum diretrio para seu prprio diretrio WEB-INF/lib. Copie a JSTL dos exemplos do Tomcat de: webapps/jsp-examplesIWEB-INF webapps/jsp-examplesIWEB-INF standard.jar /lib/jstl.j ar /lib/

E coloque-a no diretrio WEB-INF/lib do seu prprio aplicativo web.

440 capitulo

usando JSTL

A EL e as aes"padro so lilftitadas

o que acontece quando voc se choca contra uma parede? Voc pode voltar aos scripts, certamente mas voc sabe que esse no o caminho.
Os desenvolvedores normalmente querem ter muito mais aes-padro, ou, melhor ainda, querem ter a habilidade de criar as suas prprias aes.

para isso que servem as tags cllstomizadas. Em


vez de dizer <jsp:setProperty>, voc deseja criar algo como <meu:fazerAlgoCustomizado>. E voc pode. Porm, no to fcil assim criar o cdigo de apoio que funciona nos bastidores da tag. Para o criador de pginas JSP, muito mais fcil usar tags customizadas que escrever scripts. Para o programador Java, no entanto, criar o tag handler (o cdigo Java chamado quando um JSP usa a tag) customizado mais complicado. Felizmente, existe uma biblioteca-padro de tags customizadas conhecida como Biblioteca de Tags JSP Padro (JSTL 1.1). Uma vez que o seu JSP no dever estar mesmo executando muita lgica de negcios, possvel que a JSTL (combinada com a EL) seja tudo de que voc ir precisar. Ainda assim, podero existir momentos em que voc precise de algo como, por exemplo, uma biblioteca de tags customizadas desenvolvida especificamente para a sua empresa. Neste captulo, voc aprender como usar as tags JSTL centrais, bem como tags customizadas retiradas de outras bibliotecas. No prximo captulo, aprenderemos como criar as classes que manipularo as chamadas s tags customizadas, para que voc possa desenvolver as suas prprias.

voc est aqui ~

441

onde est meu htm/?

o caso

do

"fMI.

desaparecido (reprise)
Lelrlbra Jts+c?

Na pgina 384, vimos como EL envia a string bruta de contedo diretamente para o fluxo de resposta:
<div class='tipBox'>

Irs +~s

<b></ b>

C(llrltl '1';6 4pareCiQ.1rI

-I-ex-l-o; irias el'41r1 o.pl'ese.~IJ.Ja.s


C61r1(l

<b>Tip $ {pageContent.currentTip} of the Day:</b> <br/>~ <brj> di v>

fllrI e.spfJ.flJVfJ.j' 3f1t. es+IJ.VQt.1rI '1t.jl'l-+tJ.

o que desejamos
<div class='tipBox'> <b>Tip af the Day:</b> <br/> <b></b> tags make things bold! </div>

o que conseguimos
<div class~'tipBox'> <b>Tip af the Day:</b> <br/> <br/> &lt;b&gt;&lt;/b&gt; tags make things </div>

bald!

Apresentado

como

&!.f:; :
C64>1"

D.pl"tsti'/-I-fJ.tl(j

<:

APreseotat como

&+.; ~D.pf'eSeif-!-tJ,tll:>
(;"4>11:>

>,

Tip of the Day:


<1:<;,b> tags make things bold!

um modo de converter esses sinais de maior que menor que em alguns navegadores apresentar como sinais de maior que menor e h dois modos de fazer isto. Ambos usam um mtodo Java esttico que converte os caracteres especiais HTML em seu formato de entidade:

o que precisamos

Use uma funo EL


<div class~'tipBox'> <b>Tip af the Day:</b> <br/> <br/> $(fn:canvEntity(pageCantent.currentTip) </div>

Use um mtodo assistente Java


<div class='tipBax'> <b>Tip of the Day:</b> <br/> <br/> $ {pageContent.convertedCurrentTip} !</div>

sl-e

I
t!J

lrIe+tJJtJ4SSi'sI-e,,1-e

~-------------------...,
public String getConvertedCurrentTip () ( return HTML.convEntity(getCurrentTip()};

442

usando JSTL

H U'fla 'flatteira 'flelhor: use a tag <o:oUf>


Seja qual for a abordagem usada, um pouco indistinto o que est acontecendo ... e voc pode ter que escrever esse mtodo assistente para todos os seus servlets. Felizmente, h um modo melhor. A tag <c:out> perfeita para o servio. Veja como a converso funciona:

Voc pode declarar explicitat\tet1te a cOt1verso das ettIidades XML


Se voc souber ou achar que pode encontrar algumas entidades XML que precisam ser exibidas e no apenas apresentadas, poder usar o atributo escapeXml em c:out. Definir isso para true significa que qualquer XML ser convertido em algo que o navegador Web apresentar, sinais de maior que menor que e tudo mais:
<div class='tipBax'> <b>Tip af the Day:</b> <br/> <br/> <c:aut value='${pageCantent.currentTip}' </div>

escapeXml='true'

I>

Voc pode declarar explicitat\tet1te NENHUMA cot1verso das et'ltidades XML


Algumas vezes, voc deseja exatamente o comportamento oposto. Talvez, esteja construindo uma pgina que tem contedo e quer exibir esse contedo com a formatao HTML. Nesse caso, voc poder desativar a converso XML:
<div class='tipBax'> <b>Tip af the Day:</b> <br/> <br/> <c:out value='${pageContent.rawHTML}'

s~
>dfnf..1.l-; I e ><Ml-...

; .fr4J.J
i'$'SI)

g,-!e.fa IJS caNu:fft'ts .fQlt'ilt'i.

HrMl-

I\'

escapeXml='false'

</div>

Is.f1J : i1.1f~S... aVf.lflf.lJa,;

f.lIJYf .f11f("f.lIt'iIJS 1"".1!J>/ 1. ""'1.1.'" CIJIt'iIJ

I>

ffx.flJ.

A cot1verso ocorre por padro

o atributo escapeXmI tem como padro true, portanto, voc pode omiti-Io se quiser. Uma tagc:out sem um atributo escapeXML exatamente igual a uma tag c:out com escapeXML definido para "true".
<div class='tipBox'> <b>Tip of the Day:</b> <br/> <br/> <c:aut value='${pageContent.currentTip}' </div> ~ ISSIJ : t'efJ.llt'ielfff -!VIfCllJIfQIi(Jo.Je. I>

voc est

.443

escapando htm/

l"l9

exlst~m < &#039j &gtj &Itj &#034j &ampj

f:

fet.suntas ldl9tlS
Quais caracteres HTML especiais so convertidos? > &

"

1\:

Acaba que esta converso bem simples. Existem apenas cinco caracteres que requerem o escape: <, >, & e os dois smbolos de aspas, aspas simples e duplas ". Tudo isso convertido nas entidades HTML equivalentes. Por exemplo, < torna-se &It;, & torna-se &amp etc. No ltimo ms, minha empresa contratou uma consultora Web para fazer uma auditoria em nosso aplicativo Web. Ela notou que estvamos usando EL em todo lugar para produzir as strings fornecidas pelos usurios. Ela disse que era um risco de segurana e recomendou que produzssemos todas as strings do usurio usando a tag c:out. O que est havendo?

f:

1\: Sua consultora

est certa. O risco de segurana ao qual ela est se referindo chamado de hack com cruzamento de sites ou script com cruzamento de sites. O ataque enviado do navegador Web de um usurip para outro usando seu aplicativo Web como o mecanismo de envio.

o cracker

fornece um campo de comentrio em seu aplicativo Web, que est armazenado no banco de dados. O cracker inclui um cdigo JavaScript com vrus no comentrio. Seu aplicativo Web

O usurio inocente exibe o comentrio

do cracker, mas

o texto que o cracker forneceu tambm inclui o cdigo "inocente" ;\ JavaScript que compromete o sistema do usurio2!

(J SOf'

4 +fJ.; c:.:)v..,.. para

f: O que acontecer
1\:

se o valor da expresso EL for null?

fJ.presePl+o.r +eX+1J flJS usv:rii}S iil<lf'e~e " t.4C~ CIJIt\

Boa pergunta. Voc sabe que uma expresso EL ${evalsToNull} gera uma string vazia na sada da resposta assim como <c:out value="$ {evalsToNull}"/>.

crtl;Q.lt\en+c fe si+eS ~esse Icrlt\vl:rli) ~e exi;tr fJ.S+f3.5s <.scri'p+' e


4)

c~f";c

J~ PIa
pe1

PlQ.ve;tJ.f<':Jr Wej, f/) tls~fJ.r,i}2,

Mas esse no o final da histria de c:out. A tag c:out inteligente e reconhece quando o valor null e pode executar uma ao especial. Essa ao para fornecer um valor padro ...

Isso

i'iI<If'efe ~tle I) CI)~j s~tJ. litI-hrpre+fJ.fl)

J-s

PlIJ.Vf!dfDr D a+fJ.3ue ", J IJ.Plvla.PI~1) <; uSlIQ.ri'll/.

444

capfuio 9

usando JSTL

Os valores t1ullso apreset1fados como texto em brat1co


Suponha que voc tenha uma pgina que d as boas-vindas dizendo "Hello <user>". Mas recentemente, os usurios no tm se conectado e a sada parece bem estranha:
EL

tlo itftpritftir tlada se o usurio for tlul!


<b>Hello ${user}.</b>~

Apresentado

como

<b>Hello

Utfta tag da expresso JSP tlo itftpritftir tlada se o usurio for tlul!
<b>Hello <%= user
%>.

C"II\" tlse" } e <%= tlsel' ItJl'o,II\ o,lIfJ.!i'aJ",s CIJII\"

&{

%,

</b' -~'""'""
Apresentado como

__ <_b_>_H_e_l_l_o_. <_/b_> __

t1efit1aum valor padro com o atributo default


Suponha que voc queira mostrar a esses usurios annimos uma mensagem que diz: "Hello guest" (Ol convidado). Este um lugar perfeito para usar um valor padro com a tag c:out. Simplesmente adicione um atributo default e fornea o valor que deseja imprimir, caso sua expresso seja avaliada como null:

s-k! l/IJ,!()" se,,: f"JVjlJ() se " a+I"I"I;//+., 1I1J,1//e 1,,1' IJ,lIlJ.llfJ.J" CIJ"'tJ '1//11.

<c:out> fornece Utft atributo default


<b>Hello <c:out value='${user}'

~
default='guest' />.</b>

Apresentado \
<b>Hello

como

I IL '" e rr5""~ (j IIlJ.ll' ffJ.Jl'a


l'i1sfl'lti ff!"lel+.

Ou voc pode fazer assitft:


<b>Hello <c:out value='${user}'>guest</c:out></b>

voc est

445

a tag <c:forEach>

Fazetldo loops setMscripts


Imagine que voc deseja algo que faa um loop atravs de uma coleo (por exemplo, um array de itens de um catlogo), que retire um elemento de cada vez, e que exiba esse elemento em uma linha de uma tabela gerada dinamicamente. No possvel programar de antemo a tabela completa - voc no tem idia de quantas linhas existiro no momento da execuo e, claro, voc no sabe quais so os valores correspondentes. A resposta a tag <c:forEach>. Isto requer um conhecimento bastante ligeiro sobre as tabelas HTML, mas inclumos aqui notas para os leitores que no estiverem familiarizados com o tpico. A propsito, para o exame voc precisa saber como usar <c:forEach> com tabelas.

Cdigo do Servlet
String[] movieList = {nAmelie", request.setAttribute(nmovieList", nReturn of the King", movieList); nMean Girls"};

o que

voc quer

Movie list: Amelie Return af the King Mean Girls

Em um .JSP, com scripting


<table> <% String[] items - (String[]) request.getAttribute(nmovieList"); String var-null; for (int i = O; i < items.length; i++) { var = items[i];

%>
<tr><td><%= <% } %> </table> var %></td></tr>

446

usando JSTL

<c:forEach>
A tag <c:forEach> da JSTL perfeita para isto ~ ela lhe fornece uma maneira simples de iterar atravs de arrays e de colees.
(FaIa.l"ew\lJS s6bl"f eS+4 dtl"e.f-;va

Cdigo JSP
<%@ taglib <htrnl><body> <strong> <br><br> Movie list:</strong>

.r

flJ.jllb

IIl.lJ,tsIJ,dto.PI+e PlIJ Cfi.P,{+VI6)


%>

prefix="c" uri=''http://java.sun.com/jsp/jstl/core''

<table> <c:forEach <tr> <td>${rnovie}</td> </tr> </c:forEach> </table> var="movie" items="${movieList}" >

~
Fa; V'" 11J6Paj;l"lJ,vs dlJ (J.f{,~l i?rf-elt'1J (IJ aft'lbvf IIl.6vteLts+) e e;dbe Cl1.dl2 ele",e,,+ elll. lJIIl.o.PlIJVIJ, IIi1t.IJ..(s+a. IJ"'Q ClJlvPltl, +o.belo.

</body></htrnl>

<fI":> si5l1tii'c1J. tible

JeIJW (Lti1t.o.
/)12+12

Lembrete rpido sobre tabelas HTML


<table> <tr> <tr> <tr>

<+d:> Si5l1litcl2 ti!;le

(/)e.JIJS de tiIJele.).

</tr>

</tr>

</tr>

</table>

As tabelas so bem simples. Elas possuem clulas, organizadas em linhas e colunas, e os dados so inseridos dentro das clulas. O esquema dizer tabela quantas linhas e colunas voc deseja. As linhas so definidas com a tag <tr> (Table Row), e as colunas so definidas com a tag <td> (Table Data). O nmero de linhas vem do nmero de tags <tr>, e o nmero de colunas vem do nmero de tags <td> que voc colocar dentro das tags <tr></tr>. Os dados a serem exibidos so colocados somente dentro das tags <td></td>!

voc est

li'

447

a tag <c:forEach>

(1eseonstruindo <e:forEaeh>
A tag <c:forEach> integra-se perfeitamente a um loop for - a tag repete o corpo do elemento com a tagfor each na coleo (e estamos usando "coleo", significando um array, ou Coleo, ou Map, ou String delimitada por vrgulas). A caracterstica principal que a tag atribui cada elemento da coleo varivel que voc declara com o atributo varo

If
A tag <c:forEach>

Val"l-4ve/ ~ve 41"~Q;ePla cada

'iLJ.I.A,JIJ-r't) da ccle{;tJ, a
ClJ.d

f) sev

valtu' se

r+eN.{itJ,

f) "tJe+e.
CtJ!f!';".;

var="movie"

items="${movieList}"
I:'

>

f/ S+I"'YJ5
dell)"'l--ado. ptJl'

1111'5Vlo.s)s tJbI'f!
</)

allt11 tJ ltlp #leve seI" fel+".

Stri~g[]

ite~s =

(string[])

request.getAtribute(nmovieList"); i++)

for !(int i

=i0; i < items.length;

string movie = items[i]; ot.println(movie);

V4I'S+a+vs

CI'I"II.(1<9\14 Pl(lV4 Vikl'l-4l1el

Obtendo um contador de loops com o atributo opcional varStatus

o.f'~a]ePltJ. (I<9\aIYJs+~Cr(l. dejaVax, sel'vle+ dspds+t.CtJl"f.LtUlP ~S+a+vs.

<table> <c:forEach <tr> var="movie" items="${movieList)" varStatus="movieLoopCount" >

<td>Count: </tr>

${movieLoopCount.count}</td> ""

<tr><td>${ffiOVie} <br><br></td>~ </tr> </c:forEach> </table>

\
tJ.

1iil'jQ<9\<fJS paNJ. alie LtJp~S+P.+lIs pl"cprled4de

dfJ.sse

+ePlt.a V<9\4 CClIPl+ 3ve lhe

Coun0
Return of the King

f6I"Plf!ffJ. " lIal61' a+vo./ d" ctJPl-l-lAdtl' de r+e1'4f';es.


fJ!>\ (lJ!>\/tU)P "l",) (C<l~tJ

tl r

MeanGirl

ConnO

448 captulo 9

usando JSTL

Voc pode at tMestMO at1it1hartags <c:forEach>


E se voc tiver algo como uma coleo de colees? Ou um array de arrays? Voc pode aninhar tags <c:forEach> para obter estruturas de tabelas mais complexas. Neste exemplo, colocamos arrays String dentro de uma ArrayList, e ento tomamos a ArrayList um atributo de solicitao. O JSP precisa fazer um loop atravs da ArrayList para obter cada um dos arrays String, e depois fazer um loop atravs de cada array String para exibir os elementos propriamente ditos do array. Cdigo do Servlet
String[] moviesl ~ {nMatrix RevolutionsH, nKill BillH, nBoondock SaintsH}; String[] movies2 = {nAmelieH, nReturn of the KingH, nMean GirlsH}; java.util.List movieList = new java.util.ArrayList(); movieList.add(moviesl); movieList.add(movies2); request.setAttribute(nmoviesH, movieList);

Cdigo JSP

<table>

r
(.
I

tJ

a.";'f'ibrr/-lJ de

(a fJrf'f"I...i'S";'

C
IlJlJf I I /~I'i'11J . L

, <c:forEach var="movie" <c:forEach var=HlistElementH

"-

items="${l.istEl.ement)"
items=H${movies}H
I\"

>

>

<tr> <td>${movie}</td> </tr>

'--

I </ c: forEach>
</c:forEach>

./ .5";'f'I;'<: '"" tlit\ dS af'f'4~SI (lI! IfJNJ.it\a.ff'i/;(lI'fJS t:/fJ a.ff'tbv.flJ vaf' d If e~l'i'1.

</table>

Boondock Saints Amelie Retum of the King Mean Girls

voc est

449

a tag <c:forEach>

N9 exlst~m

fetguntls Idl9tt8

r:

Cuidado!

Como voc sabia que o atributo "varStatus" era uma instncia do que quer que fosse, e como voc sabia que era uma propriedade "count"?

Veja 1&9.'A

varivel "var" tem como escopo APENAS a tag!

1\: Eh ... ns olhamos

isso mesmo, escopo da tag. Ou seja,


no se trata de um escopo abrangente ao qual voc possa vincular atributos como nos outros quatro - page, request, session, application. O escopo da tag significa simplesmente que a varivel foi declarada DENTRO de um loop. E voc j sabe o que isso significa em termos de lava. Voc ver que, para a maioria das outras tags, uma varivel definida com um atributo "var" ser visvel a qualquer escopo que voc definir especificamente (usando um atributo "scope" opcional), OU, a varivel usar o padro de escopo de pgina. Assim, no se engane com cdigo que tente usar a varivel em algum ponto ABAIXO do fim do corpo da tag <c:forEach>!
<c:forEach var="foo" >

na resposta. Est tudo na especificao da JSTL 1.1. Se voc ainda no tiver a especificao, baixe-a AGORA (a introduo deste livro lhe diz onde obter as especificaes abordadas no livro). Ela A referncia para todas as tags da JSTL, e lhe informa todos os atributos possveis (sejam eles opcionais ou obrigatrios), o tipo do atributo, e muitos outros detalhes sobre o modo de usar a tag. Tudo o que voc precisa saber sobre estas tags (para o exame) se encontra neste captulo. Mas algumas das tags tm algumas outras opes que no abordamos aqui, ento voc poder desejar dar uma olhada na especificao.

r:

J que voc sabe mais do que est disposto a dizer sobre esta tag ... ela fornece uma maneira de modificar os passos da iterao? Em um loop for Java real, eu no preciso fazer i++, posso fazer i +=3, por exemplo, para obter cada terceiro elemento, em vez de todos os elementos ...

items="${fooList}"

1\: Sem problemas.

A tag <c:forEach> possui atributos opcionais para begin, end (caso voc deseje iterar sobre um subconjunto da coleo), e step, caso voc deseje pular alguns elementos.

${foo}
</c:forEach>

~tJk

lJ-tJ/! fJr v~l'i-:vel


${

r: o

es';": fc.l'~

/c.

"c" em <c:forEach> um prefixo obrigatrio?

1\: Bom,

obrigatrio usar algum prefixo, certamente; todas as tags e funes EL devem ter um prefixo para dar ao Container o namespace para a tag ou nome de funo em questo. Mas voc no PRECISA nomear o prefixo com "c". Esta apenas a conveno para o conjunto de tags da JSTL conhecidas como "centrais". Recomendamos usar algo diferente de "c" como prefixo sempre que voc quiser confundir totalmente os seus colegas de trabalho.

Pode ajudar se voc pensar no escopo da tag como sendo idntico ao escopo do bloco no bom e velho cdigo lava. Um exemplo o loop for que todos vocs conhecem e amam:
for i++) (int i ~ O; i < items.length; {

x +

i;

IJfitJ!! fJr
es';":

1/ U

h~N. Jij

doSomethin

450

cap,ifu/o 9

usando JSTL

Fazendo

utMa incluso condicional

COtM <c:if>

Imagine que voc tenha uma pgina em que os usurios possam ver comentrios deixados por outros usurios. E imagine que os membros tambm possam postar comentrios, mas visitantes que no so membros no possam. Voc deseja que todos obtenham a mesma pgina, mas que os membros "vejam" mais informaes da pgina. Voc precisa de um <jsp:include > condicional e, claro, voc no quer faz-Io com scripts!

o que os membros vem

o que os NO-membros vem


Member Comments
This site rocks. This sUe is coa!. This sUe is stupid.

Member Comments
This site rocks. This sUe is coa!. This sUe is

Cdigo JSP
<%@ taglib prefix="c" uri=''http://java.sun.com/jsp/jstl/core'' <html><body> <strong>Member Comments</strong> <br> <hr>${COmmentList}<hr~ $ {userType %>

<c: if test="

eq 'member' }" > '"


\

Sy,t'JJ1/"f!. Ye'y~ deftJ1aJe~ t!.'5y~ pt'J~t'JJ " IJ.-!-ri/;Y+" yser,peJ J" eMIYSy:rl",J1fJ.$ lJ1f"r~tJ,{;es de
/(;51';;

<~sp: include page="inputComments. jSf" /> ~~


</body></html>

</c:1f>

\Si'~J s" aspas

sIMPLJ .. S

Pgina includa ("inputComments.jsp") )

Je ~le vce p"Je lSiJ,r I1fJ.$ syas eJ1v(JlveI1J~ ~elt\ber, AJo se

<form action="commentsProcess.jsp" method="post"> Add your comment: <br> <textarea name-"input" cols="40" rows~"lO"></textarea> <input name="commentSubmit" type="button" value~"Add </form>

<br> Comment">

voc est

." 451

a tag <c:if>

Mas, e se voc precisar de

Ut\1

else1

E se voc quiser fazer uma coisa se a condio for verdadeira, e uma outra coisa se a condio for falsa? Em outras palavras, e se quisssemos exibir ou uma coisa ou outra, mas sem que ningum veja ambas? A tag <c:if> da pgina anterior funcionou bem, porque a lgica era: todos vem a primeira parte e, em seguida, se a condio do teste for verdadeira, algo mais exibido. Mas imagine agora este cenrio: voc tem um site de venda de carros, e deseja customizar o ttulo que aparece em cada pgina, com base em um atributo do usurio definido anteriormente na sesso. A maior parte da pgina a mesma, independentemente do usurio, mas cada um v um ttulo customizado - um que reflita a motivao pessoal do usurio para comprar (afinal, estamos tentando vender-lhe um carro para ficarmos indecentemente ricos). No incio da sesso, um formulrio pede ao usurio que escolha o que mais importante ...

Imas1ne um ste de uma emptesa de venda de canos. A ptlmell'a pgIna Pel'Eunta aI.)usutI9 9 qUe ~ J-' acha 111ms lmp(ntante. AssIm C9m9 um lwm
!
I 1"
_?

vendeu)t. as b~l11as que 1 v p I' 1 1 Cal'actetlStlCaS f .0 ttiam eLaS do catt9 lr9 cust9m17-m' a aptesenta9 C9m br~"le I' ,,! (:[0 usuan9, f o na pte-retenC1a
1 de l1]9c[9'i~le ca da uma das cal'aG'tetstkas d9 catt9

No incio da sesso:

patea ter sld9 telta C)m pessoaIs em

he Brakes
ur advanced anti-lock brake system (ABS) is ngineered to give you the ability to steer even as ou're stopping. We have the best speed sensors of car this size.

452

usando JSTL

tag <c:if> no funcionar para isto

No h como fazer exatamente o que queremos usando-se a tag <c:if>, porque ela no possui um "else". Podemos quase faz-Io, usando algo como: JSP usando <c:if>, mas no funciona corretamente ..

<c:if test~"${userPref~~'performance'}" > Now you can stop even if you <em>do</em> drive insanely fast .. </c:if> <c:if test~"${userPref~='safety'}ff > Our brakes won't lock up no matter how bad a driver you are. </c:if> <c:if test~"${userPref=~'maintenance'}" > Lost your tech job? No problem-you won't have to service these brakes for at least three years. </c:if>

Jl,t~s6)lIf lJ'; I.~lI~~


<!-continua com o restante da pgina

se lIserR-el

,,';IJ h.1" "(,,t.lI11<1a as -I-i-l-ul-pal"lJ?


ver -->

pj:;es?

Je eSJi)eclflc;~1" (I~
que TODOS devero

A tag <c:it> no funcionar, a no ser que tenhamos CERTEZA de que nunca precisaremos de um valor-padro. O que realmente precisamos de algo como um construtor if/else:*
li'

fi
usel"Prel +e"J.fj,

JSP com script, fazendo o que desejamos

C"sli/(r(

ve

stillJ eli''1MIJ ell<laljvII<I ~ll<le,,+ fI.,,+el"i'l" '14 sess';.

<html><body><h2> <% String pref ~ (String) session.getAttribute("userPref"); if (pref.equals("performance")) { out.println("Now you can stop even if you <em>do</em> drive insanely fast."); } else if (pref. equals ("safety")) { out.println("Our brakes won't lock up, no matter how bad a driver you are.

")

else if (pref. equals ("maintenance")) { out.println(" Lost your tech job? No problem-you won't have to service these brakes for at least three years."); else { // userPref no nenhuma das opes, ento exibe o titulo-padro out.println("Our brakes are the best.");

} %>
</h2><strong>The Brakes</strong> <br> Our advanced anti-lock brake system (ABS) is engineered steer even as you're stopping. We have the best speed sensors of any car this size. <br> </body></html> to give you the ability to

*Sim, ns concordamos

que quase sempre h

uma abordagem melhor do que usar testes if encadeados. Mas voc ter que confiar em ns at aprender como tudo isso funciona ...

voc est

453

o tag <c:choose>

I will CHOOSE you WHEN you are ready to give up your obsession with Pilotes. OTHERWISE, 1'11have to go with Kenny for the synchronized swim team.

D
O

A tag <c:choose> e suas parceiras <c:whe.,> e <c:otherwise>


<c:choose> <c:when test="${userPref ==

fJrpf!."G.S IJ M des.fes

)1/4+I'

C"l'pS "PIdl/il'id
N

<.c:+l.el'~;;i$e

i"1'tJ. l'd41'.

(AJ"i." ~ ClJ'\I/IJ'\ clJ'\tJ.mlc $Wi+cl. "el'it.1/1J'\ fo./I-+t.NV;t.)

- 1'i4 1.0.

'performance'}"> if you <em>do</em> drive insanely fast.

Now you can stop even </c:when>

<c:when </c:when>

test="${userPref will

==

'safety'}"> lock up, no matter how bad a driver you are.

Our brakes

never

<c:when

test="${userPref tech

'maintenance'}"> won't have to service these brakes

Lost your for at least </c:when> three

job? No problem--you

years.

<c:otherwise> Our brakes </c:otherwise> </c:choose> <!-o resto da pgina segue are the best.

~<~---

Se l'ie"t.vlJ'\ dIJS +es+es

<'c:wt.e,,>

fIJI'

vel'Jo.detl'; pfJ.dl'':i.
aqui ... -->

., <'C:+td!l'wtse>

NJdlll. C<)lJ'\

AJ+fJ.: AJ-o <'c:ct..,se>

bl'~fJ.+;l'i6

+el'it.a v",a

sve +~ +~<.c:a+t.eI'Wise>.
ti.

454

CB}JtIJ}O

A tag <e:set> ... 'Imito ",ais legal que a <jsp:setProperty>


A tag <jsp:setProperty> s capaz de fazer uma coisa: definir a propriedade de um bean. Mas, e se voc quiser definir um valor em um Map? E se quiser criar uma nova entrada em um Map? Ou, se simplesmente quiser criar um novo atributo no escopo da solicitao? Voc tem todas essas possibilidades com <c:set>, mas ter que aprender algumas regras simples. Set vem em dois sabores: var e target. A verso var serve para definir variveis de atributos, e a verso target serve para definir propriedades de beans ou valores de Maps. Cada um dos dois sabores vem com duas variantes: com ou sem um corpo. O corpo de <c:set> apenas uma outra forma de inserir o valor.

Definindo uma varivel de atributo var com <c:set>

OSEM

corpo
<c:set

var="userLevel"

Se Ai/lrfJ /'wver ti*'. o.+l'i911+" tie esc"p" tia sess';tJ ct.o.*'.atitJ lIset'Leve/ eS+4 +"5 crra tl'JIllptJJ1titJ-se 3l1e tJ 4+l'l'bll+ valI/e I?:i'c J1vltJJ.

scope~"session"

value~"Cowboy"

/>

U
J

/ e
<c:set var="Fido" value="${person.dog}"

/>

eCOMcorpo
<c: set var="userLevel
Sheriff, </c:set>
Ir

scope="session"
Cowgirl
J\"

r
>

Le*'.!Jl'e-se,; J1atilJ. til!!bal'ra a3tH ~{.iat1titla


+"5

-I-rvel' {.i'JI Ctlf'ptl.

Bartender,

/ \..... () Ctlt'ptl li!1.vali"ti e IIsatic I:*'.<I vaieI' tia

Se o valor for avaliado como nulo, a varivel ser REMOVIDA! Isso mesmo, removida.
Imagine que para o valor (no corpo da tag ou usando ~ a~ributo value), ,:oc~ use ${person.dog}. Se ${person.dog} avaliar como nulo, (szgnifican_do que nao ;;R nenhuma person, ou a propriedade dog de pe;son nu!a), entao: se HO.~ o.I \' S e um atributo de varivel com um nome "Fido', esseeatrzbuto ~e:a remov~ voc no especificar um escopo, ele comear olhando na pagzna, ~epOls n~ solicitao, etc.) Isto acontece, mesmo se o a~ributo "Fido" tiver szdo defimdo originalmente como String, Duck ou Broccoll.

voc est

iP

455

a tag <c:set>

Usa"do <c:set>

COtM

beatls e Maps

Este sabor de <C"set> ( com as suas d . . s~~e apenas para duas coisas' .uas vanantes - com ou sem co o 80 lsso.Y~c no pode uS_Io'::r;~~d~des de ?eans e valores de Ja~ arrays. E sImples - voc fornece a ele IClOn?r C01sasa listas, nem a . nome da propriedade/chave e o vaI OL o objeto (um bean ou um Map) , o

Definindo uma propriedade Ouvalor de t

arget com <c:set>

SEM corpo

GCOMcorpo

o "target" deve avaliar para o OBJETO! No digite o nome de String "id" do atributo do bean ou Map!
Isto importante de se lembrar. Na tag <c:set>, o atributo "target" parece funcionar como o "id" de <jsp:setProperty >. At mesmo o atributo "var" na outra verso de <c:set> usa uma String literal que representa o nome do atributo do escopo. MAS. .. no assim quefunciona com "target"! Com o atributo "target", voc NO digita a String literal que representa o nome sob o qual o atributo foi vinculado pgina, ao escopo, etc. Em vez disso, o atributo "target" precisa de um valor que resolva para o ALVO REAL. Isso significa uma expresso EL ou uma expresso de script %= %, ou algo que ainda no vimos: <jsp:attribute>.

456

usando JSTL

Pomos principais e pegadinhas

COtM

<c:set>

Sim, <c:set> fcil de usar, mas h algumas questes de que voc precisa se lembrar: l'l9 e)st~m

~ No possvel ter AMBOS os atributos "var" e "target" ao mesmo tempo em um <c:set>. ~ "Scope" opcional, mas, se no us10, o padro o page scope. ~ Se o "value" for nulo, o atributo nomeado por "var" ser remo"ido! ~ Se o atributo nomeado por "var" no existir, ele ser criado, mas apenas se "value" no for nulo. ~ Se a expresso "target" for nula, o Container gera uma exceo. ~ O "target" serve para inserir uma expresso que resolva para o Objeto Real. Se voc inserir uma String literal que represente o nome de "id" do bean ou Map, no funcionar. Em outras palavras, "target" no serve para o nome do atributo do bean ou Map - e sim, para o prprio objeto do atributo. ~ Se a expresso "target" no for um Map, nem um bean, o Container gera uma exceo. ~ Se a expresso "target" for um bean, mas este no tiver uma propriedade que coincida com "property", o Container gera uma exceo. Mas cuidado, porque a expresso EL por si mesma NO causar uma exceo se a propriedade no existir. Ento, embora ${fooBean.notAProperty} no cause uma exceo por si mesma (apenas retorna nulo), se essa mesma "notAProperty" for o valor de um atributo "target", o Container gera uma exceo.

Yet.sUntas

Idl9tlS

Y: Por que eu usaria a verso com corpo, ao invs da verso sem corpo?
Parece que elas fazem exatamente a mesma coisa.

1\: Isso porque elas DE FATO ... fazem a

mesma coisa. A verso com corpo apenas para convenincia, quando voc deseja mais espao para o valor. Poderia ser uma expresso longa e complexa, por exemplo, e coloc-Ia no corpo torna-a mais fcil de ler.

Y: Se eu no especificar

um escopo, isso significa que o Container encontrar atributos APENAS dentro do escopo de pgina, ou ele faz uma busca comeando com o escopo de pgina?
"scope" opconal na tag, e estiver usando "var" ou "target", o Container buscar escopos na ordem que seria de se esperar - pgina, depois solicitao, depois sesso, depois aplicao (contexto). Se voc estiver usando a verso "var" sem um escopo, e o Container no conseguir achar um atributo com o nome em questo em nenhum dos quatro escopos, o Container cria um novo atributo no escopo da pgina.

1\: Se voc no usar o atributo

Y: Por que a palavra "atributo" to sobrecarrega da? Ela significa tanto "as
coisas que so colocadas dentro de tags", como "as coisas que so vinculadas a objetos em um dos quatro escopos". Ento, no fim das contas voc tem um atributo de uma tag cujo valor um atributo da pgina e...

1\: Tudo bem, j entendemos.

Mas assim que as coisas so. Mais uma vez, ningum pediu a NOSSA opinio. Ns teramos chamado os objetos vinculados de algo como, sei l, "objetos vinculados".

voc est

l:>

457

a tag <c:remove>

<c:remove> faz setttido


Concordamos com o Dick - usar um set para remover algo parece errado (mas lembre-se, o set somente remove quando vo passa a ele um valor nulo). A tag <c:remove> intuitiva e simples:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" <html><body> <c:set var="userStatus" ${userStatus} var="u erStatus" scope="request" <br> scope="request" value-"Brilliant"

%>

/>

userStatus: <c:remove userStatus </body></html>

/>

is now:

$ {userStatus

t\- ()
<l

eSCl!if6 6fd'an41
<l

eJ

CI!i"''' ~ /

seltlfl';J

eSC<lf<l-f4dI'4<l

de fIJ.j1i14.

userStatus: Brilliant userStatus is now:

458

usando JSTL

Teste a sua memria sobre as Tags


Se estiver estudando para o exame, no pule esta parte. As respostas encontram-se no final do captulo.

o o

Preencha o nome do atributo opcional. <c: forEach $ {rnoviel var="rnovie" </c:forEach> iternS~"${rnOVieListl"l ---------I="foo" >

Preencha o nome do atributo que est faltando. ~I~"$ {userPref~=' safety' <c: if I Maybe you should just walk ... </c:if> l" >

e
o

Preencha o nome do atributo que est faltando.

<c: set var="userLevel"

scope~" session"

~I ="foo"

/>

Preencha o nome das ta9s (dois tipos de ta9s diferentes) e o nome do atributo que est faltando. <c:choose> <c:I
II 1 ~"${userPref == 'perforrnance' Now you can stop even if you <ern>do</ern> drive

l"> insanely

fast.

<c:

1>

Our brakes

are the best. I>

</c:I </c:choose>

voc est

459

a tag

COIft a <e:ilftport.:> h' de itle/uir eOtltedo' a agora


At aqu'1, temos usado d

'"

nS Iftatleiras

Contedo de um o uas maneiras diferente . . uma outra m . utro recurso para um JSP M s de, a~IClOnar anerra, usando a JSTL. . as ha alnda

OA

diretiva incJude
<%@

. . a lClOna o Conted atrIbuto file para a p' . o a partir do valor d traduo. agllla atual no momento de o

EstatlCar,

includ~ file-a d' . -

Header.htmlff

%>

AAV aao-padro
A

. ~sp.lncJude> <J$P'in 1 d
. c u e pag~=ffH

<-

._

/> DInamica' d' . atrib . a lClona o Contedo . . ~to page para a po-in a partIr do valor do solICitao. ;:, a atual, no momento da

' ea d er']Spff

ftc. cM+rtrliJ ag JSTL <c:import>


i';J(;/vlles;

dcS cv+r<:>s d41's a VI'I de <C:"''''f'4r+:> pde


dI} C.C'1+4(l1er

<c: illlport url="htt


A

.
P'//WWw.Wckedl 3m

se lacll,li'511:.i"lcl'l1.

webl

DInamica' d' . Y art . comi s k 1 atrib alCl0na O contedo' Y er/horse.htmlff uto URL para a ' . a partIr do valor d solicitafo. Funcion~a~lll~ atual, no momento da o que a <jsp:inc1ude> p at~ca~ente da mesma fc , mas e maIS pod nua erosa e flexvel.

~~

/>

odos eles tm nomes de atributos (E cuidado com a diferena

diferentes!

entre "include" e "import".)

Cada um dos trs mecanismos para incluir contedo a partir de outro recurso para dentro do seu JSP usa uma palavra diferente para o atributo. A diretiva include usa file, a <jsp:incZude> usa page, e a tag JSTL <c:import> usa urI. Isto faz sentido, pensando bem ... mas voc precisa memorizar todas as trs. A diretiva servia originalmente para templates estticos de layout, como headers HTML. Em outras palavras, um "arquivo". A <jsp:include> servia mais para contedo dinmico vindo de JSPs, ento deram ao atributo o nome "page" para refletir isso. O atributo para <c:import> recebeu o nome daquilo que voc fornece a ele - uma URL! Lembre-se, os dois primeiros "includes" no podem ir alm do Container atual, mas <c:import> sim.

460

usando JSTL

A <c:ilMport> consegue alcanar o LAVO vE FORA da aplicao web