当客户端关闭后,服务器不关闭,2次获取Session是否为同一个
客户端不关闭,服务器关闭后,2次获取的session是同一个吗
概念
- 服务器会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中
使用例子
SessionDemo1写入Session,SessionDemo2获取Session
SessionDemo1代码
package com.lingaolu.session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
/**
* @author 林高禄
* @create 2020-07-29-20:48
*/
@WebServlet("/sessionDemo1")
public class SessionDemo1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("name","林大帅");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
SessionDemo2代码
package com.lingaolu.session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
/**
* @author 林高禄
* @create 2020-07-29-20:48
*/
@WebServlet("/sessionDemo2")
public class SessionDemo2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Object name = session.getAttribute("name");
response.setContentType("text/html;charset=utf-8");
if(null != name){
response.getWriter().write(name.toString());
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
运行访问SessionDemo1,写入Session
访问SessionDemo2,获取Session
原理
我们清除浏览器数据,重新访问SessionDemo1
发现响应头里面多了一个Cookie客户端会话------Cookie
JSESSIONID=583C8B12719988070A1D0EA17FEDCF96;
我们再请求访问SessionDemo2
发现请求头多了一个一个Cookie
JSESSIONID=583C8B12719988070A1D0EA17FEDCF96
这2个JSESSIONID是一样的,那么这个是什么呢?
这就是Session的一个标识,也就是Session是基于Cookie的,由于这个JSESSIONID的存在,使得SessionDemo1和SessionDemo2中的Session是同一个Session,也就可以共享数据
我们把浏览器关掉,再次访问SessionDemo2
发现获取不到Session数据了,请求头也没有了JSESSIONID,响应头有一个,但是值不一样的,说明关闭浏览器之后,会话关闭了,Session数据没有了,而这次的访问是另外开启的会话,所以Session是另外新的,也就说明了Session是在一次会话的多次请求间共享数据
- 第一次获取Session,没有Cookie没有JSESSIONID,会在内存中创建一个Session对象
- Session对象会把id以key为JSESSIONID存入Cookie
- 第二次获取Session,发现有key为JSESSIONID的Cookie
- 拿到JSESSIONID的值,获取相应id的Session,也就获取到同一个Session
- 也就是Session的实现是依赖于Cookie的
Session的细节
当客户端关闭后,服务器不关闭,2次获取Session是否为同一个
从上面的例子可以看出,默认情况下,会话关闭在次重新打开后,JSESSIONID变了,所以不是同一个Session
但是,我们知道Session是基于Cookie的,所以,如果需要相同,可以创建Cookie,key为JSESSIONID,设置最大存活时间,让Cookie持久化保存
Cookie c = new Cdookie("JSESSIONID",session.getId())
c.setMaxAge(存活时间)
response.addCookie(c)
我们改一下SessionDemo1代码,让JSESSIONID写入Cookie
package com.lingaolu.session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
/**
* @author 林高禄
* @create 2020-07-29-20:48
*/
@WebServlet("/sessionDemo1")
public class SessionDemo1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("name","林大帅");
Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(24*60*60);
response.addCookie(c);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
启动访问SessionDemo1,debug看一下JSESSIONID
访问SessionDemo2,JSESSIONID是一样的,也就是同一个Session
关闭浏览器,结束会话,重新打开浏览器,重新访问SessionDemo2
发现还是能拿到Session,JSESSIONID是一样的,也就是同一个Session,毕竟我们把JSESSIONID持久化了24*60*60=1小时了
客户端不关闭,服务器关闭后,2次获取的session是同一个吗
答案肯定不是同一个,因为服务器关闭了,内存已经被回收了,内存中的session已经不存在了。虽然不是同一个,但是我们可以做到数据不丢失
- sesison的钝化:在服务器正常关闭之前,将session对象系列化到硬盘上
- sesison的活化:在服务器启动后,将sesison文件转化为内存中的sesison对象即可
idea可以钝化,但是不可以活化
现在我们正常关闭项目
找到项目部署的路径
现在我们web下还没有sesison的钝化文件
现在关闭项目,发现有了session的钝化文件
那为何idea活化不了呢?因为ieda在重启项目的时候,会把work目录删掉,然后再重新生成新的work目录,也就把session钝化文件删掉,所以找不到之前的session钝化文件,所以没法活化
tomcat就可以,tomcat正常关闭服务后,会序列化生成钝化文件,重新启动后,会反序列化把钝化文件生成内存的sesison,然后删除sesison钝化文件,这样就能保留sesison数据,虽然JSESSIONID不一样,但是数据是一样的,这里就不演示了,以后我们的项目肯定是部署到外面服务器,所以不用担心idea这种情况。
Session什么时候被销毁
服务器关闭
Session对象调用invalidate()
Session默认失效时间30分钟
这个时间可以修改,找到tomcat的配置文件web.xml
就可以修改你想要的失效时间
Session的特点
- session用于存储一次会话的多次请求的数据
- session可以存储任意类型,任意大小的数据