前言
Session
和 Cookie
的作用有点类似,都是为了存储用户相关的状态信息,是一种会话跟踪技术
Cookie
是存储在本地浏览器,而Session
存储在服务器- 存储在服务器的数据会更加的安全,不容易被窃取,并且
Session
比Cookie
使用方便,Session
可以存储对象,Cookie
只能存储字符串,并且tomcat 8.x
之后的版本中Cookie
可以存储的字符类型有限制
获取 HttpSession
对象
request.getSesssion()
- 调用该方法,并且是第一次请求的时候,服务器会创建一个
Session
对象并返回,并且每个Session
对象都有一个唯一的JSESSIONID
,随后会以Set-cookie
响应头的形式将JSESSIONID
返回给客户端,客户端再次访问的时候将JSESSIONID
发送给服务器。后续请求的时候服务器可通过JSESSIONID
找到对应的Session
对象 - 如果当前会话已经有了
Session
对象那么getSesssion()
方法直接返回当前的Session
对象
request.getSession(boolean)
- 当参数为
true
时,与requeset.getSession()
相同 - 参数为
false
,那么如果当前会话中存在Session
对象则返回,不存在返回null
,而不是创建
HttpSession
的作用域
HttpSession
是域对象,范围是当前会话
HttpServletRequest
:一个请求创建一个request
对象,所以在同一个请求中可以共享request
,例如一个请求从AServlet
转发到BServlet
,那么AServlet
和BServlet
可以共享request
域中的数据ServletContext
:一个应用只创建一个ServletContext
对象,所以在ServletContext
中的数据可以在整个应用中共享,只要不关闭服务器,那么ServletContext
中的数据就可以共享,作用域是整个应用程序HttpSession
:一个会话创建一个HttpSession
对象,同一会话中的多个请求中可以共享session
中的数据;作用域是当前会话,会话关闭Session
消失
凡是域对象,都有如下 4
个操作数据的方法
Session
的实现原理
Session
的实现是依赖 Cookie
的
- 用户第一次请求服务器的时候,浏览器会将用户信息发送给服务器,服务器根据用户提交的相关信息,创建对应的
session
- 请求返回时,将此
session
的唯一标识信息sessionId
返回给浏览器 - 浏览器接收到服务器返回的
sessionId
信息后,会将此信息存入到cookie
中,同时cookie
会记录此sessionId
属于哪个域名 - 当用户第二次请求服务器时,请求会自动判断此域名下是否存在
cookie
信息,如果存在,会自动将cookie
信息发送到服务器,服务器会从cookie
中取出sessionId
,再根据sessionId
查询对应的session
信息。如果没有找到说明用户没有登录或者登录失效,如果找到session
证明用户已经登录可执行后面操作
根据以上流程可知,sessionId
是连接 cookie
和 session
的一道桥梁,大部分系统也是根据此原理来验证用户登录状态
session
生成后,只要用户继续访问,服务器就会更新 session
的最后访问时间,并维护该 session
。为防止内存溢出,服务器会把长时间内没有活跃的 session
从内存删除,这个时间就是 session
的超时时间。如果超过了超时时间没访问过服务器,session
就自动失效了
Session
的超时时间
tomcat
服务器默认对于创建 Session
的数量没有限制,为了防止内存溢出,服务器会把长时间没有活跃的 Session
从内存中删除,这个时间也就是 Session
的超时时间,默认是 30
分钟。如果你打开网站的一个页面开始长时间不动,超出了 30
分钟后,再去点击链接或提交表单时你会发现你的身份已经过期,因为你的 Session
已经丢失了
单个 Web
应用的 Session
的默认超时时间,可以在应用的 web.xml
的 session-config
标签中设置,如果没有设置,那么将会以服务器的时间为准,单位是分钟,值为 0
或负数表示 Session
永不超时
对于单个 Session
对象,可以通过在代码中调用 setMaxInactiveInterval()
方法设置超时时间,单位是秒,值为 0
或负数表示 Session
永不超时

Session
其他常用 API
SessionId
的生命周期
Session
保存在服务器中,而 SessionId
通过 Cookie
发送给客户端,但我们知道 Cookie
的默认生命是 -1
,即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个 Cookie
就丢失了。当客户下一次打开浏览器访问的时候,虽然可能此时服务器端的 Session
还没有过期,但是由于没有了 SessionId
,那么此前的 Session
就找不到了,因此客户的状态可能就丢失了,可能就又需要重新登录
对此,我们可以手动设置 JSESSIONID
的 Cookie
的过期时间
@WebServlet("/session-servlet")
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
HttpSession session = req.getSession();
Cookie jsessionid = new Cookie("JSESSIONID", session.getId());
jsessionid.setMaxAge(30 * 60);
jsessionid.setPath("/");
resp.addCookie(jsessionid);
}
}
Session
和 Cookie
的区别
从存储方式上比较
Cookie
只能存储字符串,如果要存储非ASCII
字符串还要对其编码Session
可以存储任何类型的数据
从隐私安全上比较
Cookie
存储在浏览器中,信息容易泄露出去Session
存储在服务器上,不存在敏感信息泄露问题
从有效期上比较
Cookie
可以保存在硬盘中,只需要设置maxAge
属性为比较大的正整数,即使关闭浏览器,Cookie
还是存在的Session
保存在服务器中,设置maxInactiveInterval
属性值来确定Session
的有效期。并且Session
依赖于名为JSESSIONID
的Cookie
,该Cookie
默认的maxAge
属性为-1
。如果关闭了浏览器,该Session
虽然没有从服务器中消亡,但也就失效了
从对服务器的负担比较
Session
是保存在服务器的,每个用户都会产生一个Session
,如果是并发访问的用户非常多,是不能使用Session
的,Session
会消耗大量的内存Cookie
是保存在客户端的。不占用服务器的资源
从跨域名上比较
Cookie
可以设置domain
属性来实现跨域名Session
只在当前的域名内有效,不可夸域名
参考:https://blog.csdn.net/weixin_43767015/article/details/113736963