Você está na página 1de 17

J550

Sesses
Helder da Rocha (helder@acm.org)
www.argonavis.com.br

Sesses
Como o HTTP no mantm estado de sesso, so as aplicaes Web que precisam cuidar de mant-lo quando necessrio Sesses representam um cliente
A sesso nica para cada cliente e persiste atravs de vrias requisies
request

Cliente

request request request

session

Sesses
Sesses so representados por objetos HttpSession e so obtidas a partir de uma requisio Dois mtodos podem ser usados
HttpSession session = request.getSession(false);

Se a sesso no existir, retorna null, caso contrrio retorna sesso.


HttpSession session = request.getSession();

Retorna a sesso ou cria uma nova. Mesmo que getSession(true)

Para saber se uma sesso nova, use o mtodo isNew()


if (session.isNew()) { myObject = new BusinessObject(); } else { myObject = (BusinessObject) session.getAttribute("obj"); }

getSession() deve ser chamado antes de getOutputStream()*


Sesses podem ser implementadas com cookies, e cookies so definidos no cabealho HTTP (que montado antes do texto)
*ou qualquer mtodo que obtenha o stream de sada, como getWriter()

Compartilhamento de objetos na sesso


Dois mtodos
setAttribute("nome", objeto); Object getAttribute("nome");

permitem o compartilhamento de objetos na sesso. Ex:


Requisio 1
String[] vetor = {"um", "dois", "tres"}; HttpSession session = request.getSession(); session.setAttribute("dados", vetor);

Requisio 2
HttpSession session = request.getSession(); String[] dados = (String[])session.getAttribute("dados");

Como a sesso pode persistir alm do tempo de uma requisio, possvel que a persistncia de alguns objetos no sejam desejveis

Use removeAttribute("nome") para remover objetos da sesso 4

Gerncia de sesses
No h como saber que cliente no precisa mais da sesso
Pode-se definir um timeout em minutos para a durao de uma sesso desde a ltima requisio do cliente setMaxInactiveInterval(int) define novo valor para timeout int getMaxInactiveInterval() recupera valor de timeout Timeout default pode ser definido no web.xml para todas as sesses Outros mtodos teis: getLastAccessedTime() e getCreationTime()

Para destruir uma sesso use


session.invalidate();

Eventos de ligao e ativao de uma sesso podem ser controlados com implementaes das interfaces HttpSessionBindingListener e HttpSessionActivationListener
Consulte a documentao. A abordagem dessas interfaces no faz parte do escopo deste curso 5

Timeout default no web.xml


O elemento <session-config> permite definir a configurao da sesso
Deve aparecer depois dos elementos <servlet-mapping>

O trecho abaixo redefine o tempo de durao default da sesso em 15 minutos para todas as sesses
<session-config> <session-timeout>15</session-timeout> </session-config>

Uma sesso especfica pode ter uma durao diferente se especificar usando setMaxInactiveInterval()
6

Sesso prova de clientes


A sesso implementada com cookies se o cliente suport-los
Caso o cliente no suporte cookies, o servidor precisa usar outro meio de manter a sesso

Soluo: sempre que uma pgina contiver uma URL para outra pgina da aplicao, a URL deve estar dentro do mtodo encodeURL() de HttpServletResponse
out.print("<a href='" + response.encodeURL("caixa.jsp") + "'>");

Se cliente suportar cookies, URL passa inalterada (o identificador da sesso ser guardado em um cookie) Se cliente no suportar cookies, o identificador ser passado como parmetro da requisio
ex: http://localhost:8080/servlet/Teste;jsessionid=A424JX08S99 7

Captura de eventos de atributos


possvel saber quando um atributo foi adicionado a uma sesso usando HttpSessionAttributeListener e HttpSessionBindingEvent Mtodos a implementar do Listener
attributeAdded(ServletContextAttributeEvent e) attributeRemoved(ServletContextAttributeEvent e) attributeReplaced(ServletContextAttributeEvent)

HttpSessionBindingEvent possui trs mtodos para recuperar sesso e nome e valor dos atributos
String getName() String getValue() HttpSession getSession()

preciso registrar o listener no web.xml

Captura de eventos do ciclo de vida


Pode-se saber quando uma sesso foi criada, invalidada ou expirada usando HttpSessionListener:
Mtodos sessionCreated() e sessionDestroyed()

Para saber quando uma sesso existente foi ativada ou est para ser passivada usa-se HttpSessionActivationListener:
Mtodos sessionDidActivate() e sessionWillPassivate()

Para controlar quando objetos so associados a uma sesso e quando deixam a sesso (por qualquer razo) deve-se implementar um HttpSessionBindingListener
Mtodos valueBound() e valueUnbound()

Cada listener tem um evento correspondente, que recebido em cada mtodo. Para maiores detalhes, consulte a documentao e exemplos no Tomcat
Maiores detalhes sobre este assunto fogem ao escopo deste curso 9

Escopo de objetos em servlets


Servlets podem compartilhar informaes de vrias maneiras
Usando meios persistentes (bancos de dados, arquivos, etc) Usando objetos na memria por escopo (requisio, sesso, contexto) Usando variveis estticas ou de instncia

Servlets oferecem trs nveis diferentes de persistncia na memria (ordem decrescente de durao)
Contexto da aplicao: vale enquanto aplicao estiver na memria (javax.servlet.ServletContext) Sesso: dura uma sesso do cliente (javax.servlet.http.HttpSession) Requisio: dura uma requisio (javax.servlet.ServletRequest)

Para gravar dados em um objeto de persistncia na memria


objeto.setAttribute("nome", dados);

Para recuperar ou remover os dados


Object dados = objeto.getAttribute("nome"); objeto.removeAttribute("nome");

10

Escopo de objetos em servlets: resumo


Mtodo terminado

Thread-safe
init() chamado

Servlet carregado

Contexto

Var. local Var. local

Requisio Requisio

Sesso do Cliente

Varivel de instncia

Varivel esttica

Arquivos, Bancos de dados, LDAP, JNDI, etc.

Resposta enviada Sesso invalidada ou expirada

Sesso
destroy() chamado Servidor reiniciado

Contexto

11

Lidando com recursos compartilhados


H vrios cenrios de acesso concorrente
Componentes compartilhando sesso ou contexto Threads acessando variveis compartilhadas

Servlets so automaticamente multithreaded


O container cria um thread na instncia para cada requisio preciso sincronizar blocos crticos para evitar problemas decorrentes do acesso paralelo

Exemplo: protegendo definio de atributo de contexto:


synchronized(this) { context.setAttribute("nome", objeto); }

Para situaes onde multithreading inaceitvel, servlet deve implementar a interface SingleThreadModel (s um thread estar presente no mtodo service() ao mesmo tempo)
Evite isto a todo custo: muito ineficiente! 12

Exerccio
1. Criar uma aplicao Web usando os objetos de negcio
j550.cap04.Produto. Atributos (mtodos get/set): int id, String nome, String preco j550.cap04.Carrinho. Mtodos: addProduto(Produto), removeProduto(id), Produto getProduto(id), Produto[] getProdutos()

a. Crie um servlet j550.cap04.web.AdminLojaServlet

Veja como us-los na classe TestaProdutos.java

b. Crie um servlet j550.cap04.web.ComprasServlet e classe

LojaServlet recebe parmetros para adicionar um produto e lista os produtos existentes como resposta ComprasServlet lista todos os produtos disponveis com um boto Adicionar ao lado de cada um. O boto deve adicionar o produto correspondente no objeto Carrinho. A resposta deve mostrar cada item includo com um boto Remover. Deve haver tambm boto Comprar Mais e Encerrar O Carrinho deve persistir entre requisies

13

Cookies
Como j podemos manipular sesses de maneira transparente com HttpSession, usamos cookies principalmente para definir preferncias que iro durar alm do tempo da sesso
Servidor ir criar cabealho que ir instruir o browser a criar um arquivo guardando as informaes do cookie

Para criar cookies que duram mais que uma sesso (cookies persistentes no disco do cliente) preciso
Criar um novo objeto Cookie Definir a durao do cookie com o mtodo setMaxAge() Definir outros mtodos se necessrio Adicionar o cookie resposta
14

Como usar Cookies


Exemplo de gravao: 1) definir um cookie que contenha o nome do usurio recebido como parmetro na requisio
String nome = request.getParameter("nome"); Cookie c = new Cookie("usuario", nome);

2) Definir a durao do cookie em segundos


c.setMaxAge(1000 * 24 * 3600 * 60); // 60 dias

3) Adicionar o cookie resposta


response.addCookie(c);

Exemplo de leitura: 1) recuperar o cookie da requisio


Cookie[] cookies = request.getCookies();

2) Extrair cookie para um objeto local


for (int i = 0; i < cookies.length; i++) { if (cookies[i].getName().equals("nome") { usuario = cookies[i].getValue(); } }

15

Exerccios
2. Crie uma tela de entrada na loja LojaServlet com links para os servlets.

Ela deve requisitar um e-mail. Grave o e-mail como um Cookie com durao de 30 dias. "Lembre-se" do e-mail na prxima requisio e mostre-o no text-field

16

helder@acm.org

argonavis.com.br
17

Você também pode gostar