会话技术
- 会话:一次会话当中包含了多次的请求和响应
- 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
- 会话的功能:在一次会话的范围之内的多次请求之间,共享数据
- 共享数据的方式:客户端会话技术(
cookie
),服务器端会话技术(session
)
Cookie
Cookie快速入门
- 创建Cookie对象,绑定数据:
Cookie(String name, String value)
- 发送Cookie对象:
response.addCookie(Cookie cookie)
- 获取Cookie,拿到数据:
Cookie[] request.getCookies()
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("msg", "hello");
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
System.out.println(cookies[i].getName() + " : " + cookies[i].getValue());
}
}
}
Cookie的实现原理
- 图解

客户端浏览器第一次向服务器发送请求,服务器会做出响应,也就是服务器会将Cookie对象发送给客户端浏览器,其发送方式就是在响应头set-cookie
当中设置cookie
的name
和value
,浏览器收到cookie对象就会保存。
当客户端浏览器第二次发送请求的时候,就会自动的将cookie发送给服务器,其发送方式就是在请求头cookie
当中设置cookie
的name
和value
,服务器端就可以通过request对象当中的方法获取cookie对象。
- 浏览器抓包


Cookie细节处理
- 一次可不可以发送多个
Cookie
可以通过创建多个Cookie
对象和多次调用addCookie
方法即可实现,一次性发送多个Cookie
对象
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("msg", "hello");
Cookie cookie1 = new Cookie("msg", "world");
response.addCookie(cookie);
response.addCookie(cookie1);
}

- cookie在浏览器当中能保存多长时间
默认情况下,当浏览器被关闭之后,Cookie
数据被销毁
但是我们可以通过设置Cookie对象的生命周期来实现Cookie对象的持久化存储,可以使用cookie.setMaxAge(int seconds)
来设置生命周期
seconds>0
:将cookie数据写到硬盘当中,持久化存储。seconds表示cookie存活的时间为seconds秒
seconds<0
:默认值
seconds=0
:删除cookie值
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("msg", "hello");
cookie.setMaxAge(600);
response.addCookie(cookie);
}
- cookie能否发送中文
在tomcat8版本之前,cookie中不能直接存储中文数据,需要将中文数据进行转码,采用URL编码(%E3)
在tomcat8版本及其之后版本,cookie中都支持中文数据
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("msg", "你好");
response.addCookie(cookie);
}

- cookie获取范围多大
假设在一个tomcat当中部署多个web项目,那么在这些web项目当中的cookie能不能共享?
实际上,在默认情况下,cookie是不能共享的,但是我们可以通过cokkie.setPat(String path)
方法来设置cookie的获取范围,其中path是web项目的虚拟路径
- 不同服务器之间cookie共享的问题
可以使用cookie.setDomain(STring path)
,将path设置为相同的一级域名,那么多个服务器就可以实现cookie之间的共享。
例如,setDomain(".baidu.com")
,那么tieba.baidu.com和news.baidu.com中的cookie就可实现共享
cookie的特点和作用
- cookie的数据存储在客户端浏览器
- 浏览器对于单个的cookie的大小有限制(4kb左右),以及对于同一个域名下的cookie的数目也有限制(20个以内)。
- 作用:一般存储不太敏感的少量数据,能够在不登录的情况下,完成服务器对客户端的身份识别
cookie案例:记住上一次的访问时间
- 需求:访问一个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.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.Date;
@WebServlet(urlPatterns = {"/CookieDemo"})
public class CookieDemo extends HttpServlet {
private int cookieContains(Cookie[] cookies) {
if (cookies == null) {
return -1;
}
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals("time")) {
return i;
}
}
return -1;
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
Cookie[] cookies = request.getCookies();
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = URLEncoder.encode(simpleDateFormat.format(date), "utf-8");
int count = cookieContains(cookies);
if (count == -1) {
response.getWriter().write("欢迎首次访问");
Cookie cookie = new Cookie("time", time);
response.addCookie(cookie);
} else {
response.getWriter().write("欢迎回来,上次访问时间为:" + URLDecoder.decode(cookies[count].getValue(), "utf-8"));
cookies[count].setValue(time);
response.addCookie(cookies[count]);
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
- 注意:cookie对象专递数据时,应该注意数据编码格式,使用URLEncoder对象进行URL编码
Session
- 概念:服务器端会话技术,再一次绘画的多次请求之间共享数据,将数据保存在服务器端的对象(HttpSession)当中。
- 获取HttpSession对象:
HttpSession session = request.getSession();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("msg", "HELLO WORLD!");
System.out.println(session.getAttribute("msg"));
session.removeAttribute("msg");
}
Session的原理
- 图解

实际上Session是依赖于Cookie来实现的,在第一次创建session对象的时候,会分配相应的id,通过cookie来发送给客户端浏览器,在客户端浏览器进行请求时,将会发送id给服务器,服务器就会按照id获取唯一的session对象
- 浏览器抓包


Session的细节
- 当客户端关闭之后服务器不关闭,两次获取session是同一个吗?
默认情况下,两次获取的session并不是同一个。
如果我们期望客户端关闭之后获取的仍然相同,我们可以使用cookie来完成。实际上就是设置JSESSIONID的请求头
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(60 * 60);
response.addCookie(cookie);
System.out.println(session);
}
- 客户端不关闭,服务器端关闭之后,两次获取的session是同一个吗?
不是同一个,但是在某些情况下我们需要保证数据的不丢失,因此我们需要将session进行钝化(序列化)和活化(反序列化),以此来保证我们的session对象在服务器关闭之后数据也不会丢失,实际上tomcat可以帮我们完成钝化和活化操作。
- session默认的失效时间(session什么时候会被销毁)
session.invalidate()
方法的调用可以销毁session对象;
session对象的默认存活时间是30分钟,可以通过tomcat的web.xml
来配置session的默认存活时间;
session的特点
- session用于存储一次会话的多次请求之间的数据,存储在服务器端
- session可以用于存储任意类型、任意大小的数据
session与cookie的区别
- session存储在服务器端,cookie存储在浏览器端
- session没有数据大小的限制,而cookie存在数据大小的限制
- session数据相对安全,cookie的数据相对不安全