一、会话技术
1、会话
一次会话包含多次请求和响应;
一次会话:
浏览器第一次给服务器发送资源请求,会话便建立,直到有任一方断开,会话结束;
2、功能
在一次会话的范围内的多次请求间共享数据;
3、方式
客户端会话技术:Cookie;
服务器端会话技术:Session;
二、Cookie快速入门
1、概念
客户端会话技术,将数据保存到客户端;
作用:
用于服务器在用户没有登录的情况下识别用户身份;
(补充时间:2019年09月30日17点55分)
2、快速入门
使用步骤:
第一步:创建Cookie对象,绑定数据;
new Cookie(String name, String value);
public Cookie(String name, String value){}
第二步:发送Cookie对象;
resp.addCookie();
void addCookie(Cookie cookie);
第三步:获取Cookie,拿到数据;
req.getCookies();
Cookie[] getCookies();
代码演示:
MyServlet:
package com.zibo.servlet;
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("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet……");
System.out.println("转到doPost……");
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost……");
//第一步:创建Cookie对象,绑定数据;
Cookie cookie = new Cookie("msg","hello!");
//第二步:发送Cookie对象;
resp.addCookie(cookie);
}
}
SecondServlet:
package com.zibo.servlet;
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("/s1")
public class SecondServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//第三步:获取Cookie,拿到数据;
Cookie[] cookies = req.getCookies();
//查看cookie数据
if(cookies!=null){
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
System.out.println(name+":"+value);
}
}
}
}
运行结果:
3、Cookie原理
第一步:浏览器像服务器发送请求;
第二步:服务器给浏览器发送携带Cookie的响应消息;
第三步:浏览器将服务器发送的Cookie保存起来;
第四步:浏览器第二次向服务器发送请求的时候,会将之前保存的Cookie发送给服务器;
第五步:服务器可以获取浏览器的Cookie数据;
三、Cookie技术细节
1、一次是否可以发送多个cookie?
答:可以!
方法:
创建多个cookie对象,调用多次resp.addCookie()方法即可;
2、cookie在浏览器中保存多长时间?
默认情况:
浏览器关闭后,cookie数据被销毁;
持久化存储:
setMaxAge(int seconds):
参数取值说明:
1、正数:将cookie数据写到硬盘文件中,持久化存储,cookie存活时间;
2、负数:默认值;
3、零:删除cookie;
例如:
setMaxAge(30):含义是将cookie写到硬盘文件,30s后删除硬盘中的cookie文件;
代码示例:
//第一步:创建Cookie对象,绑定数据;
Cookie cookie = new Cookie("msg","hello!");
//设置cookie持久化存储时间
cookie.setMaxAge(30);
//第二步:发送Cookie对象;
resp.addCookie(cookie);
3、cookie是否能存中文;
在Tomcat8之前,不能直接存储中文数据;
需要将中文数据转码后再存储,一般采用URL编码;
在Tomcat8之前,cookie支持中文数据,但是特殊字符仍然不支持,建议使用URL编码;
4、cookie能否被多个项目共享?
问题1:
假设在一个Tomcat中部署了多个web项目,那么这些web项目的cookie能不能共享?
答:
默认情况下不能共享;
setPath(String path)方法:设置cookie的取值范围;默认情况下,设置当前的虚拟目录;
如果想要共享,则可以手动设置虚拟目录为“/”(根目录);
问题2:
不同的Tomcat服务器间cookie共享问题?
答:
setDomain(String path):如果设置一级域名相同,那么多个服务器之间的cookie可以共享;
举例:
setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com可以共享cookie;
5、Cookie的特点和作用
特点:
1、Cookie存储数据在客户端浏览器;
2、浏览器对于单个cookie的大小有限制(4kb),对于同一个域名下的总cookie也有限制(20);
作用:
1、cookie一般存少量的不太敏感的数据;
2、在不登陆的情况下,完成服务器对客户端的身份识别;
四、Cookie案例
1、需求
1、首次访问一个Servlet,提示:您好,欢迎首次访问;
2、非首次访问。则提示:您好,您上次的访问时间是xxx;
2、分析
3、代码演示
package com.zibo.servlet;
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.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebServlet("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet……");
System.out.println("转到doPost……");
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost……");
//1、获取cookie数组
Cookie[] cookies = req.getCookies();
//2、便利cookie数组,看是否存在lastTime
boolean flag = false;//记录lastTime是否存在
if(cookies!=null && cookies.length>0){
for (Cookie cookie : cookies) {
System.out.println(cookie.getName());
String name = cookie.getName();
if("lastTime".equals(name)){
//3、存在——非首次访问
flag = true;
//获取当前时间字符串
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = sdf.format(date);
//设置cookie的值
//提前对空格进行URL编码
format = URLEncoder.encode(format, StandardCharsets.UTF_8);
cookie.setValue(format);
//设置cookie的存活时间
cookie.setMaxAge(60*60*24*30);//一个月
//发送cookie
resp.addCookie(cookie);
//提前在value改变之前响应数据
//响应数据之前设置防止中文乱码
resp.setContentType("text/html;charset=utf-8");
String cookieValue = cookie.getValue();
//URL解码
cookieValue = URLDecoder.decode(cookieValue, StandardCharsets.UTF_8);
resp.getWriter().write("<h1>欢迎,您的上次访问时间是"+cookieValue+"</h1>");
}
}
}
//当cookie不存在
if(cookies==null || cookies.length==0 || !flag){
//不存在,首次访问
//获取当前时间字符串
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = sdf.format(date);
//提前对空格进行URL编码
format = URLEncoder.encode(format, StandardCharsets.UTF_8);
//设置cookie的值
Cookie cookie = new Cookie("lastTime",format);
//设置cookie的存活时间
cookie.setMaxAge(60*60*24*30);//一个月
//发送cookie
resp.addCookie(cookie);
//提前在value改变之前响应数据
//响应数据之前设置防止中文乱码
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("<h1>欢迎,您的首次访问!</h1>");
}
}
}
运行结果: