Você está na página 1de 30

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>(Jr'!JtlfQS'4r~e+ras f

Sii:J sa" 'M(JS "4 /,(JNJ.lj<j f A- c'f';c

/I i ' tl t..(J/I'f"f'fJ,I7er';'icta't"f;tJ.dc. 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. seria mais coerente de ser uma query que o usurio digitou. que A cpia do parmetro de armazenado como atributo no escopo sesso? V (5el"vle-l-

, 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 eSCIJpfJSIJIi'ci"-I-af'i.fJ. '14 A. IJPftJ.aC es-rtJ. li1CIJI"I"e-r~ p41"'/;ve 9tJ.3ve '1aIJ e especIllcIJ ". I' - 1'". / ,

Jehl"lti\/i1lJ.JIJ. sess'i.tJ.> ele Jevel"i"IJ. seI" IJ.1"1ti\tt.je'llJ.JIJ esclJf" /'Ia

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 .. l" h

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-!-" es-h tal' se 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 vlfla ses s';tJ VStJ.#1J /iVl-I-(jdlJ 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 112..[J / J P"5. J 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

. . C"','"4ji., d., .,Qie.f6. lllJ C . D epen d en d o dI' c asse cUJometo d o cna um a v RequestDispatcher, o caminho para o recurso a ser enviado mudar.
- Dffi., ~: se set/ set'lIle.f

DD. RequestDispatcher, Independentemente NO mudar. DE.

da caminho para o recurso aum enviado o classe cujo mtodo cria ser

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

~C4S 3t1f p6SstlflJ\ ~tlfla c6r). "146 e c6#'Ise!l.t:ll>'Ul


(1.10\

s-k

, / L D IJ'tctielc (a ICjtCa tic $1e56c1(;)'n:"1J't


".

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 pode tMotltorar as respostas ele

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 manter Ns podemos usar um objeto HttpSession sabia disso. 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, f) H Se-l-c.lJIJl:te e apel1l1.S
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 HTTP/1.1 ?~O0EKSSIONIO=OAAB6C80E415


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" e vll>la sessa6 "(JVil) a se ;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._ J_ seSS46 pre-exls-n:~

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. ess';,(J s


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 cliente COI1"l hea ir ignorar os Osders "Set-Cookie" da

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 s~s:;~:~~e .. a . . 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~:: nunca dev.olve quaudv "7,ce,':u,;;;; que uma que. sem r.e re Z' t. ~~erdadeiro" uma so ler ..'P. o isNewvri header O c coa kie daseSSlOn ID . tenha um ne l,i do rene . a/o .

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 sf!.Ssu,n 4l 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 espec/!lc6 I , / 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.. am,q~O.8,vldeo/x_' .. _ /xml,apPlication/xhtm/+xml -. . ,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\: session 10 dose o Container no conse~uir Lembre-se, uma 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 nem no seu contexto objeto . Sim, a reescrita de URL especfica por fabricante. O chama na sOliclta?aoLembre_se de que o objeto sessao. _ d URL todo Tomcat usa o ponto-e-vrgula ";" para anexar a informao oU no rocesSo d e codijicaao a 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'8I'leslfl.t'J. si
() 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 a, ..sOdlcltaOcomo 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