Tecnologia de Sessão
a) Sessão: Uma sessão inclui múltiplas solicitações e respostas.
- Uma sessão é estabelecida quando o navegador envia sua primeira solicitação para um recurso do servidor, e continua até que uma das partes termine (o fechamento do navegador encerra a sessão).
b) Função: Compartilhar dados entre várias solicitações dentro do escopo de uma sessão.
c) Métodos: 1. Tecnologia de sessão no lado do cliente: Cookies 2. Tecnologia de sessão no lado do servidor: Sessões
Cookies
Tecnologia de sessão no lado do cliente, armazenando dados no navegador.
Início Rápido com Cookies
Passos:
- Criar objeto Cookie, vincular dados
- new Cookie(String nome, String valor)
- Enviar objeto Cookie
- response.addCookie(Cookie cookie) Adiciona o cookie especificado à resposta. Este método pode ser chamado várias vezes para definir mais de um cookie.
- Obter Cookie, obter dados
- Cookie[] request.getCookies()
Implementação em código:
package br.exemplo.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/exemploCookie1")
public class ExemploCookie1 extends HttpServlet {
protected void doPost(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
Cookie ck = new Cookie("mensagem","olá");
resposta.addCookie(ck);
}
protected void doGet(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
doPost(requisicao, resposta);
}
}
package br.exemplo.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/exemploCookie2")
public class ExemploCookie2 extends HttpServlet {
protected void doPost(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
Cookie[] cks = requisicao.getCookies();
if(cks != null){
for (Cookie ck : cks) {
String nome = ck.getName();
String valor = ck.getValue();
System.out.println(nome + ":" + valor);
}
}
}
protected void doGet(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
doPost(requisicao, resposta);
}
}
Acessando http://localhost/exemplos/exemploCookie1, observe que não há saída no console do IntelliJ IDEA. Acesse http://localhost/exemplos/exemploCookie2 e verifique a saída no console do IntelliJ IDEA: mensagem:olá.
Acessar com outro navegador http://localhost/exemplos/exemploCookie2 não exibirá informações, pois não é a mesma sessão.
Princípio de Funcionamento
Baseado nos cabeçalhos de resposta set-cookie e no cabeçalho de solicitação cookie.
Acessando http://localhost/exemplos/exemploCookie1, use uma ferramenta de captura de pacotes para observar o cabeçalho de resposta.
Acessando http://localhost/exemplos/exemploCookie2, observe o cabeçalho de solicitação.
Múltiplos Cookies em uma Solicitação?
Pode-se enviar múltiplos cookies, criando vários objetos Cookie e usando response.addCookie() várias vezes.
package br.exemplo.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/exemploCookie3")
public class ExemploCookie3 extends HttpServlet {
protected void doPost(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
Cookie ck1 = new Cookie("mensagem","olá");
Cookie ck2 = new Cookie("nome","joao");
resposta.addCookie(ck1);
resposta.addCookie(ck2);
}
protected void doGet(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
doPost(requisicao, resposta);
}
}
Acessar http://localhost/exemplos/exemploCookie3, use uma ferramenta de captura de pacotes para observar o cabeçalho de resposta.
Acessar http://localhost/exemplos/exemploCookie2, use uma ferramenta de captura de pacotes para observar o cabeçalho de solicitação e verificar a saída no console do IntelliJ IDEA.
Acessar http://localhost/exemplos/exemploCookie1, também terá o mesmo cabeçalho de solicitação como ao acessar exemploCookie2.
Duração dos Cookies no Navegador?
1. Por padrão, quando o navegador é fechado, os dados do cookie são destruídos.
2. Armazenamento persistente: setMaxAge(int segundos)
- Número positivo: Escreve os dados do cookie em um arquivo no disco rígido. Armazenamento persistente e define o tempo de vida do cookie, após o qual o arquivo de cookie expira automaticamente.
- Número negativo: Valor padrão.
- Zero: Deleta informações do cookie.
Implementação em código:
Um: Número positivo
package br.exemplo.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/exemploCookie4")
public class ExemploCookie4 extends HttpServlet {
protected void doPost(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
Cookie ck1 = new Cookie("mensagem","setMaxAge");
ck1.setMaxAge(30);
resposta.addCookie(ck1);
}
protected void doGet(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
doPost(requisicao, resposta);
}
}
Acessar http://localhost/exemplos/exemploCookie4, então acesse http://localhost/exemplos/exemploCookie2, verifique a saída no console do IntelliJ IDEA: mensagem:setMaxAge. Feche o navegador e reabra para acessar http://localhost/exemplos/exemploCookie2 novamente, ainda verá a saída mensagem:setMaxAge. Após 30 segundos, ao acessar http://localhost/exemplos/exemploCookie2, verifique que não há saída.
Dois: Número negativo
package br.exemplo.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/exemploCookie4")
public class ExemploCookie4 extends HttpServlet {
protected void doPost(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
Cookie ck1 = new Cookie("mensagem","setMaxAge");
ck1.setMaxAge(-1);
resposta.addCookie(ck1);
}
protected void doGet(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
doPost(requisicao, resposta);
}
}
Acessar http://localhost/exemplos/exemploCookie4, então acesse http://localhost/exemplos/exemploCookie2, verifique a saída no console do IntelliJ IDEA: mensagem:setMaxAge. Feche o navegador e reabra para acessar http://localhost/exemplos/exemploCookie2 novamente, verifique que não há saída.
Cookies Podem Armazenar Chineses?
1. Em servidores Tomcat anteriores à versão 8, cookies não podiam amrazenar diretamente dados chineses.
- Precisa-se codificar os dados chineses - geralmente usa-se codificação URL (%E3)
2. Em servidores Tomcat a partir da versão 8, cookies suportam dados chineses. Caracteres especiais ainda não são suportados, recomenda-se usar codificação URL para armazenamento e decodificação URL para análise.
java.net.URLDecoder;
java.net.URLEncoder;
- URLEncoder.encode(str_data,"utf-8");
- URLDecoder.decode(valor,"utf-8");
Problemas de Compartilhamento de Cookies?
1. Suponha que em um servidor Tomcat estejam implantados vários projetos web. Os cookies desses projetos podem compartilhar dados?
- Por padrão, os cookies não são compartilhados.
- setPath(String caminho): Define o escopo de obtenção do cookie. Por padrão, define o contexto de aplicativo atual.
- Para compartilhar, pode-se definir o caminho como "/", representando o caminho raiz do projeto atual, permitindo que todos os projetos implantados no servidor compartilhem informações do Cookie.
2. Problemas de compartilhamento entre diferentes servidores Tomcat?
- setDomain(String domínio): Se o domínio de nível superior for igual, os cookies podem ser compartilhados entre múltiplos servidores.
- setDomain(".baidu.com"), então tieba.baidu.com e news.baidu.com poderão compartilhar cookies.
Implementação em código:
Um: Não compartilhar
package br.exemplo.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/exemploCookie5")
public class ExemploCookie5 extends HttpServlet {
protected void doPost(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
Cookie ck1 = new Cookie("mensagem","你好");
resposta.addCookie(ck1);
}
protected void doGet(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
doPost(requisicao, resposta);
}
}
Crie um novo módulo: dia09, crie um Servlet: ExemploCookie, defina o caminho virtual como /dia09
package br.exemplo.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/exemploCookie")
public class ExemploCookie extends HttpServlet {
protected void doPost(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
System.out.println("dia09...");
Cookie[] cks = requisicao.getCookies();
if(cks != null){
for (Cookie ck : cks) {
String nome = ck.getName();
String valor = ck.getValue();
System.out.println(nome + ":" + valor);
}
}
}
protected void doGet(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
doPost(requisicao, resposta);
}
}
Reinicie o servidor para implantar esses dois módulos. Acesse http://localhost/exemplos/exemploCookie5, então acesse http://localhost/exemplos/exemploCookie2 para ver a saída mensagem:你好; Acessar http://localhost/dia09/exemploCookie, só verá dia09... impresso. Porque os dados não são compartilhados.
Dois: Definir compartilhamento
package br.exemplo.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/exemploCookie5")
public class ExemploCookie5 extends HttpServlet {
protected void doPost(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
Cookie ck1 = new Cookie("mensagem","你好");
ck1.setPath("/");
resposta.addCookie(ck1);
}
protected void doGet(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
doPost(requisicao, resposta);
}
}
Reinicie o servidor para implantar esses dois módulos. Acesse http://localhost/exemplos/exemploCookie5, então acesse http://localhost/dia09/exemploCookie para verificar os dados compartilhados:
Características e Uso dos Cookies
a. Os cookies armazenam dados no navegador do cliente.
b. O navegador tem limitações no tamanho de um único cookie (4kb) e no número total de cookies para o mesmo domínio (20).
c. Uso:
- Os cookies são geralmente usados para armazenar pequenas quantidades de dados não sensíveis.
- Identificação de clientes sem login (configurações armazenadas como cookies no navegador, recuperadas na próxima visita).
Caso de Uso: Lembrar a Última Visita
Requisitos:
- Acessar um Servlet, se for a primeira vez, exiba: Olá, seja bem-vindo à sua primeira visita.
- Caso contrário, exiba: Bem vindo novamente, sua última visita foi em: string de data e hora.
Aálise:
- Pode-se usar cookies para isso.
- No servidor, no Servlet, verificar se existe um cookie chamado lastTime.
- Se houver: não é a primeira vez.
- Resposta de dados: Bem vindo novamente, sua última visita foi em: 10 de junho de 2018 11:50:20.
- Escrever de volta o cookie: lastTime=10 de junho de 2018 11:50:01.
- Caso contrário: é a primeira vez.
- Resposta de dados: Olá, seja bem-vindo à sua primeira visita.
- Escrever de volta o cookie: lastTime=10 de junho de 2018 11:50:01.
Implementação em código:
package br.exemplo.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebServlet("/testeCookie")
public class TesteCookie extends HttpServlet {
protected void doPost(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
resposta.setContentType("text/html;charset=utf-8");
Cookie[] cks = requisicao.getCookies();
boolean flag = false;
if(cks != null && cks.length > 0){
for (Cookie ck : cks) {
String nome = ck.getName();
if("lastTime".equals(nome)){
flag = true;
String valor = ck.getValue();
System.out.println("Decodificação antes: "+valor);
valor = URLDecoder.decode(valor,"utf-8");
System.out.println("Decodificação depois: "+valor);
resposta.getWriter().write("<h1>Bem vindo novamente, sua última visita foi em:"+valor+"</h1>");
Date data = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd de MMMM yyyy HH:mm:ss");
String str_data = sdf.format(data);
System.out.println("Codificação antes: "+str_data);
str_data = URLEncoder.encode(str_data, "utf-8");
System.out.println("Codificação depois: "+str_data);
ck.setValue(str_data);
ck.setMaxAge(60 * 60 *24 * 30);
resposta.addCookie(ck);
break;
}
}
}
if(cks == null || cks.length == 0 || flag == false){
Date data = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd de MMMM yyyy HH:mm:ss");
String str_data = sdf.format(data);
System.out.println("Codificação antes: "+str_data);
str_data=URLEncoder.encode(str_data,"utf-8");
System.out.println("Codificação depois: "+str_data);
Cookie cookie = new Cookie("lastTime", str_data);
cookie.setMaxAge(60 * 60 *24 * 30);
resposta.addCookie(cookie);
resposta.getWriter().write("<h1>Olá, seja bem-vindo à sua primeira visita</h1>");
}
}
protected void doGet(HttpServletRequest requisicao, HttpServletResponse resposta) throws ServletException, IOException {
doPost(requisicao, resposta);
}
}
Acessar http://localhost/exemplos/testeCookie pela primeira vez, verificar a exibição e a saída no console do IntelliJ IDEA.
Acessar http://localhost/exemplos/testeCookie novamente, verificar a exibição e a saída no console do IntelliJ IDEA.
Caso não seja feita a codificação e decodificação de URL, ao acessar http://localhost/exemplos/testeCookie ocorrerão problemas: