文章目录
Session
浏览器携带的是一整个cookie数组
。
服务器获取这个数组中有没有名为 JSESSIONID
的cookie,然后验证服务器内部是否存有对应的session
的id和这个cookie值一样。
1、如果请求内没有名为 JSESSIONID
的cookie
2、存在名为 JSESSIONID
的cookie,但它的value
在服务器内找不到相同值的session id。
以上两种情况,都会创建一个新的session
,并在response
中加入一个:
name
为JSESSIONID
,value
为session.getId()
的cookie
下一次浏览器再发起请求的时候,
如果cookie还没过期
,将会带上携带的名为JSESSIONID
的cookie。
而服务器内还没有销毁这个会话的话,就视为是浏览器与服务器之间的一次没有结束的会话过程
。
写一个接口测试一下 Session类的使用:
@RequestMapping(value = "/sessionLogin", method = RequestMethod.POST)
public String sessionLogin(HttpServletRequest request, HttpServletResponse response) {//
HttpSession session = request.getSession();
System.out.println("创建时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(session.getCreationTime()));
System.out.println("最后访问时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(session.getLastAccessedTime()));
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
System.out.println("request携带的Cookie 名称:" + cookie.getName() + " value值:" + cookie.getValue() );
}
}else {
System.out.println("request无Cookie,生成名为 " + "JSESSIONID" + " 且value值为:" + session.getId() );
}
System.out.println("会话Id为:" + session.getId() );
System.out.println("Servlet 内容为:" + session.getServletContext().toString() );
System.out.println("会话最大持续时间:" + session.getMaxInactiveInterval() );
while (session.getAttributeNames().hasMoreElements()) {
String attributeName = session.getAttributeNames().nextElement();
System.out.println("会话属性名:" + attributeName + " 属性值:" + session.getAttribute(attributeName) );
}
System.out.println("未建立会话,或客户选择不加入会话:" + session.isNew() );
if (!session.isNew()) {
session.invalidate();
System.out.println("非第一次访问:即将手动使此会话失效,再次请求接口将新建session! ");
}
return session.getId();
}
PostMan 发送数据:
第一次请求打印:
创建时间:2022-11-30 16:14:59 最后访问时间:2022-11-30 16:14:59 request无Cookie,生成名为 JSESSIONID 且value值为:B26B4868702486405D11E7AC99D3FBD2 会话Id为:B26B4868702486405D11E7AC99D3FBD2 Servlet 内容为:org.apache.catalina.core.ApplicationContextFacade@39183f7d 会话最大持续时间:1800 未建立会话,或客户选择不加入会话:true
从输出里可以发现,浏览器最初是没有携带
cookie
的,服务器创建了session
后,会创建对应的cookie
返回给客户。
在这个过程中,接口逻辑中,可以对request
中携带的用户名及密码进行校验,再创建cookie
返回确认登录。这时候,接收到一个
cookie
:
第二次请求:
创建时间:2022-11-30 16:14:59 最后访问时间:2022-11-30 16:15:00 request携带的Cookie 名称:JSESSIONID value值:B26B4868702486405D11E7AC99D3FBD2 会话Id为:B26B4868702486405D11E7AC99D3FBD2 Servlet 内容为:org.apache.catalina.core.ApplicationContextFacade@39183f7d 会话最大持续时间:1800 未建立会话,或客户选择不加入会话:false 非第一次访问:即将手动使此会话失效,再次请求接口将新建session!
可见,浏览器携带了
cookie
,服务器据此传给后端程序的session
属性中isNew
是false
,可以给予浏览器免密码登录,直接跳转到用户页面。
Session中可以存放用户的id、密码或者权限值等等。
默认创建的Session最大持续时间就是 1800s,也就是3分钟,不过可以手动设置,延长时间。
后台也可以手动执行invalidate()
方法使Session失效。
1、Session很明显的缺点就是,它只能存在于当前会话的服务器上,只有当前会话服务器能识别。
一旦服务器宕机,会话就没了,浏览器再次发起之前的会话请求就无效了。
2、由于负载均衡的轮询机制,接口请求到达另外的服务器上,是不会被认可的,需要重新登录。
3、虽然Session是存在于服务器端,但是同样认证过程中,是依赖于在客户与服务器之间传递的Cookie
,所以对于Cookie
拦截等情况,无办法。
4、况且现在单个节点的服务器一般都很难满足需求,所以单纯的使用session,实际开发中是不可取的。