Session的作用及原理
文章目录
- 1. 定义
- 2. 和Cookie比较
- 3. 图解
- 4. 源码解析(Java)
- 5. 总结
1. 定义
Session在计算机中,尤其是网络应用中,被称为“会话控制
”。
Session对象可以存储用户在程序中的一些数据,用户在系统中不同的web页面之间进行跳转时,存储在Session中的数据不会丢失。
当用户请求来自web页面时,如果该用户还没有会话,web服务器就会创建一个新的Session对象。当会话过期或者被放弃后,服务器将终止该会话。
2. 和Cookie比较
Session和Cookie都可以保存用户数据,但是Session
是保存在服务端
,Cookie
是保存在客户的浏览器
中。
电脑桌面端应用
与APP应用
不保存Cookie。
Session的实现需要依赖于Cookie,当服务端创建Session后,会返回一个JSESSIONID
存到Cookie中,下次再请求时,请求头中携带的Cookie会将JSESSIONID一并带回到服务端,这样服务端就可以找到对应的Session对象。
3. 图解
Session是在servlet
中遇到request.getSession()
时创建的;JSP本质就是一个servlet,将JSP编译后得到的servlet中,就会有request.getSession()
代码,所以访问JSP也会创建Session。
4. 源码解析(Java)
随便在一个接口中加入以下代码:
// 在任意地方获取当前请求的request对象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 利用request获取session
HttpSession session = request.getSession();
springboot
使用内置tomcat
启动时,request对象是org.apache.catalina.connector.RequestFacade
的实例。
首先进入request.getSession()
方法:
@Override
public HttpSession getSession() {// 对request的非空判断if (request == null) {throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));}// 默认传参truereturn getSession(true);
}
进入getSession(true)
方法:
/*** @param create 当session不存在时,是否新创建session*/
@Override
public HttpSession getSession(boolean create) {// 对request的非空判断if (request == null) {throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));}// 包保护特殊处理逻辑if (SecurityUtil.isPackageProtectionEnabled()){return AccessController.doPrivileged(new GetSessionPrivilegedAction(create));} else {return request.getSession(create);}
}
此处request属于org.apache.catalina.connector.Request
类,进入request.getSession(create)
方法:
@Override
public HttpSession getSession(boolean create) {// 真正获取Session的方法Session session = doGetSession(create);if (session == null) {return null;}// 获取HttpSessionreturn session.getSession();
}
进入doGetSession(create)
方法:
protected Session doGetSession(boolean create) {// tomcat上下文Context context = getContext();if (context == null) {return null;}// 如果session不为空且session对象是无效的,则置session为nullif ((session != null) && !session.isValid()) {session = null;}// 如果session不为空,且是有效的session,则直接返回sessionif (session != null) {return session;}// 获取上下文中管理器对象Manager manager = context.getManager();// 管理器对象为空说明不支持Session,直接返回nullif (manager == null) {return null;}// 从Cookie中解析到的JSESSIONID如果不为空if (requestedSessionId != null) {try {// 根据SessionId从管理器对象中查找对应的Session对象session = manager.findSession(requestedSessionId);} catch (IOException e) {// 出错打印日志if (log.isDebugEnabled()) {log.debug(sm.getString("request.session.failed", requestedSessionId, e.getMessage()), e);} else {log.info(sm.getString("request.session.failed", requestedSessionId, e.getMessage()));}session = null;}// 获取出来的session对象不为空且session已失效,则将session置为nullif ((session != null) && !session.isValid()) {session = null;}// session对象不为空且session有效if (session != null) {// 更新session中的最后访问时间为当前时间session.access();// 返回sessionreturn session;}}// 如果请求中未传递sessionId且create参数为false,则表示当前请求不存在对应session对象时不新创建if (!create) {return null;}// 有效的会话跟踪模式是否包含Cookie模式boolean trackModesIncludesCookie =context.getServletContext().getEffectiveSessionTrackingModes().contains(SessionTrackingMode.COOKIE);// 支持Cookie且response已经被提交(response不能再向缓冲区写入任何东西)则直接抛出异常if (trackModesIncludesCookie && response.getResponse().isCommitted()) {throw new IllegalStateException(sm.getString("coyoteRequest.sessionCreateCommitted"));}// 获取sessionIdString sessionId = getRequestedSessionId();if (requestedSessionSSL) {} else if (("/".equals(context.getSessionCookiePath()) && isRequestedSessionIdFromCookie())) { // 如果sessioncookie的path为/,且sessionId来自于cookieif (context.getValidateClientProvidedNewSessionId()) {boolean found = false;// 获取tomcat中当前Host下所有的Container,在每个container中寻找sessionId对应的session,如果存在对应的session,则标记为foundfor (Container container : getHost().findChildren()) {Manager m = ((Context) container).getManager();if (m != null) {try {if (m.findSession(sessionId) != null) {found = true;break;}} catch (IOException e) {// Ignore. Problems with this manager will be// handled elsewhere.}}}// 如果都没有,则将sessionId置空if (!found) {sessionId = null;}}} else {sessionId = null;}// 创建session对象session = manager.createSession(sessionId);// 基于session对象创建一个session cookieif (session != null && trackModesIncludesCookie) {// 创建Cookie对象,并设置MaxAge、Comment、Domain、Secure、HttpOnly、Path参数Cookie cookie = ApplicationSessionCookieConfig.createSessionCookie(context, session.getIdInternal(), isSecure());// 向response中增加Set-Cookie响应头response.addSessionCookieInternal(cookie);}if (session == null) {return null;}// 设置访问时间为当前时间session.access();return session;
}
判断session是否失效的session.isValid()
方法:
@Override
public boolean isValid() {if (!this.isValid) {return false;}if (this.expiring) {return true;}if (ACTIVITY_CHECK && accessCount.get() > 0) {return true;}// 最大存活时间是否大于0if (maxInactiveInterval > 0) {// 获取存活时间(s)int timeIdle = (int) (getIdleTimeInternal() / 1000L);// 存活时间超过最大存活时间则使其失效if (timeIdle >= maxInactiveInterval) {expire(true);}}return this.isValid;
}
5. 总结
Session是一项会话存储技术,它的实现需要Cookie的配合。服务端根据请求中Cookie携带的JSESSIONID参数寻找对应的Session对象。
第一次请求没有携带JSESSIONID或者JSESSIONID对应的Session对象已经失效或者不存在,则服务端创建新的Session,并将JSESSIONID添加到响应头中,浏览器端接收到响应后,设置Cookie中的JSESSIONID参数。
Session的作用及原理相关推荐
- Cookie和Session的作用,区别和各自的应用范围,Session工作原理
Cookie和Session的作用与区别 Session用于保存每个用户的专用信息. 每个客户端用户访问时,服务器都为每个用户分配一个唯一的会话ID(Session ID) . 她的生存期是用户持续请 ...
- Cookie和Session的作用和工作原理
一.Cookie详解 (1)简介 因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现.在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两饮料 ...
- volatile关键字的作用、原理
在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到"半个"单例. 而发挥神奇作用的volatile,可以当之 ...
- Bundler 的作用及原理
Bundler 的作用及原理 翻译 · yesmeck · Created at one year ago · Last by teacafe2000 Replied at one year ago ...
- JAVA基础加强(张孝祥)_类加载器、分析代理类的作用与原理及AOP概念、分析JVM动态生成的类、实现类似Spring的可配置的AOP框架...
1.类加载器 ·简要介绍什么是类加载器,和类加载器的作用 ·Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader ...
- Batch Normalization的作用及原理
目录 声明 BN是什么[1] 为什么提出BN[1, 2] BN的作用及原理 加速训练,提高收敛速度[1] 缓解梯度消失(梯度爆炸)[3] 缓解过拟合[4] 其他相关问题 BN和激活函数的顺序问题[5] ...
- 【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理
1 LES BX, DWORD PTR DS:_OSTCBCur ;OSTCBCur->OSTCBStkPtr = SS:SP!!! 2 MOV ES:[BX+2], SS ;将当前SS(栈的基 ...
- python super()方法的作用_详解python的super()的作用和原理
Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递.uz0免费资源网 今天我们介绍的主角是s ...
- 主从复制面试之作用和原理
主从复制面试之作用和原理 有些同学连集群和主从都分不清楚的,这里我说一下他们最本质的区别,其实也就是data-sharing和nothing-sharing的区别.集群是共享存储的.主从复制中没有任何 ...
最新文章
- 整理对应_JSP第二版课后习题答案【侵权联系我删除】
- AngularJS学习日记(四)Service和Provider
- 2017年9月2日普级组T2 跳格子
- python画图比赛_Python选修课第二届Turtle绘图大赛
- Linux-MySQL基本命令-SQL语句
- python内存管理机制错误_Python内存管理机制和垃圾回收机制的简单理解
- 精确的硬盘整数分区方法
- 计算机发送到桌面快捷方式,win10电脑没有发送到桌面快捷方式选项的详细恢复步骤...
- ARMv8-A TrustZone概述
- 使用PS制作毛玻璃效果
- 英语基础语法-语态(被动语态Be done)
- 投影仪家用推荐最新?投影仪什么牌子性价比比较高
- java论文word_JAVA课程实践报告 基于web的点餐系统毕业设计word格式
- 蔡高厅高等数学21-连续函数闭区间的性质(最大最小值定理、有界性定理、零值点定理、介值定理、推论)
- python程序设计思维导图_程序设计 思维导图
- linux 黑屏后死机,如何修复各种各样的黑屏死机
- 视频像素数据_从摄像头到驱动
- python画图小动物_如何用python画简单的动物
- ckeditor 工具栏配置
- R语言如何向向量中追加一个元素?
热门文章
- 批量修改图片尺寸(适用于4:3和16:9的图片)
- 湖南福米科技Java开发岗暑期实习面经
- 你知道如何写一个框架吗?详细步骤放送(上)
- php不通过js链接workeman,workerman 403毛病缘由与解决方法_PHP开发框架教程,workerman...
- 死锁的概念以及发生死锁的缘由
- 动态路由协议简单理解
- windows driver - DeviceIoControl 用法
- 数据库系统原理课后练习题(期末复习题目附答案)
- TKmybatis的使用,MyBatis的Mapper接口、Example方法
- vue打包部署服务器,背景图片显示空白