本文总结自,B站-遇见狂神说
-
服务器会给每一个用户(浏览器)创建一个session对象
-
一个session独占一个浏览器,只要浏览器没关闭,这个session就存在
-
session用于存储一次会话的多次请求的数据,存在服务器端
-
session可以存储任意类型,任意大小的数据
例如:
-
用户登录之后,整个网站都可以访问你的信息
-
保存购物车信息
-
经常使用的数据,需要保存在这
图解
-
发送请求时,服务器会把你的sessionid登记,每个用户唯一
-
信息和数据都保存在服务器
-
只有匹配到对应的sessionid才能在服务器取到数据和信息
原理
Session的实现是依赖于Cookie的。通过JSESSIONID来确保服务器在一次会话范围内,多次获取的Session对象是同一个
- 例如:
lJSESSIONID
=091CB6E860F70C2D0C250AFD5EA11119;
使用步骤
存一个session的id和值
- 得到session
- 给session存东西
代码:
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 解决乱码问题
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 得到session
HttpSession session = request.getSession();
// 给session存东西
session.setAttribute("name", new Person("小李",12));
// 获取session的id
String sid = session.getId();
// 判断是否为新的session
if (session.isNew()) {
response.getWriter().write("session创建成功!id:" + sid);
} else {
// 浏览器打开就会存在
response.getWriter().write("session已在服务器中存在:" + sid);
}
// 【猜测】session在创建的时候做了什么
// Cookie cookie = new Cookie("JESSIONID",sid);
}
取出session的id对应的值【控制台】
- 获取session的id
代码:
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 解决乱码问题
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 得到session
HttpSession session = request.getSession();
Person p = (Person) session.getAttribute("name");
System.out.println(p.toString());
}
session有效期
Session的默认失效时间是30分钟
删除session
以下两种方法可以搭配使用!!
-
服务器关闭,session销毁
-
手动注销
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 得到session
HttpSession session = request.getSession();
// 注销session
session.removeAttribute("name");
// 手动注销,但他会立马生成一个新的
session.invalidate();
}
-
会话自动过期:默认失效时间 30分钟
可配置web.xml,自行修改
<!--设置session默认的失效时间-->
<session-config>
<!--15min后session自动失效,换新-->
<!--可以搭配手动注销,一起使用-->
<session-timeout>15</session-timeout>
</session-config>
细节问题
当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
- 默认情况下。不是。
- 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
//1.获取session
HttpSession session = request.getSession();
System.out.println(session);
//2.期望客户端关闭后,session也能相同
Cookie c = new Cookie("JSESSIONID", session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作
- session的钝化:
- 在服务器正常关闭之前,将session对象系列化到硬盘上
- session的活化:
- 在服务器启动后,将session文件转化为内存中的session对象即可。
区别
- cookie是把用户的数据写给浏览器,浏览器保存
- session把用户的数据写到用户独占session中,服务器端可以保存多个(保存重要信息)
- session对象由服务器创建;
- session没有数据大小限制,Cookie有
- session数据安全,Cookie相对于不安全