Upload
jobson-medeiros
View
30
Download
0
Embed Size (px)
Citation preview
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 1/25
(íle 3ver II./lAl'dal' eSfp'ylJ
"1a si/a ."a~i/I"'a p4ra jatl41'fJ" v "-n.e S,•.s ca"'"PIU:".f.e
" li";,,ba.f.e" ,.)
gerenciamento da sessão
Livrat'ldo-se das sessões
A cliente entra, inicia uma sessão, muda de idéia e
sai do site. Ou a cliente entra, inicia uma sessão e seu
browser trava. Ou a cliente entra, inicia uma sessão e a
finaliza fazendo uma compra (check-out do carrinho de
compras). Ou o computador dela trava. Seja o que/oro
A questão é que os objetos da sessão usam recursos.
Você não quer que as sessões fiquem lá além do tempo
necessário. Lembre-se, o protocolo HTTP não tem
nenhum mecanismo que informe ao servidor que a cliente
já foi. (Em termos de aplicação distribuída, para aquelesque estão familiarizados, não 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 é segurodestruir uma sessão?
+uais seriam as estratégias que você (e o Container)
usariam para gerenciar o número de sessões e eliminar
as desnecessárias? Quais são algumas das maneiras
possíveis que o Container poderia saber que uma sessãonão é mais necessária?
Pense um pouco e dê uma olhada na API HttpSession
algumas páginas adiante para conseguir algumas dicas.
"Algumas aplicações distribuídas 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 específicos, 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
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 2/25
sessões abandonadas
CotttOqueretttos que ele futtciotte ...
Gostaríamos que o Container reconhecesse quando umasessão ficasse inativa por muito tempo e a destruísse.É claro que teríamos que brigar com o Container para
que ele soubesse o que "muito tempo" realmente querdizer. Vinte minutos é muito tempo? Uma hora? Umdia? (Talvez exista uma maneira de informarmos aoContainer o que é "muito tempo".)
oDiane seleciona "Escura"e c1ica no botão submit.
o Container envia a
solicitação para uma nova
thread do servlet BeerApp.
Web Container
o Container cria uma nova
sessão, ID nº 343. O cookie
"JSESSIONID" é enviado de
volta para Diane na resposta
(não exibido).
8 Diane desaparecemisteriosamente.
e Diane não retorna.Os minutos passam ...
242 capítulo6
O Container faz o que qualquer Container
faria em seu tempo vago (embora
provavelmente haja um monte de clientes
a serem atendidos).
Web Container
O Container checa o estado da sessão
nº 343 e descobre que nenhuma
solicitação chegou com aquela sessionID durante 20 minutos.
Web Container
A sessão iniciada porDiane ainda está lá...
esperando ... abandonada.
O Container diz "20 minutos
é muito tempo. Ela não
voltou.", e destrói a pobre eabandonada sessão.
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 3/25
A itrterface flttpSessiot1
Tudo com o que você se preocupa quando chama ogetSessionO é que você receba uma instância de umaclasse que implemente a interface HtlpSession. É
tarefa do Container criar a implementação.Uma vez que você consegue uma sessão, o que vocêpodejazer com ela?Na maioria das vezes, você usará as sessões para
receber e configurar os atributos do escopo sessão.
Mas tem mais, é claro. Veja se você conseguedescobrir sozinho alguns dos métodos maisimportantes. (As respostas estão na próxima página,então não vire!)
Âpºnte seU lápISo que ele faz
getCreation TimeO
getLastAccessedTimeO
setMaxlnactivelntervalO
getMaxlnactivelntervalO
invalidateO
gerenciamento da sessão
. <<interface>>Javux.servlethttp Ri
Ob. . ttpSession
lo;:ect getAttribute(String)
g getCreationTiStringgetIdO llneO
long getLastAcc .
int getMaxIna .essedTllneOServletC ctzveIntervalO. ontext getSer 1<
vozdinvalidateO v etContexto
bO~leanisNewoVozdr.
enzoveAttrib "voidsetAttr"b ute(Strzng)" z ute(Strin O"
voidsetMaxIn " g, bJect)
/; alguns Outroactz~eInterval(int)
os Inetodos
Para que você o usaria
você está ••. 243
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 4/25
métodos HttpSessíon
Os prit'lcipais tttétodos HttpSessiot'l
Você já conhece os métodos para atributos (getAttributeO,
setAttributeO, removeAttribute()), mas aqui estão alguns dos mais
importantes de que você pode precisar na sua aplicação (e que
podem cair na prova).
o que ele faz Para que você o usaria
Retoma o momentoescobrir a duração da sessão. Vocêode decidir restringir que certas sessõesriada pela primeira
ultrapassem um determinado período deempo. Por exemplo, você pode dizer: "Uma
vez logado, você tem exatamente IO minutosara completar este formulário ..."
Para descobrir quando um cliente acessouela última vez esta sessão. Você pode usá-Iorecebeu uma
para decidir que, caso o cliente tenha saídoá muito tempo, você enviará um e-mailerguntando se ele vai retomar. Ou usar onvalidateO na sessão.ara fazer com que uma sessão seja encerrada,
s,
depois que um certo período de tempoue você quer permitir
tenha passado, sem que o cliente tenha feito
do
nenhuma solicitação nesta sessão. Esta é umaas formas de reduzir a quantidade de sessões
paradas no seu servidor.
Para determinar por quanto tempo uma
s,
sessão pode permanecer inativa sem perder aermitido entre as
validade. Você pode usá-Io para julgar quanto
e
tempo um cliente inativo ainda possui, antesue sua sessão seja invalidada.ara matar uma sessão, caso o clientesteja inativo ou se você SOUBER que aessão terminou (por exemplo, depois quecliente finaliza uma compra ou se Ioga). Armazenados nestainstância da sessão em si pode ser recicladaelo Container, mas isso não nos importa.invalidate significa que a session ID nãoxiste mais e os atributos foram removidoso objeto sessão.
SUA
Agora que você já conhece estes métodos, você consegue definir
uma estratégia que elimine as sessões abandonadas?
244 capítulo 6
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 5/25
gerencíamento da sessão
oConfigurando o timeout da sessão no DOConfigurar o timeout no DD tem quase o mesmo efeito que
chamar o setMaxInactiveIntervalO em cada sessão que é criada.
eConfigurando o timeout para uma sessão específica
Se você quiser alterar o valor do session-timeout para uma
instância de sessão específica (sem afetar a duração do timeout
em nenhuma sessão da aplicação):
</servlet>
<session-config>
<session-timeout>lS</session-timeout>
</session-config>
</web-app>
() 7'> es+: elJ\ 1J\/~(,rfIJs.1.le ;:/lj 3l1E'se
<web-app ...> (JcllE'l1+e l1'liIJfljer l1el1t.lIlJ\4 s(Jlict+4S'li1J
<servlet> I N "Tr. 1 I_;t1es'T'/J.S(!!SSiM eJt\ I';> Jt\ll1l1"T'IJ$j1J\4rt'-4.
-l,
Boas notícias: não é você que vai acompanhar isto. Está vendo
aqueles métodos acima? Você não tem que usá-Ios para se livrar das
sessões mortas (inativas). O Container pode fazer isto para você.
Três formas de matar uma sessão:
~ Por timeout
~ Você chama o invalidateO no objeto sessão
~ A aplicação cai (trava ou não é distribuída)
Cot1figurat1do O titMeout da sessão
Do
Você não pode estar falando
sério ... então quer dizer que
eu tenho que acompanhar a
atividade da sessão e que eu
tenho que matar as sessões
inativas? O Container não podefazer isso?
session.setMaxlnactivelnterval(20*60);
"() ar/t/ll>lel1+tJu-fa (:'11>I
"tjer ~lIe se tJ
l1el1l.t/lI>I#.
II>IIi1l1+6S;
":5: #. st'ssã(J 114
lia! 11Jcê ct.aJt\Q
!. I. It\'e'T(J;:/ (J e
e-fa;:/a.
Os timeouts no DDestão em MINUTOS!
Eis aqui uma enorme incon!istênci~que devemos prestar atençao ... voce
especifica timeouts no DD usandoMINUTOS, mas se você configura: um
timeout programático, você especifica
em SEGUNDOS!
você está aqui ~ 245
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 6/25
exercício do intervalo da sessão
~
;; ~;; q Imã de GeladeIra Especifiqu~ no DD e~ programatlcamente, que uma
. sessão deve ser destruí da, se ela não receber nenhuma
solicitação por 20 minutos. Nós colocamos o primeiro ímã no
servlet para você e é possível que você nem use todos.
o O
;nactive-interva1><max-~</session-con
-Servlet-----------------------------
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException
I HttpSession I
aogetServletContext() .getSession();
setMaxlnact'
. lvelnterval(
[setTimeout( ] D~i 12000 L-:.=J
I request .\ [] I-se-S-S-i-o-n-IIetSmionTimeout ( !
246 e8pJ'fulo 6
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 7/25
gerencíamento da sessão
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 cadaum 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,9me,sm9 clIe,nte, ace,ssa 9 se,ty'le,t.
~PUbliC void doGet(HttpServletRequest request, HttpServletResponse response)
throws 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 response)
throws 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
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 8/25
respostas dos exercícíos
~
Imã de G-elítdeltít
l\esp9staB
Especifique no DD e programaticamente, que umasessão deve ser destruída, se ela não receber nenhuma
solicitação por 20 minutos.
I <web-app ...> ILeliflbre-sf?.J ., +i"lifle"v-f-~., blJ ~
I <session-con g> I ~especi'flcI4IÁ" f!1ifl Il.{ItJfJro's.
I<session-timeout> I~ </session-timeout>
I <I session-con g> I
I </web-app> I
~Servlet---·--- -------------------------
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException
[ HttpSession 11 session I [J request. getSession ();
lsession. IsetMaxlnactivelnterval( [1200 I~LeJM.f,re-se; .,
e.sped/lctJ.lÁlIJ elifl
248
CBtJ,'tulo 6
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 9/25
gerenciamento da sessão
SBJA 9 C9l1tél1net
I\esp9st:ls
o public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException
response.setContentType(~text/html");
PrintWriter out = response.getWriter();
HttpSession session ~ request.getSession();
session. setAttribute ("foa", "42") isession.setAttribute(~bar", ~420");
session.invalidate() ;
<'String foo = (String)sesslon.ge~~~ribute(~foo");
out.println(~Foo: ~ + foo);
Resultado: ocorrerá uma exceção deruntime (lllegaIStateException), porquevocê não pode ter um atributo DEPOIS
que uma sessão já tenha sido invalidada.
~
><r! M.Vt.f.4 -I-I!./'de pa/'I!. ct.l!.tfP,a/'ó
5e+A'ff/'lbvhÜ 114Sf!SSã6PÓ/'1JVf!
f!14j: FoI
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException
response.setContentType(~text/html");
PrintWriter out = response.getWriter();
A-3Vl es-h.*t6S 161"5411d6 v*t-A""eóv-I- IJ-d.pIl}ro dI/.
.•••seSSã6Jf>61$ eS+4*t.:)s dl;f!l1da:
-A""e(w-l- depill'$ de ()
de 1;'tJ.-A··.lldl/.de.if (session.isNew(») {
out.println(~This i~
else {
out. println (~Welcome back!"); p"de Ct.QtfP,fU'ó} Ai. ""
out. println (~Foo: ~ + session. getAttribute (~foo") ); ts ew();tfP, VtfP,aSf:SSQó
3Vfjt~f"l iÍ'IVo.lldt!.dl!../1;r+"11.f.4; esh:" tfP,estfP,,,
I"
pr"b1e.tfP,fJ.da cadljtl fJ.C/~fJ.••••• '" 1_-V.:)cf 114IJpóde ct.atfP,fJ.rf!s-n:;
tfP,:+t>dó f,l)j V,l)j4 sfssã.,
1i?lIalldadfJ..
Resultado: ocorrerá uma exceção deruntime (lllegaIStateException), porquevocê não pode chamar o isNewO na sessãoDEPOIS que ela tenha sido invalidada.Configurar o intervalo máximo deinatividade em O significa que a sessão vaiexpirar e ser invalidada imediatamente!
HttpSession session ~ request.getSession();
session.setAttribute(~foo", ~42");
session.setMaxlnactivelnterval(O);
~
você está aqui.. 249
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 10/25
custon cookies
yT9cê p9de usétt 95 c99kles péttét
tt9Cétt 9S pq.tes de Stt'lnb n9me!
Yét19tentte 9 setYld9t e 9 cl1ente.
O sety'id9t enYIa 9 c99kIe ét9
clIente, Cjye9 enVIa de Y9ltétem
cétda S911c1taçã9subse<tiiente.
Os c99kles da sessà.9 S9mem
<tuand9 9 6t9Wset d9 clIente éencettad9, mas V9ce rODE dIzet
n9
dep915 ~.:ueelelIente
tecLat seu
Posso usar cookies para outras coisas, ou
eles são apeKas para sessões?
Ainda que os cookies tenham sido originalmentedesenvolvidos para ajudar no suporte do estado da
sessão, você pode usar cookies customizados para
outras tarefas. Lembre-se, um cookie nada mais é
do que um pequeno pedaço 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 solicitação.
Uma coisa legal dos cookies é que o usuário não
se envolve - esta troca é automática (supondo que
o cliente tenha habilitado cookies, naturalmente).
Por padrão, um cookie vive somente enquanto
dura uma sessão; uma vez que o cliente fecha
o browser, o cookie desaparece. É assim queo cookie "JSESSIONID" funciona. Mas você
pode mandar um cookie permanecer mesmo
DEPOIS que o browser éfechado.
Dessa forma, a sua aplicação ainda pode obter a
informação do cookie, mesmo que a sessão com
o cliente já tenha sido finalizada há muito tempo.
Imagine que o Kim queira mostrar o nome do
usuário cada vez que ele retome ao site da cerveja.
Então, ele configura o cookie na primeira vez que
recebe o nome do cliente, e se obtiver o cookie de
volta com uma solicitação, ele sabe que não tem
que pedir o nome de novo. E não importa se o
cliente simplesmente reiniciou o browser ou esteve
fora por uma semana!
HTTP/l.l 200 OK _ToroasHirschSet-Cookie: usernaroe-
Content-Type: text!htm1L gth. 397
Content- en . 200303:25:40 GMTDate: Wed, 19 Nov
. Anache-Coyote/l.1erver.t'
Connection: close
<htrol>
<lhtrol>
~~~.~lect~selectBeerTaste2.do HTTPll 1. w.W1Ckedlysmart.com .
User-Agent: Mozi11a/5.0
Cookie: username==TomasH' hAccept· textl 1 . Irscht 1· ~ Xli ,apphcation/xml a r .. m ,q-O.9,textlplaiu·q==o 8 'd ,pp IcatlOn/xhtml+xml textl]P' . ,. ,VI eo/x mn . ,eg,Image/glf;q==O.2, *1*;q==O.1 - g,lmage/png,imagel
Accept-Language: en-us,en;q==O.5
Accept-Eucoding: gzip,deflate
r() c/tf!,,-h e"ll/tl 15.f-., de V.,/.f-o..
\() Si!I'ViflM' i!"Vltl i5.f-., ,l'lmeil'''.
250 capítulo 6
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 11/25
gerencíamento da sessão
Usando cooldes COtH a API Servlet
Você pode obter headers relacionados ao cook:ie através da
solicitação e da resposta HTTP, mas você não deve. Tudo
o que você precisa fazer com os cook:ies foi encapsulado
naAPI Servlet em três classes: HttpServletRequest,
HttpServletResponse e Cook:ie.
<<inteJjaee>>
http HttpServletRequestjavax.servlet. .
getcontextPathO<<interfaee> >getCookiesO javax.servlet. http.HttpServletResponse
etHeader(String)
g QueryString() addCookieOget addHeaderOgetSession(), J d'
VIraS mais metodos ... eneoueRe zreetURLOIiM sendErrorO
setStatusOIi MUITOS mais métodos ...
javax.servlet. http.Cookie
Cookie(String, String)
~tring getDomainO
zntgetMaxAgeO
String getNameOString getPathO
boolean getSecureO
String getValueO
vo~dsetDomain(String)vozd 'se!"Á A .
• olV1GX ge(znt)
vO~dsetPath(String)
vOldsetValue(String)
Ii alguns outros métodos
response.addCookie(cookie);
Criando um novo cookieo CIJPls+rf.l"1-6r ClJoUe leva lIlrl
Cookie cookie = new Cookie(~usernameH, name);~ .sI . I ,,..r1Pl5P1itJlrle{VafitJr.
Configurando o tempo que um cookie permanecerá no cliente
cookie. setMaxAge (30*60); . O se+A4.axA'fif!: Jetl'P1it/itJelrl, <J I
~f.btJlJJ)O.s. {) caJi5tJ Ji;:
perlrlaPleg4 Vt"lItJPltJcliePlh'l1: 11
f'i'U' 30'1f\'O s'!!5l1P1Jas
IrlI'P1l1+as). CaPlt~lIral" a IrlQX
Recebendo o{s) cookie{s) da solicitação do cliente f'4Nl. -1ta; CIJIrl6 3l1e 6 Co66kte
Cookie [] cookies = request. getCookies (); Jesapl1.reja Ôll4P1JIJitJ
for (int i = O; i < cookies.length; i++) { tec~ar.~r+I1.PI+o6JSeookie cookie = cookies[i];
if (cookie. getName ().equals (~usernameH) ) ;;'fJ.1rl4r tJ 5e-1-1A.axIf9e() PlIJc6IfJkteString userName = cookie.getValue(); Ll.5f..5.s~olJ~J) tJ
out.println(~Hello ~ + userName); Ibreak; r,!!Cder4 Je
Enviando o cookie ao cliente
!J';IJ ~: " 1Itt:+"JIJ 5e-H:.IJt:J/:.te(S+rtPl5)'" ve.cê s:' pe.Je tJ~hr
c"o/:.tes elltt lIlItt arr, CIJIJ/:.tee vócê hr: 1l1e ta;er lIlItt IlJtJp
PIe.arr, p4ra ePlC6P1+r4r alpe1e 3l1e voee SlIer.
você está aqui.. 251
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 12/25
exemplo cookie
Exet\tplo sit\tples de ut\t eoolde eustot\tizado
Imagine que o Kim deseje criar um formulário que peça ao usuário
para enviar o seu nome. O formulário chama um servlet que recebe
o parâmetro usemame da solicitação e usa este valor para criar umcookie na resposta.
Na próxima vez que o usuário fizer uma solicitação em
QUALQUER servlet nesta aplicação, o cookie retoma com a
solicitação (supondo que o cookie ainda esteja vivo, baseando-se
no valor maxAge dele). Quando um servlet na aplicação vê estecookie, ele pode colocar o nome do usuário em uma resposta
gerada dinamicamente, e a lógica do negócio sabe que não tem que
pedir ao usuário que digite o seu nome novamente.
Este cbe\~go~ uma versão fie \es\e slmp\ln~~~~~\\\\'?~"d\')\\\\~acabamos de descrever.
o servlet que cria e CONFIGURA o cookie
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class CookieTest extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
response. setContentType ("text/html") ; itecebe (} /7t}/MetJlJ vsv:l'l{j
String name = request. getParameter ("username") ;V f!J1Vlo.tJ"J16161'W1vl:l'ia.
Cookie cookie = new Cookie ("username", name); <--Cl'tfll. VNoJ16V6c<tJfjl:le~lIe F
o.I'WIlJ.jf!/7IJ.> /7iJWletJ" lISVfl.l'i'eJ.cookie.setMaxAge(30*60); I
'" Malfrff.No" (;41JMe11lVfJJ1(j
30 W11;'V+4S.A-tJlci'6/7fl..o C()lJl:te Ct'JWlIJ t.eatJel' tJe
response. addCookie (cookie) ;<f:--_____ J /I J J'I •l'esft'Js-ra, .se.,...-l.-M/tae.RequestDispatcher view = request.getRequestDispatcher("cookieresult.jSP");
view. forward (request, response); ~
Pel'W1,--h: 3l1e lIWI J.sP crie IJ. I tJe l'eSft:lS.f-lJ. • .-I
o JSP que cria a view a partir deste servlet,
1 b d 1útJt:IbeWl. c!al'lJ, t.a J1atJlJ.Ct)No<htm >< o y> J._'" I '" J P I<a href=" checkcookie .do">click here</ a> Cli.l'aCTf:l'ls-ri'ctJ.S tJe 1- /71'sSÓ).W1tJ.S'MS
</body></html> t:ltJi'Q.If'lt:lSU'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'W1tJSeJ1Calf'll;,t.4J1tJ<iiaf'a lIlf'I
J.sP J1';' If'IlIJ, IJ.ctJ;,/~tJf'tJJifJ ;/.0 c(J(J/::ie.()ClJlJ/::'-ejfl es-fo. ;,Q. f'(SPlJs.f1J. 116iIJ'It)/I!;el1-fIJlf'l
3tJe 4 SlJli'cl-flJ.j';C : eI1ClJ.iIJ'It;,t.a;/a1J J.sP. ••
252 capítulo 6
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 13/25
gerenciamento da sessão
ExetMplo de UtM coolde custotMizado, cottlit1uação ...
o servlet que RECEBE o cookie
import javax.servlet *.
~mport javax.servlet:h~tP.*;lmport ]ava.io.*;
request, HttpServletResponse response)
throws IOException, ServletException
response.setContentType(~text/html") .PrlntWrlter out 'response.getWriter();
Cookie [] cookies ~ request. getCookies ();~ecebe 6S uM/t:.tes da Sf:Jliêt-l-at/ti6.
if ( cookies !~ null) {
for (int i ~ O' . < .. _ ,l cookles.length; i++)
Cookle cookie = cookies[i];lf (cookie getNa ()
. . me .equals{~username")) IStrlng userN _ . J '
. ame - cookle. getVal ue (). i .___ t.!-rl'illltS dliout.prlntln(~Hello ~ + userName)' '~ •
break; ,da ca4/l:le I'l'ilJCill'tlPlJtJillJ'i ClJtJkl'ecl..fJ,IJ'ifJ.JiIJ
If'IISI!I'Pl41J'ie • Se ele
I!PlClíPl-l-I'RdtJ)IJb-l-ePlt.a a
val61' e extb4-t}.
public class CheckCookie extends HttpServlet (
public void doGet(HttpServletRequest
Não confunda Cookiescom headers!
Quando você adiciona um header em uma resposta, vocêpassa as Strings nome e valor como argumentos:
response.addHeader(~foo", ~bar");o
;to
..
. ......
.=~lQ' '" "0 00 00 00 000.
I " saber i;DCênão precisa •. I· os os me't ..• •: do cookie. Ouos :· .• p •: ara aprova voce' - :• ,nao te . •• memorizar cad ra que •: I a um dos 't d :• c asse cooki me o os na •• e, masdev ' •: os métodos de sol" era conhecer :• lCltaç - •: para obter e adi . ao e resposta:: 10cê tamb' d czonar Cookies. :: em eve conh :• construtor C. ecer o •ookie e' •: getMaxAgeO ., IOS metodos ::.......... e set1V1axAgeO. :
.....•••••... .•••........... :
Mas quando você adiciona um Cookie em uma resposta,você passa um objeto Cookie. Você configura o nome doCookie e o valor no construtor Cookie.
Cookie cookie = new Cookie(~name", name);
response.addCookie(cookie);
E lembre-se também de que existem o método setHeader()e o addHeader() (o addHeader adiciona um novovalor a um header existente, caso exista, e o setHeadertroca o valor existente). Porém, NÃO existe um métodosetCookie(). Existe apenas o addCookie()!
você está
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 14/25
momentos do ciclo da vida da sessão
Os prittcipais 'ltO'ltetrtos de U'lt HttpSessiott
Os momentos mais importantes na vida de um objetoHttpSession:
A sessão é criada ou destruída.
newinvalidate
Os atributos da sessão são adicionados, removidos ou substituídos por outraspartes da aplicação.
removeAttributeO
A sessão torna-se passiva em uma VM e é ativada em outra dentro de umaaplicação distribuída.
VMlprepare-se
para mudar
Container A-l
254 capítuío 6
A- sessã"
IOIÍj /'tI. de 1/1010.
V,(,{ptU'4
"tr!-f'o..
Agora
eu tenho
você.
Container A-2
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 15/25
Eventos do ciclo de vida da sessão
Momento
Ciclo de vida
A sessão foi criada
Quando o Container cria uma sessão pela primeira vez.
Neste momento, a sessão ainda é considerada nova (em
outras palavras, o cliente ainda não enviou uma solicitação
com uma session ID).
A sessão foi destruída
Quando o Container invalida uma sessão (porque houve um
timeout da sessão, ou alguma parte da aplicação chamou o
seu método invalidate()).
Atributos
Um atributo foi adicionado
Quando alguma parte da aplicação chama o setAttributeOna sessão.
Um atributo foi removido
Quando alguma parte da aplicação chama o
removeAttributeO na sessão.
Um atributo foi substituído
Quando alguma parte da aplicação chama o setAttributeO
na sessão e o nome do atributo já esteja associado a ela.
Migração
A sessão está a ponto de se tornar passiva
Quando o Container está prestes a migrar (mudar) a sessãopara uma VM diferente. E chamado antes de a sessão ser
movida, de forma que os atributos tenham a chance de se
preparar para a migração.
A sessão foi ativada
Quando o Container acaba de migrar (mudar) a sessão para
uma VM diferente. É chamado antes que qualquer outra
parte da aplicação possa chamar o getAttributeO na sessão,
para que os atributos recém-movidos possam se preparar
para o acesso.
gerenciamento da sessão
Tipo de Evento e Listener
HtipSessionEvent
~, ...•..
,HttpSessionBindingEvent
~.'.:..V,ttpSessionAttributeListener
HtipSessionEvent
,ttpSessionAttributeListener
você está~
255
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 16/25
HttpSessionBíndingListener
Não se esque~ado HttpSessiot'Jit'dit'gListet'er
oO
I' I1CIJ+e illVI!X,1_ l?s-rlí.nf>P '"iS-n;i'ler
package com.example; II.Kerv1e-r, p.import javax.servlet.httP.*;~
public Dog(String breed)
this.breed=breed;
public class Dog implements HttpSessionBindingListener
private String breed;
Os eventos da página anterior são para os
momentos principais na vida da sessão. Mas oHttpSessionBindingListener é para os momentos maisimportantes na vida de um atributo sessão. Lembre-se do
capítulo 5, onde nós vimos como você pode usá-Io ~ se, por
exemplo, o seu atributo quer saber quando ele é adicionado
a uma sessão, para que ele possa sincronizar-se com o
banco de dados em questão (e atualizar o banco de dados
quando for removido de uma sessão). Veja abaixo uma
pequena revisão do capítulo anterior:
public String getBreed()
return breed; U'fl U/} fo,lavt'4 !7,#Ji'lt Si5l'1l';:tCflalie 4'Jllé,.. kbICItJA]()1I
public void valueBound (HttpSessionBindingEvent event) {es+e 4-1-"l/;u-I-c. e,.. U"'<'l sess«lJ.Ii código a ser executado agora que eu sei que estou numa sessão
public void valueUnbound(HttpSessionBindingEvent event) {
Ii código a ser executado agora que eu sei que não faço mais parte da sessão
V-NÃO configura todos osoce . d" g no DO'listeners session bm m .
o o a classe Dog aqui) implementaSe uma classe a!rz~uto (com . o Container chama os callbacks
o HttpSessionBmdmgLrste;el, dO e valueUnboundO) quandoque tratam eventos (value o,undo o nada ou removida de umauma instância dessa classe e a IClO
sessão. É isso. E funciona. . d. - vale ara os outros lzsteners eMas Isto NAO p o O HttpSessionListenere osessão da págin~ ante~lOr. devem ser registrados no DD,HttpSessionAttrlbuteLrstener, -es em si diferentemente
I - relacionados as sesso 'visto que ~ es s~od' "d aI localizado na sessão.de um atributo m IVI u
256 capítuio 6
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 17/25
gerenCÍamento da sessão
A tltigração da sessão
Lembra no capítulo anterior que nós falamos brevemente sobre aplicaçõesdistribuídas, onde os pedaços da aplicação poderiam ser replicados porvários de nós na rede? Em um ambiente de clusters, o Container podefazer um balanceamento de carga, recebendo as solicitações dos clientese enviando-as para as NMs (que podem estar, ou não, em máquinasdiferentes, mas isso não é relevante para nós). O fato é que a aplicaçãoestá em diversos lugares.
Isso significa que cada vez que o mesmo cliente faz uma solicitação, estapode acabar indo para uma instância diferente do mesmo servlet. Ou seja,a solicitação A para o Servlet A pode acontecer numa VM, e a solicitaçãoB para o Servlet A pode ir parar numa outra VM. Então a questão é, o queacontece com os componentes como o ServletContext, ServletConfig eobjetos HtlpSession?
Resposta simples, implicações importantes:
Apenas os objetos HttpSession (e seus atributos) são movidos de uma
VM para outra.
Existe apenas um ServletContext por VM. Existe um único ServletConfigpor servlet, por VM.
Mas existe apenas um objeto HttpServlet para uma determinada session
ID por aplicação, independentemente de em quantas VMs a aplicação
esteja distribuída.
A aplicação Cerveja distribuída etlt duas VMs
Alt:rh; es-IJ -fvJi'JdiA Ilcf1.dt;'lt;
Sejtl'1dó Z:l óSIJÚ' 'Cs
y sess:ks e((I~1tt! ebl
Dpei'IfJ.S/M.1Y5QI'ebl a!;tlbl d(I.Ji'J~n+D. I}~SJtt!fJ.sesslóJ'l I!J
parQ GlJtt!fJ. dml'l>V~a opliC"ffi"lI/AlCI} ~ce ebl dGlf1.StJ.ó~sJtt!fJ.h""f>6.
~"PI';""'iJ .5e1",11~~eo.m!JósóS
opliCQ{ióc~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
Aplicação Cerveja
VM 1
Aplicação Cerveja
você está aqui... 257
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 18/25
migração da sessão
A t\1igração da sessão et\1ação
A forma como os fabricantes de servidores lidam com
c1ustering e distribuição de aplicações web varia. Não há
nada na especificação J2EE que obrigue um fornecedor adar suporte a aplicações distribuídas. Mas a figura abaixonos dá uma idéia interessante de como isso funciona.
O fundamental é que, enquanto que as outras partes da
aplicação são replicadas em cada nóNM, os objetos sessão
são movidos. E isto é garantido. Logo, se o fornecedor
realmente suporta aplicações distribuídas, o Container é
requerido para migrar as sessões através das VMs. E isso
inclui migrar os atributos da sessão também.
o Diane seleciona "Clara" ec1icano botão submit.
o servidor de balanceamento
de carga decide enviar a
solicitação para o ContainerA-i na VM Um.
Servidor/Container de
balanceamento de carga
o Container cria uma novasessão, ID n2.343.O cookie "JSESSIONID é devolvido para
Diane na resposta (não mostrado).
Container A-2
Servidor/Container de
balanceamento de carga
O Container recebe a
solicitação, verifica a session
ID e percebe que a sessão está
em umaoutra VM, a VM Um!
oo
Desta vez, o servidorde balanceamento de
carga decide enviar
a solicitação para oContainer A-2 na VM
Dois.
e Diane seleciona "Amarga" ec1icano botão submit. Sua
solicitação também inclui o
"JSESSIONID" n2.343.
258 capítulo 6
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 19/25
gerenciamento da sessão
e A sessão n9.343 migra da VM Um para a VMDois. Ou seja, ela não existe mais na VM Um,
já que ela se mudou para a VM Dois.
Container A-1
Servidor/Container de
balanceamento de carga VM 2
Esta migração significa que a sessão se tornou VM 1passiva na VM Um e foi ativada na VM Dois.
Container A-1
O Container cria uma nova thread para o Servlet
A e associa a nova solicitação à sessão recémmovida n9.343.
Servidor/Container de
balanceamento de carga
A nova solicitação de Diane é enviada para athread e todos saem felizes. Diane não tem idéia
do que aconteceu (exceto pelo breve atrasol
latência na espera da migração da sessão).
você está lt- 259
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 20/25
HttpSessionActivationListener
oa
Este Iistener é tão parecido com um
atributo, que eu consigo descobrir
quando eu estou para Ser movido para
uma nova VM como parte de uma sessão,
e posso ter certeza de que as variáveis
da minha instância estão prontas ...
<<interface>>
HttpSessionActivationListener
sess~onDi~ctivate(HttpSesSionEventj
seSSlOnWiJIPassivate(HttpSessionEventj
Agora fica meio confuso ...
Um Container é exigido para a migração dosatributos Serializáveis (o qual assume que todasas variáveis da instância dentro do atributo ou são
Serializáveis, ou são nulas).
Mas um Container não é exigido para usar a
Serialização para migrar o objeto HttpSession!
O que isto significa para você? Simples:
garanta que os tipos das suas classes de
atributos sejam Serializáveis e você nunca
terá que se preocupar com isso. Mas se
eles não forem Serializáveis (em virtudede uma das variáveis da instância do
objeto atributo não ser Serializável), faça
com que a classe do seu objeto atributo implemente o
HttpSessionActivationListener e use os callbacks ativação!
passividade para contornar o problema.
Já que épossível migrar um HttpSession de uma VM para outra,
os desenvolvedores da especificação pensaram que seria legalse alguém se preocupasse em dizer aos atributos dentro das
sessões que eles também estão prestes a mudar. Dessa forma, os
atributos podem garantir que sobreviverão à mudança.
Se todos os seus atributos são objetos Serializáveis de
verdade, que não se importam onde eles serão colocados,
você talvez nunca use este listener. Aliás, imaginamos que
95,324% de todas as aplicações nunca usem este listener.
Mas ele está lá caso você precise. Seu uso mais provável é
dar aos atributos uma chance de preparar as variáveis da sua
instância para a Serialização.
A migração da sessão e a Serialização
o HttpSessiottAetivatioKListmer deixa os
atributos protrtos para a graKde tMUdaKça..
o Container não é REQUERIDO para usarmos a Serialização, por issonão há nenhuma garantia de que o readObject() e o writeObject()serão chamados no atributo Serializável ou em uma das variáveis dasua instância!
Se você está familiarizado com a Serialização, você sabe que uma classe que implementa esserecurso também pode escolher implementar um método writeObjectO, chamado pela VM sempre
que um objeto for serializado, e um método readObjectO, chamado quando ocorrer o inverso. Umobjeto Serializável pode usar estes métodos para, por exemplo, configurar nulos os campos não-Serializáveis durante a Serialização (writeObjectO), e então restaurar os campos quando ocorrer oprocesso inverso (readObjectO). (Se você NÃO estáfamiliarizado com os detalhes da Serialização,não se preocupe.) Mas os métodos não serão, necessariamente, chamados durante a migração dasessão! Portanto, se você precisa salvar e restaurar o estado da variável da instância no seu atributo,use o HttpSessionActivationListener e use os dois eventos de callbacks (sessionDidActivateO esessionWillPassivateO), assim como você usaria o readObjectO e o writeObjectO.
260 capítulo 6
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 21/25
gerencíamento da sessão
Exeiflplos de listcmer
Nas duas páginas a seguir, preste atenção nos tipos do objetoevento e se o listener é também uma classe atributo.
o contador da sessão
Este listener permite que você acompanhe a quantidade de sessões
ativas na aplicação. Muito simples.
package com.example;
import javax.servlet.http.*;
public class BeerSessionCounter implements HttpSessionListener {
static private int activeSessions;
public static int getActiveSessions()
return activeSessions;
~s';"a classe se;,,: ;/i's';"rtbll{Ja e",wí6-IIJFlclasses C<l""<l ';"<lJ4s as
611';";"IJ.Sclasses da apftclJ.{i<l)'IJ.;"1J.
{ ~ óve ';"ó;/ós 6,s ,se;"lIfe';"s e 4S 611+;"4S
cllJ.sses /l.ssts-/-e,,-/-es P6SSIJ.'" acessa;"
es-/-e "'~';"6J6.
public voíd sessionCreated(HttpSessionEvent event) {~ctiveSessíons++; \, I
fshs ""'fff)JI)S Cfl.l" l"e541r< Vir<
H++,Ses slt:'l'Jíve"./-.
publíc void sessionDestroyed(HttpSessionEvent event) {~
actíveSessions--;
Configurando o Iistener no DD
<web-app ...>
<listener>
<listener-class>
com.example.BeerSessionCounter
</listener-class>
</listener>
</web-app>
você está aqui ~ 261
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 22/25
atributo de sessão listener
Exet\tplos de Iistet1er
o Listener Attribute
Este listener permite rastrear cada vez que algum atributo é
acrescentado, removido ou substituído em uma sessão.
package com.example;
import javax.servlet.http.*;
ís+e 'ts+el'/el" usa V"" I'IlJ""f!
I';;Ci:>I'!Sts+el'l+el<j>esal"/e ser u""
'ts+eller IJrHt'lbil+e) recebe iI""
wewf-i:>8'-1'1'/'';;3_/ublic class BeerAttributeListener implements HttpSessiOnAttributeListener
public void attributeAdded(HttpSessionBindingEvent event} (
String name = event. getName (); "7.. O HHpSessianílle,,-I- per""r+e a lI<lcêbj ect value = event. getValue ()j "11i:>""e" va!,,/' ,/<la-!-I'lbu+" óue,JieSf!"ca,Jie"iIes+e Wf!"-!-".
System.out.println{"Attribute added: " + name + ": " + value);
public void attributeRemoved(HttpSessionBindingEvent event} (
String name = event.getName();
Object value ~ event.getValue{);
System.out.println("Attribute removed: " + name + ". " + value);
public void attributeReplaced(HttpSessionBindingEvent event} (
String name = event.getName();
Object value ~ event.getValue();
System.out.println("Attribute replaced: " + name + ". " + value);
Configurando o listener no DD<web-app ...>
<listener>
<listener-class>
com.example.BeerAttributeListener
</listener-class>
</listener>
</web-app>
262 capítulo 6
r: Ei, onde você está exibindo? Onde
entra o System.out na aplicação?
Jt: Para onde quer que o Container decidaenviá-Io (que você pode ou não configurar).
Em outras palavras, um lugar determinado pelo
fabricante, geralmente um arquivo de log. O
Tomcat coloca a saída em tomcaUlogs/catalina.
log. Você terá que ler a documentação do seu
servidor para descobrir o que o seu Container
faz com a saída-padrão.
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 23/25
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 próprio atributo - quando ele éacrescentado ou removido de uma sessão e quando a sessão migra
de uma VM para outra.
package com.example;
import javax.servlet.http.*;
import java.io.*;
public class Dog implements HttpSessionBindingListener,
HttpSessionActivatiOnListener,Serializable
private String breed;
Ii imagine outras variáveis da instância, incluindo
Ii algumas que não sejam Serializáveis
Ii imagine o construtor e outros métodos get e set
public void valueBound(HttpSessionBindingEvent event)
Ii código a ser executado agora que sei que estou em uma
public void valueUnbound(HttpSessionBindingEvent event) {
Ii código a ser executado agora que sei que não faço mais parte da
sessão
o qco oc OãO:--'~
tLve"l.f.tJsde fl.f.lV4{i4
do. sess';tJ (~t!s
abstt've as
~:.f.(,jd{)sCfJ.t't'e54" u
H#p.:5es slt:mtLve",.f).
public void sessionWillPassivate(HttpSessionEvent event)
Ii código para obter meus campos não-Serializáveis em um
Ii que possa sobreviver à mudança para uma nova VM
public void sessionDidActivate(HttpSessionEvent event) {
Ii código para restaurar meus campos ... para refazer tudo
tenha feito
Ii no sessionWillPassivate()
você está
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 24/25
sessão listeners
Os Listetters relaciottados à Sessão
Cenário A interface Iistener/métodosipo do evento
eralmente
implementado por
HttpSessionListenerttpSessionEventUma classejavax.servleLhttp)
atributo
~ Alguma outrasessionCreatedsessionDestroyed
classe
Você quer saber
HttpSessionActivationListenerttpSessionEvent~ Uma classe
javax.servleLhttp )atributo
J/Jfa: nõ'6 f!.xtsh nft"hVJJ1essionDidActivateHHf'Sess1i>"IrHri/fl,1-/-eíve,,-I-~ Alguma outra
?
classettpSessionBindingListenerttpSessionBindingEvent
Uma classejavax.servleLhttp )
atributo ~ Alguma outra
valueBound
ê
valueUnbound classe
deste tipo sejamotificados quandoles forem associadosu removidos de umaessão.
Você quer saber
HttpSessionAttributeListenerttpSessionBindingEventUma classe
javax.servleLhttp )atributo
J~+b.:PJ4CVds+e i1ei1t.v~ttributeAddedHHf'5es s1t,,,A-Hrt/;l/-/-eíve.,.fAlguma outra
ttributeRemoved classe
attributeReplaced
Alguns dos eventos relacionados à sessão n~o seguemd - de nomenclatura para os eventos.s pa roes
Os métodos HttpSessionListener adotam os HttpSessionEven~s. . .
Os métodos HttpSessionBindingListener adotam os HttpSesslOnBmdmgEvents.
Porém, os métodos HttpSessionAttributeListener empregam o
HttpSessionBindingEvents. .
E os métodos HttpSessionActivationListener empregam o HttpSessl~nEvents.
Járfiqu~tas clatssbeesmHtn~Soe~~~;:~:~;s~::~~:~:~c~:~:~;:;;:~~1:;;~~~;:;; dee el amen e ,eventos na API.
264 capítulo 6
5/8/2018 JSP.SERVLET0010 - slidepdf.com
http://slidepdf.com/reader/full/jspservlet0010 25/25
geref~lciélmienl'oda sessã
Os Ustmers para Evemos relaciotlados à Sessão e
utlta visão geral da API Objetos Evemo
<<interfaee> >HttpSessionActivationListener
sessionDidActivate(HttpSessionEvent)
session WiIlPassivate(HttpSessionEvent)
<<interfaee> >
HttpSessionListener
sessionCreated(HttpSessionEvent)
sessionDestroyed(HttpSessionEvent)
HtipSessionEvení
<<interfaee> >
HtpSe~wnBmmngL~wn"
valueBound(HttpSessionBindingEvent)
valueUnbond(HttpSessionBindingEvent)
<<interfaee> >
HtpSessionAttributeListener
attributeAdded(HttpSessionBindingEvent)
attributeRemoved(HttpSessionBindingEvent)
attributeReplaced(HttpSessionBindingEvent)
HttpSessionBindingEvení
getSessionO
getNameO
getValueO
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'tI
J6 l)fJ~tI; Jese~t:aJelW .,eve~.,. f'~6f'~tJ. 6 tJ.~5(j
iltJ./Óf'J e ., ~"VtJ.Is-I-<Js;~lltc4 1Ft ele
re:+61"1?4.J 118.161"JIJe) trl-1"t1JIJ-/-,(J6S suJa
A-AJrí:5 Jfi. IPI.{JJtJ.#1ftJ.1;IJetf'lW (j eve~d
você está